• 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.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN;
21 import static android.content.pm.PackageManager.FEATURE_BLUETOOTH;
22 import static android.content.pm.PackageManager.FEATURE_LEANBACK;
23 import static android.content.pm.PackageManager.FEATURE_WATCH;
24 import static android.content.pm.PackageManager.FEATURE_WIFI;
25 import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT;
26 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
27 import static android.net.BpfNetMapsConstants.METERED_ALLOW_CHAINS;
28 import static android.net.BpfNetMapsConstants.METERED_DENY_CHAINS;
29 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK;
30 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_SUCCEEDED_BITMASK;
31 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_VALIDATION_RESULT;
32 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_DNS_EVENTS;
33 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTION_METHOD_TCP_METRICS;
34 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS;
35 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
36 import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE;
37 import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
38 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
39 import static android.net.ConnectivityManager.BLOCKED_REASON_APP_BACKGROUND;
40 import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN;
41 import static android.net.ConnectivityManager.BLOCKED_REASON_NETWORK_RESTRICTED;
42 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
43 import static android.net.ConnectivityManager.CALLBACK_AVAILABLE;
44 import static android.net.ConnectivityManager.CALLBACK_BLK_CHANGED;
45 import static android.net.ConnectivityManager.CALLBACK_CAP_CHANGED;
46 import static android.net.ConnectivityManager.CALLBACK_IP_CHANGED;
47 import static android.net.ConnectivityManager.CALLBACK_LOCAL_NETWORK_INFO_CHANGED;
48 import static android.net.ConnectivityManager.CALLBACK_LOSING;
49 import static android.net.ConnectivityManager.CALLBACK_LOST;
50 import static android.net.ConnectivityManager.CALLBACK_PRECHECK;
51 import static android.net.ConnectivityManager.CALLBACK_RESERVED;
52 import static android.net.ConnectivityManager.CALLBACK_RESUMED;
53 import static android.net.ConnectivityManager.CALLBACK_SUSPENDED;
54 import static android.net.ConnectivityManager.CALLBACK_UNAVAIL;
55 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
56 import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND;
57 import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW;
58 import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT;
59 import static android.net.ConnectivityManager.FIREWALL_RULE_DENY;
60 import static android.net.ConnectivityManager.NETID_UNSET;
61 import static android.net.ConnectivityManager.NetworkCallback.DECLARED_METHODS_ALL;
62 import static android.net.ConnectivityManager.NetworkCallback.DECLARED_METHODS_NONE;
63 import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
64 import static android.net.ConnectivityManager.TYPE_ETHERNET;
65 import static android.net.ConnectivityManager.TYPE_MOBILE;
66 import static android.net.ConnectivityManager.TYPE_MOBILE_CBS;
67 import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
68 import static android.net.ConnectivityManager.TYPE_MOBILE_EMERGENCY;
69 import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA;
70 import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
71 import static android.net.ConnectivityManager.TYPE_MOBILE_IA;
72 import static android.net.ConnectivityManager.TYPE_MOBILE_IMS;
73 import static android.net.ConnectivityManager.TYPE_MOBILE_MMS;
74 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL;
75 import static android.net.ConnectivityManager.TYPE_NONE;
76 import static android.net.ConnectivityManager.TYPE_PROXY;
77 import static android.net.ConnectivityManager.TYPE_VPN;
78 import static android.net.ConnectivityManager.TYPE_WIFI;
79 import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
80 import static android.net.ConnectivityManager.getNetworkTypeName;
81 import static android.net.ConnectivityManager.isNetworkTypeValid;
82 import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
83 import static android.net.INetd.PERMISSION_INTERNET;
84 import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
85 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
86 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_SKIPPED;
87 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
88 import static android.net.MulticastRoutingConfig.FORWARD_NONE;
89 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
90 import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
91 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
92 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
93 import static android.net.NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK;
94 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED;
95 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
96 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
97 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
98 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
99 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
100 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
101 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
102 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
103 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
104 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
105 import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
106 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
107 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_1;
108 import static android.net.NetworkCapabilities.NET_ENTERPRISE_ID_5;
109 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
110 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
111 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
112 import static android.net.NetworkCapabilities.RES_ID_MATCH_ALL_RESERVATIONS;
113 import static android.net.NetworkCapabilities.RES_ID_UNSET;
114 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
115 import static android.net.NetworkCapabilities.TRANSPORT_TEST;
116 import static android.net.NetworkCapabilities.TRANSPORT_THREAD;
117 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
118 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
119 import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
120 import static android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY;
121 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST;
122 import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY;
123 import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_MATCH_LOCAL_NETWORK;
124 import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_MATCH_NON_THREAD_LOCAL_NETWORKS;
125 import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION;
126 import static android.net.connectivity.ConnectivityCompatChanges.NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION;
127 import static android.os.Process.INVALID_UID;
128 import static android.os.Process.VPN_UID;
129 import static android.system.OsConstants.ENOENT;
130 import static android.system.OsConstants.ENOTCONN;
131 import static android.system.OsConstants.EOPNOTSUPP;
132 import static android.system.OsConstants.ETH_P_ALL;
133 import static android.system.OsConstants.IPPROTO_TCP;
134 import static android.system.OsConstants.IPPROTO_UDP;
135 
136 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_GETSOCKOPT;
137 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET4_BIND;
138 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET4_CONNECT;
139 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET6_BIND;
140 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET6_CONNECT;
141 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_EGRESS;
142 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_INGRESS;
143 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_SOCK_CREATE;
144 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_SOCK_RELEASE;
145 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_SETSOCKOPT;
146 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP4_RECVMSG;
147 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP4_SENDMSG;
148 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP6_RECVMSG;
149 import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP6_SENDMSG;
150 import static com.android.net.module.util.NetworkMonitorUtils.isPrivateDnsValidationRequired;
151 import static com.android.net.module.util.NetworkStackConstants.IPV4_LOCAL_PREFIXES;
152 import static com.android.net.module.util.NetworkStackConstants.MULTICAST_AND_BROADCAST_PREFIXES;
153 import static com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf;
154 import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermission;
155 import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermissionOr;
156 import static com.android.net.module.util.PermissionUtils.hasAnyPermissionOf;
157 import static com.android.server.ConnectivityStatsLog.CONNECTIVITY_STATE_SAMPLE;
158 import static com.android.server.connectivity.ConnectivityFlags.CELLULAR_DATA_INACTIVITY_TIMEOUT;
159 import static com.android.server.connectivity.ConnectivityFlags.DELAY_DESTROY_SOCKETS;
160 import static com.android.server.connectivity.ConnectivityFlags.INGRESS_TO_VPN_ADDRESS_FILTERING;
161 import static com.android.server.connectivity.ConnectivityFlags.NAMESPACE_TETHERING_BOOT;
162 import static com.android.server.connectivity.ConnectivityFlags.QUEUE_CALLBACKS_FOR_FROZEN_APPS;
163 import static com.android.server.connectivity.ConnectivityFlags.QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER;
164 import static com.android.server.connectivity.ConnectivityFlags.REQUEST_RESTRICTED_WIFI;
165 import static com.android.server.connectivity.ConnectivityFlags.WIFI_DATA_INACTIVITY_TIMEOUT;
166 
167 import android.Manifest;
168 import android.annotation.CheckResult;
169 import android.annotation.NonNull;
170 import android.annotation.Nullable;
171 import android.annotation.RequiresApi;
172 import android.annotation.SuppressLint;
173 import android.annotation.TargetApi;
174 import android.app.ActivityManager;
175 import android.app.ActivityManager.UidFrozenStateChangedCallback;
176 import android.app.AppOpsManager;
177 import android.app.BroadcastOptions;
178 import android.app.PendingIntent;
179 import android.app.admin.DevicePolicyManager;
180 import android.app.compat.CompatChanges;
181 import android.app.usage.NetworkStatsManager;
182 import android.content.BroadcastReceiver;
183 import android.content.ComponentName;
184 import android.content.ContentResolver;
185 import android.content.Context;
186 import android.content.Intent;
187 import android.content.IntentFilter;
188 import android.content.pm.PackageManager;
189 import android.content.res.XmlResourceParser;
190 import android.database.ContentObserver;
191 import android.net.BpfNetMapsUtils;
192 import android.net.CaptivePortal;
193 import android.net.CaptivePortalData;
194 import android.net.ConnectionInfo;
195 import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
196 import android.net.ConnectivityDiagnosticsManager.DataStallReport;
197 import android.net.ConnectivityManager;
198 import android.net.ConnectivityManager.BlockedReason;
199 import android.net.ConnectivityManager.NetworkCallback;
200 import android.net.ConnectivityManager.RestrictBackgroundStatus;
201 import android.net.ConnectivitySettingsManager;
202 import android.net.DataStallReportParcelable;
203 import android.net.DnsResolverServiceManager;
204 import android.net.DscpPolicy;
205 import android.net.ICaptivePortal;
206 import android.net.IConnectivityDiagnosticsCallback;
207 import android.net.IConnectivityManager;
208 import android.net.IDnsResolver;
209 import android.net.IIntResultListener;
210 import android.net.INetd;
211 import android.net.INetworkActivityListener;
212 import android.net.INetworkAgent;
213 import android.net.INetworkMonitor;
214 import android.net.INetworkMonitorCallbacks;
215 import android.net.INetworkOfferCallback;
216 import android.net.IOnCompleteListener;
217 import android.net.IQosCallback;
218 import android.net.ISocketKeepaliveCallback;
219 import android.net.InetAddresses;
220 import android.net.IpMemoryStore;
221 import android.net.IpPrefix;
222 import android.net.LinkAddress;
223 import android.net.LinkProperties;
224 import android.net.LocalNetworkConfig;
225 import android.net.LocalNetworkInfo;
226 import android.net.MatchAllNetworkSpecifier;
227 import android.net.MulticastRoutingConfig;
228 import android.net.NativeNetworkConfig;
229 import android.net.NativeNetworkType;
230 import android.net.NattSocketKeepalive;
231 import android.net.Network;
232 import android.net.NetworkAgent;
233 import android.net.NetworkAgentConfig;
234 import android.net.NetworkAndAgentRegistryParcelable;
235 import android.net.NetworkCapabilities;
236 import android.net.NetworkInfo;
237 import android.net.NetworkInfo.DetailedState;
238 import android.net.NetworkMonitorManager;
239 import android.net.NetworkPolicyManager;
240 import android.net.NetworkPolicyManager.NetworkPolicyCallback;
241 import android.net.NetworkProvider;
242 import android.net.NetworkRequest;
243 import android.net.NetworkScore;
244 import android.net.NetworkSpecifier;
245 import android.net.NetworkStack;
246 import android.net.NetworkState;
247 import android.net.NetworkStateSnapshot;
248 import android.net.NetworkTestResultParcelable;
249 import android.net.NetworkUtils;
250 import android.net.NetworkWatchlistManager;
251 import android.net.OemNetworkPreferences;
252 import android.net.PrivateDnsConfigParcel;
253 import android.net.ProfileNetworkPreference;
254 import android.net.ProxyInfo;
255 import android.net.QosCallbackException;
256 import android.net.QosFilter;
257 import android.net.QosSocketFilter;
258 import android.net.QosSocketInfo;
259 import android.net.RouteInfo;
260 import android.net.SocketKeepalive;
261 import android.net.TetheringManager;
262 import android.net.TransportInfo;
263 import android.net.UidRange;
264 import android.net.UidRangeParcel;
265 import android.net.UnderlyingNetworkInfo;
266 import android.net.Uri;
267 import android.net.VpnManager;
268 import android.net.VpnTransportInfo;
269 import android.net.metrics.IpConnectivityLog;
270 import android.net.metrics.NetworkEvent;
271 import android.net.netd.aidl.NativeUidRangeConfig;
272 import android.net.networkstack.ModuleNetworkStackClient;
273 import android.net.networkstack.NetworkStackClientBase;
274 import android.net.networkstack.aidl.NetworkMonitorParameters;
275 import android.net.resolv.aidl.DnsHealthEventParcel;
276 import android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener;
277 import android.net.resolv.aidl.Nat64PrefixEventParcel;
278 import android.net.resolv.aidl.PrivateDnsValidationEventParcel;
279 import android.net.shared.PrivateDnsConfig;
280 import android.net.wifi.WifiInfo;
281 import android.os.BatteryStatsManager;
282 import android.os.Binder;
283 import android.os.Build;
284 import android.os.Bundle;
285 import android.os.ConditionVariable;
286 import android.os.Handler;
287 import android.os.HandlerThread;
288 import android.os.IBinder;
289 import android.os.Looper;
290 import android.os.Message;
291 import android.os.Messenger;
292 import android.os.ParcelFileDescriptor;
293 import android.os.Parcelable;
294 import android.os.PersistableBundle;
295 import android.os.PowerManager;
296 import android.os.Process;
297 import android.os.RemoteCallbackList;
298 import android.os.RemoteException;
299 import android.os.ServiceSpecificException;
300 import android.os.SystemClock;
301 import android.os.SystemProperties;
302 import android.os.UserHandle;
303 import android.os.UserManager;
304 import android.provider.Settings;
305 import android.stats.connectivity.MeteredState;
306 import android.stats.connectivity.RequestType;
307 import android.stats.connectivity.ValidatedState;
308 import android.sysprop.NetworkProperties;
309 import android.system.ErrnoException;
310 import android.telephony.SubscriptionManager;
311 import android.telephony.TelephonyManager;
312 import android.text.TextUtils;
313 import android.util.ArrayMap;
314 import android.util.ArraySet;
315 import android.util.LocalLog;
316 import android.util.Log;
317 import android.util.Pair;
318 import android.util.Range;
319 import android.util.SparseArray;
320 import android.util.SparseIntArray;
321 import android.util.StatsEvent;
322 
323 import com.android.connectivity.resources.R;
324 import com.android.internal.annotations.GuardedBy;
325 import com.android.internal.annotations.VisibleForTesting;
326 import com.android.internal.util.IndentingPrintWriter;
327 import com.android.internal.util.MessageUtils;
328 import com.android.metrics.ConnectionDurationForTransports;
329 import com.android.metrics.ConnectionDurationPerTransports;
330 import com.android.metrics.ConnectivitySampleMetricsHelper;
331 import com.android.metrics.ConnectivityStateSample;
332 import com.android.metrics.NetworkCountForTransports;
333 import com.android.metrics.NetworkCountPerTransports;
334 import com.android.metrics.NetworkDescription;
335 import com.android.metrics.NetworkList;
336 import com.android.metrics.NetworkRequestCount;
337 import com.android.metrics.RequestCountForType;
338 import com.android.modules.utils.BasicShellCommandHandler;
339 import com.android.modules.utils.build.SdkLevel;
340 import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
341 import com.android.net.module.util.BinderUtils;
342 import com.android.net.module.util.BitUtils;
343 import com.android.net.module.util.BpfUtils;
344 import com.android.net.module.util.CollectionUtils;
345 import com.android.net.module.util.DeviceConfigUtils;
346 import com.android.net.module.util.HandlerUtils;
347 import com.android.net.module.util.InterfaceParams;
348 import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
349 import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
350 import com.android.net.module.util.LocationPermissionChecker;
351 import com.android.net.module.util.PerUidCounter;
352 import com.android.net.module.util.PermissionUtils;
353 import com.android.net.module.util.RoutingCoordinatorService;
354 import com.android.net.module.util.TcUtils;
355 import com.android.net.module.util.netlink.InetDiagMessage;
356 import com.android.networkstack.apishim.BroadcastOptionsShimImpl;
357 import com.android.networkstack.apishim.ConstantsShim;
358 import com.android.networkstack.apishim.common.BroadcastOptionsShim;
359 import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
360 import com.android.server.connectivity.ApplicationSelfCertifiedNetworkCapabilities;
361 import com.android.server.connectivity.AutodestructReference;
362 import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker;
363 import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker.AutomaticOnOffKeepalive;
364 import com.android.server.connectivity.CarrierPrivilegeAuthenticator;
365 import com.android.server.connectivity.ClatCoordinator;
366 import com.android.server.connectivity.ConnectivityFlags;
367 import com.android.server.connectivity.ConnectivityResources;
368 import com.android.server.connectivity.DnsManager;
369 import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
370 import com.android.server.connectivity.DscpPolicyTracker;
371 import com.android.server.connectivity.FullScore;
372 import com.android.server.connectivity.InterfaceTracker;
373 import com.android.server.connectivity.InvalidTagException;
374 import com.android.server.connectivity.KeepaliveResourceUtil;
375 import com.android.server.connectivity.KeepaliveTracker;
376 import com.android.server.connectivity.LingerMonitor;
377 import com.android.server.connectivity.MockableSystemProperties;
378 import com.android.server.connectivity.MulticastRoutingCoordinatorService;
379 import com.android.server.connectivity.MultinetworkPolicyTracker;
380 import com.android.server.connectivity.NetworkAgentInfo;
381 import com.android.server.connectivity.NetworkDiagnostics;
382 import com.android.server.connectivity.NetworkNotificationManager;
383 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
384 import com.android.server.connectivity.NetworkOffer;
385 import com.android.server.connectivity.NetworkPreferenceList;
386 import com.android.server.connectivity.NetworkRanker;
387 import com.android.server.connectivity.NetworkRequestStateStatsMetrics;
388 import com.android.server.connectivity.PermissionMonitor;
389 import com.android.server.connectivity.ProfileNetworkPreferenceInfo;
390 import com.android.server.connectivity.ProxyTracker;
391 import com.android.server.connectivity.QosCallbackTracker;
392 import com.android.server.connectivity.SatelliteAccessController;
393 import com.android.server.connectivity.UidRangeUtils;
394 import com.android.server.connectivity.VpnNetworkPreferenceInfo;
395 import com.android.server.connectivity.wear.CompanionDeviceManagerProxyService;
396 
397 import libcore.io.IoUtils;
398 
399 import org.xmlpull.v1.XmlPullParserException;
400 
401 import java.io.FileDescriptor;
402 import java.io.IOException;
403 import java.io.InterruptedIOException;
404 import java.io.PrintWriter;
405 import java.io.Writer;
406 import java.net.Inet4Address;
407 import java.net.InetAddress;
408 import java.net.InetSocketAddress;
409 import java.net.SocketException;
410 import java.net.UnknownHostException;
411 import java.util.ArrayList;
412 import java.util.Arrays;
413 import java.util.Collection;
414 import java.util.Collections;
415 import java.util.Comparator;
416 import java.util.ConcurrentModificationException;
417 import java.util.HashMap;
418 import java.util.HashSet;
419 import java.util.List;
420 import java.util.Map;
421 import java.util.Map.Entry;
422 import java.util.NoSuchElementException;
423 import java.util.Objects;
424 import java.util.Set;
425 import java.util.SortedSet;
426 import java.util.StringJoiner;
427 import java.util.TreeSet;
428 import java.util.concurrent.CopyOnWriteArraySet;
429 import java.util.concurrent.TimeUnit;
430 import java.util.concurrent.atomic.AtomicInteger;
431 import java.util.concurrent.atomic.AtomicReference;
432 import java.util.function.BiConsumer;
433 import java.util.function.Consumer;
434 import java.util.function.Predicate;
435 
436 /**
437  * @hide
438  */
439 public class ConnectivityService extends IConnectivityManager.Stub {
440     private static final String TAG = ConnectivityService.class.getSimpleName();
441 
442     private static final String DIAG_ARG = "--diag";
443     public static final String SHORT_ARG = "--short";
444     private static final String NETWORK_ARG = "networks";
445     private static final String REQUEST_ARG = "requests";
446     private static final String TRAFFICCONTROLLER_ARG = "trafficcontroller";
447     public static final String CLATEGRESS4RAWBPFMAP_ARG = "clatEgress4RawBpfMap";
448     public static final String CLATINGRESS6RAWBPFMAP_ARG = "clatIngress6RawBpfMap";
449 
450     private static final boolean DBG = true;
451     private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG);
452     private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
453 
454     private static final boolean LOGD_BLOCKED_NETWORKINFO = true;
455 
456     /**
457      * Default URL to use for {@link #getCaptivePortalServerUrl()}. This should not be changed
458      * by OEMs for configuration purposes, as this value is overridden by
459      * ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL.
460      * R.string.config_networkCaptivePortalServerUrl should be overridden instead for this purpose
461      * (preferably via runtime resource overlays).
462      */
463     private static final String DEFAULT_CAPTIVE_PORTAL_HTTP_URL =
464             "http://connectivitycheck.gstatic.com/generate_204";
465 
466     // TODO: create better separation between radio types and network types
467 
468     // how long to wait before switching back to a radio's default network
469     private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000;
470     // system property that can override the above value
471     private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
472             "android.telephony.apn-restore";
473 
474     // How long to wait before putting up a "This network doesn't have an Internet connection,
475     // connect anyway?" dialog after the user selects a network that doesn't validate.
476     private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000;
477 
478     // How long to wait before considering that a network is bad in the absence of any form
479     // of connectivity (valid, partial, captive portal). If none has been detected after this
480     // delay, the stack considers this network bad, which may affect how it's handled in ranking
481     // according to config_networkAvoidBadWifi.
482     // Timeout in case the "actively prefer bad wifi" feature is on
483     private static final int ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS = 20 * 1000;
484     // Timeout in case the "actively prefer bad wifi" feature is off
485     private static final int DEFAULT_EVALUATION_TIMEOUT_MS = 8 * 1000;
486 
487     // Default to 30s linger time-out, and 5s for nascent network. Modifiable only for testing.
488     private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger";
489     private static final int DEFAULT_LINGER_DELAY_MS = 30_000;
490     private static final int DEFAULT_NASCENT_DELAY_MS = 5_000;
491 
492     // Delimiter used when creating the broadcast delivery group for sending
493     // CONNECTIVITY_ACTION broadcast.
494     private static final char DELIVERY_GROUP_KEY_DELIMITER = ';';
495 
496     // The maximum value for the blocking validation result, in milliseconds.
497     public static final int MAX_VALIDATION_IGNORE_AFTER_ROAM_TIME_MS = 10000;
498 
499     // The maximum number of network request allowed per uid before an exception is thrown.
500     @VisibleForTesting
501     static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
502 
503     // The maximum number of network request allowed for system UIDs before an exception is thrown.
504     @VisibleForTesting
505     static final int MAX_NETWORK_REQUESTS_PER_SYSTEM_UID = 250;
506 
507     @VisibleForTesting
508     protected int mLingerDelayMs;  // Can't be final, or test subclass constructors can't change it.
509     @VisibleForTesting
510     protected int mNascentDelayMs;
511     // True if the cell radio of the device is capable of time-sharing.
512     @VisibleForTesting
513     protected boolean mCellularRadioTimesharingCapable = true;
514 
515     // How long to delay to removal of a pending intent based request.
516     // See ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS
517     private final int mReleasePendingIntentDelayMs;
518 
519     private final MockableSystemProperties mSystemProperties;
520 
521     private final PermissionMonitor mPermissionMonitor;
522 
523     @VisibleForTesting
524     final RequestInfoPerUidCounter mNetworkRequestCounter;
525     @VisibleForTesting
526     final RequestInfoPerUidCounter mSystemNetworkRequestCounter;
527 
528     private volatile boolean mLockdownEnabled;
529 
530     private final boolean mRequestRestrictedWifiEnabled;
531     private final boolean mBackgroundFirewallChainEnabled;
532 
533     private final boolean mUseDeclaredMethodsForCallbacksEnabled;
534     private final boolean mQueueNetworkAgentEventsInSystemServer;
535 
536     // Flag to delay callbacks for frozen apps, suppressing duplicate and stale callbacks.
537     private final boolean mQueueCallbacksForFrozenApps;
538 
539     /**
540      * Uids ConnectivityService tracks blocked status of to send blocked status callbacks.
541      * Key is uid based on mAsUid of registered networkRequestInfo
542      * Value is count of registered networkRequestInfo
543      *
544      * This is necessary because when a firewall chain is enabled or disabled, that affects all UIDs
545      * on the system, not just UIDs on that firewall chain. For example, entering doze mode affects
546      * all UIDs that are not on the dozable chain. ConnectivityService doesn't know which UIDs are
547      * running. But it only needs to send onBlockedStatusChanged to UIDs that have at least one
548      * NetworkCallback registered.
549      *
550      * UIDs are added to this list on the binder thread when processing requestNetwork and similar
551      * IPCs. They are removed from this list on the handler thread, when the callback unregistration
552      * is fully processed. They cannot be unregistered when the unregister IPC is processed because
553      * sometimes requests are unregistered on the handler thread.
554      */
555     @GuardedBy("mBlockedStatusTrackingUids")
556     private final SparseIntArray mBlockedStatusTrackingUids = new SparseIntArray();
557 
558     /**
559      * Stale copy of UID blocked reasons. This is used to send onBlockedStatusChanged
560      * callbacks. This is only used on the handler thread, so it does not require a lock.
561      * On U-, the blocked reasons come from NPMS.
562      * On V+, the blocked reasons come from the BPF map contents and only maintains blocked reasons
563      * of uids that register network callbacks.
564      */
565     private final SparseIntArray mUidBlockedReasons = new SparseIntArray();
566 
567     private final Context mContext;
568     private final ConnectivityResources mResources;
569     private final int mWakeUpMark;
570     private final int mWakeUpMask;
571     // The Context is created for UserHandle.ALL.
572     private final Context mUserAllContext;
573     private final Dependencies mDeps;
574     private final PermissionMonitor.Dependencies mPermissionMonitorDeps;
575     private final ConnectivityFlags mFlags;
576     // 0 is full bad, 100 is full good
577     private int mDefaultInetConditionPublished = 0;
578 
579     @VisibleForTesting
580     protected IDnsResolver mDnsResolver;
581     @VisibleForTesting
582     protected INetd mNetd;
583     private DscpPolicyTracker mDscpPolicyTracker = null;
584     private final NetworkStatsManager mStatsManager;
585     private final NetworkPolicyManager mPolicyManager;
586     private final BpfNetMaps mBpfNetMaps;
587     private final InterfaceTracker mInterfaceTracker;
588 
589     /**
590      * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple
591      * instances.
592      */
593     @GuardedBy("mTNSLock")
594     private TestNetworkService mTNS;
595     private final CompanionDeviceManagerProxyService mCdmps;
596     private final MulticastRoutingCoordinatorService mMulticastRoutingCoordinatorService;
597     private final RoutingCoordinatorService mRoutingCoordinatorService;
598 
599     private final Object mTNSLock = new Object();
600 
601     private String mCurrentTcpBufferSizes;
602 
603     private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(
604             new Class[] {
605                     ConnectivityService.class,
606                     NetworkAgent.class,
607                     NetworkAgentInfo.class,
608                     AutomaticOnOffKeepaliveTracker.class });
609 
610     private enum ReapUnvalidatedNetworks {
611         // Tear down networks that have no chance (e.g. even if validated) of becoming
612         // the highest scoring network satisfying a NetworkRequest.  This should be passed when
613         // all networks have been rematched against all NetworkRequests.
614         REAP,
615         // Don't reap networks.  This should be passed when some networks have not yet been
616         // rematched against all NetworkRequests.
617         DONT_REAP
618     }
619 
620     private enum UnneededFor {
621         LINGER,    // Determine whether this network is unneeded and should be lingered.
622         TEARDOWN,  // Determine whether this network is unneeded and should be torn down.
623     }
624 
625     /**
626      * For per-app preferences, requests contain an int to signify which request
627      * should have priority. The order is passed to netd which will use it together
628      * with UID ranges to generate the corresponding IP rule. This serves to
629      * direct device-originated data traffic of the specific UIDs to the correct
630      * default network for each app.
631      * Order ints passed to netd must be in the 0~999 range. Larger values code for
632      * a lower priority, see {@link NativeUidRangeConfig}.
633      * Note that only the highest priority preference is applied if the uid is the target of
634      * multiple preferences.
635      *
636      * Requests that don't code for a per-app preference use PREFERENCE_ORDER_INVALID.
637      * The default request uses PREFERENCE_ORDER_DEFAULT.
638      */
639     // Used when sending to netd to code for "no order".
640     static final int PREFERENCE_ORDER_NONE = 0;
641     // Order for requests that don't code for a per-app preference. As it is
642     // out of the valid range, the corresponding order should be
643     // PREFERENCE_ORDER_NONE when sending to netd.
644     @VisibleForTesting
645     static final int PREFERENCE_ORDER_INVALID = Integer.MAX_VALUE;
646     // As a security feature, VPNs have the top priority.
647     static final int PREFERENCE_ORDER_VPN = 0; // Netd supports only 0 for VPN.
648     // Order of per-app OEM preference. See {@link #setOemNetworkPreference}.
649     @VisibleForTesting
650     static final int PREFERENCE_ORDER_OEM = 10;
651     // Order of per-profile preference, such as used by enterprise networks.
652     // See {@link #setProfileNetworkPreference}.
653     @VisibleForTesting
654     static final int PREFERENCE_ORDER_PROFILE = 20;
655     // Order of user setting to prefer mobile data even when networks with
656     // better scores are connected.
657     // See {@link ConnectivitySettingsManager#setMobileDataPreferredUids}
658     @VisibleForTesting
659     static final int PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED = 30;
660     // Order of setting satellite network preference fallback when default message application
661     // with role_sms role and android.permission.SATELLITE_COMMUNICATION permission detected
662     @VisibleForTesting
663     static final int PREFERENCE_ORDER_SATELLITE_FALLBACK = 40;
664     // Preference order that signifies the network shouldn't be set as a default network for
665     // the UIDs, only give them access to it. TODO : replace this with a boolean
666     // in NativeUidRangeConfig
667     @VisibleForTesting
668     static final int PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT = 999;
669     // Bound for the lowest valid preference order.
670     static final int PREFERENCE_ORDER_LOWEST = 999;
671 
672     /**
673      * used internally to clear a wakelock when transitioning
674      * from one net to another.  Clear happens when we get a new
675      * network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens
676      * after a timeout if no network is found (typically 1 min).
677      */
678     private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8;
679 
680     /**
681      * used internally to reload global proxy settings
682      */
683     private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9;
684 
685     /**
686      * PAC manager has received new port.
687      */
688     private static final int EVENT_PAC_PROXY_HAS_CHANGED = 16;
689 
690     /**
691      * used internally when registering NetworkProviders
692      * obj = NetworkProviderInfo
693      */
694     private static final int EVENT_REGISTER_NETWORK_PROVIDER = 17;
695 
696     /**
697      * used internally when registering NetworkAgents
698      * obj = Messenger
699      */
700     private static final int EVENT_REGISTER_NETWORK_AGENT = 18;
701 
702     /**
703      * used to add a network request
704      * includes a NetworkRequestInfo
705      */
706     private static final int EVENT_REGISTER_NETWORK_REQUEST = 19;
707 
708     /**
709      * indicates a timeout period is over - check if we had a network yet or not
710      * and if not, call the timeout callback (but leave the request live until they
711      * cancel it.
712      * includes a NetworkRequestInfo
713      */
714     private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20;
715 
716     /**
717      * used to add a network listener - no request
718      * includes a NetworkRequestInfo
719      */
720     private static final int EVENT_REGISTER_NETWORK_LISTENER = 21;
721 
722     /**
723      * used to remove a network request, either a listener or a real request
724      * arg1 = UID of caller
725      * obj  = NetworkRequest
726      */
727     private static final int EVENT_RELEASE_NETWORK_REQUEST = 22;
728 
729     /**
730      * used internally when registering NetworkProviders
731      * obj = Messenger
732      */
733     private static final int EVENT_UNREGISTER_NETWORK_PROVIDER = 23;
734 
735     /**
736      * used internally to expire a wakelock when transitioning
737      * from one net to another.  Expire happens when we fail to find
738      * a new network (typically after 1 minute) -
739      * EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found
740      * a replacement network.
741      */
742     private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24;
743 
744     /**
745      * used to add a network request with a pending intent
746      * obj = NetworkRequestInfo
747      */
748     private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26;
749 
750     /**
751      * used to remove a pending intent and its associated network request.
752      * arg1 = UID of caller
753      * obj  = PendingIntent
754      */
755     private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27;
756 
757     /**
758      * used to specify whether a network should be used even if unvalidated.
759      * arg1 = whether to accept the network if it's unvalidated (1 or 0)
760      * arg2 = whether to remember this choice in the future (1 or 0)
761      * obj  = network
762      */
763     private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28;
764 
765     /**
766      * used internally to (re)configure always-on networks.
767      */
768     private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30;
769 
770     /**
771      * used to add a network listener with a pending intent
772      * obj = NetworkRequestInfo
773      */
774     private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
775 
776     /**
777      * used to specify whether a network should not be penalized when it becomes unvalidated.
778      */
779     private static final int EVENT_SET_AVOID_UNVALIDATED = 35;
780 
781     /**
782      * used to handle reported network connectivity. May trigger revalidation of a network.
783      */
784     private static final int EVENT_REPORT_NETWORK_CONNECTIVITY = 36;
785 
786     // Handle changes in Private DNS settings.
787     private static final int EVENT_PRIVATE_DNS_SETTINGS_CHANGED = 37;
788 
789     // Handle private DNS validation status updates.
790     private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
791 
792      /**
793       * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has
794       * been tested.
795       * obj = {@link NetworkTestedResults} representing information sent from NetworkMonitor.
796       * data = PersistableBundle of extras passed from NetworkMonitor. If {@link
797       * NetworkMonitorCallbacks#notifyNetworkTested} is called, this will be null.
798       */
799     private static final int EVENT_NETWORK_TESTED = 41;
800 
801     /**
802      * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the private DNS
803      * config was resolved.
804      * obj = PrivateDnsConfig
805      * arg2 = netid
806      */
807     private static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42;
808 
809     /**
810      * Request ConnectivityService display provisioning notification.
811      * arg1    = Whether to make the notification visible.
812      * arg2    = NetID.
813      * obj     = Intent to be launched when notification selected by user, null if !arg1.
814      */
815     private static final int EVENT_PROVISIONING_NOTIFICATION = 43;
816 
817     /**
818      * Used to specify whether a network should be used even if connectivity is partial.
819      * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for
820      * false)
821      * arg2 = whether to remember this choice in the future (1 for true or 0 for false)
822      * obj  = network
823      */
824     private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 44;
825 
826     /**
827      * Event for NetworkMonitor to inform ConnectivityService that the probe status has changed.
828      * Both of the arguments are bitmasks, and the value of bits come from
829      * INetworkMonitor.NETWORK_VALIDATION_PROBE_*.
830      * arg1 = unused
831      * arg2 = netId
832      * obj = A Pair of integers: the bitmasks of, respectively, completed and successful probes.
833      */
834     public static final int EVENT_PROBE_STATUS_CHANGED = 45;
835 
836     /**
837      * Event for NetworkMonitor to inform ConnectivityService that captive portal data has changed.
838      * arg1 = unused
839      * arg2 = netId
840      * obj = captive portal data
841      */
842     private static final int EVENT_CAPPORT_DATA_CHANGED = 46;
843 
844     /**
845      * Used by setRequireVpnForUids.
846      * arg1 = whether the specified UID ranges are required to use a VPN.
847      * obj  = Array of UidRange objects.
848      */
849     private static final int EVENT_SET_REQUIRE_VPN_FOR_UIDS = 47;
850 
851     /**
852      * Used internally when setting the default networks for OemNetworkPreferences.
853      * obj = Pair<OemNetworkPreferences, listener>
854      */
855     private static final int EVENT_SET_OEM_NETWORK_PREFERENCE = 48;
856 
857     /**
858      * Used to indicate the system default network becomes active.
859      */
860     private static final int EVENT_REPORT_NETWORK_ACTIVITY = 49;
861 
862     /**
863      * Used internally when setting a network preference for a user profile.
864      * obj = Pair<ProfileNetworkPreference, Listener>
865      */
866     private static final int EVENT_SET_PROFILE_NETWORK_PREFERENCE = 50;
867 
868     /**
869      * Event to update blocked reasons for uids.
870      * obj = List of Pair(uid, blockedReasons)
871      */
872     private static final int EVENT_BLOCKED_REASONS_CHANGED = 51;
873 
874     /**
875      * Event to register a new network offer
876      * obj = NetworkOffer
877      */
878     private static final int EVENT_REGISTER_NETWORK_OFFER = 52;
879 
880     /**
881      * Event to unregister an existing network offer
882      * obj = INetworkOfferCallback
883      */
884     private static final int EVENT_UNREGISTER_NETWORK_OFFER = 53;
885 
886     /**
887      * Used internally when MOBILE_DATA_PREFERRED_UIDS setting changed.
888      */
889     private static final int EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED = 54;
890 
891     /**
892      * Event to set temporary allow bad wifi within a limited time to override
893      * {@code config_networkAvoidBadWifi}.
894      */
895     private static final int EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL = 55;
896 
897     /**
898      * Used internally when INGRESS_RATE_LIMIT_BYTES_PER_SECOND setting changes.
899      */
900     private static final int EVENT_INGRESS_RATE_LIMIT_CHANGED = 56;
901 
902     /**
903      * The initial evaluation period is over for this network.
904      *
905      * If no form of connectivity has been found on this network (valid, partial, captive portal)
906      * then the stack will now consider it to have been determined bad.
907      */
908     private static final int EVENT_INITIAL_EVALUATION_TIMEOUT = 57;
909 
910     /**
911      * Used internally when the user does not want the network from captive portal app.
912      * obj = Network
913      */
914     private static final int EVENT_USER_DOES_NOT_WANT = 58;
915 
916     /**
917      * Event to set VPN as preferred network for specific apps.
918      * obj = VpnNetworkPreferenceInfo
919      */
920     private static final int EVENT_SET_VPN_NETWORK_PREFERENCE = 59;
921 
922     /**
923      * Event to use low TCP polling timer used in automatic on/off keepalive temporarily.
924      */
925     private static final int EVENT_SET_LOW_TCP_POLLING_UNTIL = 60;
926 
927     /**
928      * Event to inform the ConnectivityService handler when a uid has been frozen or unfrozen.
929      */
930     private static final int EVENT_UID_FROZEN_STATE_CHANGED = 61;
931 
932     /**
933      * Event to update firewall socket destroy reasons for uids.
934      * obj = List of Pair(uid, socketDestroyReasons)
935      */
936     private static final int EVENT_UPDATE_FIREWALL_DESTROY_SOCKET_REASONS = 62;
937 
938     /**
939      * Event to clear firewall socket destroy reasons for all uids.
940      * arg1 = socketDestroyReason
941      */
942     private static final int EVENT_CLEAR_FIREWALL_DESTROY_SOCKET_REASONS = 63;
943 
944     /**
945      * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
946      * should be shown.
947      */
948     private static final int PROVISIONING_NOTIFICATION_SHOW = 1;
949 
950     /**
951      * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
952      * should be hidden.
953      */
954     private static final int PROVISIONING_NOTIFICATION_HIDE = 0;
955 
956     /**
957      * The maximum alive time to allow bad wifi configuration for testing.
958      */
959     private static final long MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS = 5 * 60 * 1000L;
960 
961     /**
962      * The maximum alive time to decrease TCP polling timer in automatic on/off keepalive for
963      * testing.
964      */
965     private static final long MAX_TEST_LOW_TCP_POLLING_UNTIL_MS = 5 * 60 * 1000L;
966 
967     /**
968      * The priority of the tc police rate limiter -- smaller value is higher priority.
969      * This value needs to be coordinated with PRIO_CLAT, PRIO_TETHER4, and PRIO_TETHER6.
970      */
971     private static final short TC_PRIO_POLICE = 1;
972 
973     /**
974      * The BPF program attached to the tc-police hook to account for to-be-dropped traffic.
975      */
976     private static final String TC_POLICE_BPF_PROG_PATH =
977             "/sys/fs/bpf/netd_shared/prog_netd_schedact_ingress_account";
978 
eventName(int what)979     private static String eventName(int what) {
980         return sMagicDecoderRing.get(what, Integer.toString(what));
981     }
982 
getDnsResolver(Context context)983     private static IDnsResolver getDnsResolver(Context context) {
984         final DnsResolverServiceManager dsm = context.getSystemService(
985                 DnsResolverServiceManager.class);
986         return IDnsResolver.Stub.asInterface(dsm.getService());
987     }
988 
989     /** Handler thread used for all of the handlers below. */
990     @VisibleForTesting
991     protected final HandlerThread mHandlerThread;
992     /** Handler used for internal events. */
993     final private InternalHandler mHandler;
994     /** Handler used for incoming {@link NetworkStateTracker} events. */
995     final private NetworkStateTrackerHandler mTrackerHandler;
996     /** Handler used for processing {@link android.net.ConnectivityDiagnosticsManager} events */
997     @VisibleForTesting
998     final ConnectivityDiagnosticsHandler mConnectivityDiagnosticsHandler;
999 
1000     private final DnsManager mDnsManager;
1001     @VisibleForTesting
1002     final NetworkRanker mNetworkRanker;
1003 
1004     private boolean mSystemReady;
1005     private Intent mInitialBroadcast;
1006 
1007     private final PowerManager.WakeLock mNetTransitionWakeLock;
1008     private final PowerManager.WakeLock mPendingIntentWakeLock;
1009 
1010     // A helper object to track the current default HTTP proxy. ConnectivityService needs to tell
1011     // the world when it changes.
1012     private final ProxyTracker mProxyTracker;
1013 
1014     final private SettingsObserver mSettingsObserver;
1015 
1016     private final UserManager mUserManager;
1017 
1018     // the set of network types that can only be enabled by system/sig apps
1019     private final List<Integer> mProtectedNetworks;
1020 
1021     private Set<String> mWolSupportedInterfaces;
1022 
1023     private final TelephonyManager mTelephonyManager;
1024     private final CarrierPrivilegeAuthenticator mCarrierPrivilegeAuthenticator;
1025     private final AppOpsManager mAppOpsManager;
1026 
1027     private final LocationPermissionChecker mLocationPermissionChecker;
1028 
1029     private final AutomaticOnOffKeepaliveTracker mKeepaliveTracker;
1030     private final QosCallbackTracker mQosCallbackTracker;
1031     private final NetworkNotificationManager mNotifier;
1032     private final LingerMonitor mLingerMonitor;
1033     private final SatelliteAccessController mSatelliteAccessController;
1034 
1035     private final L2capNetworkProvider mL2capNetworkProvider;
1036 
1037     // sequence number of NetworkRequests
1038     private int mNextNetworkRequestId = NetworkRequest.FIRST_REQUEST_ID;
1039 
1040     // Sequence number for NetworkProvider IDs.
1041     private final AtomicInteger mNextNetworkProviderId = new AtomicInteger(
1042             NetworkProvider.FIRST_PROVIDER_ID);
1043 
1044     // NetworkRequest activity String log entries.
1045     private static final int MAX_NETWORK_REQUEST_LOGS = 20;
1046     private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS);
1047 
1048     // NetworkInfo blocked and unblocked String log entries
1049     private static final int MAX_NETWORK_INFO_LOGS = 40;
1050     private final LocalLog mNetworkInfoBlockingLogs = new LocalLog(MAX_NETWORK_INFO_LOGS);
1051 
1052     private static final int MAX_WAKELOCK_LOGS = 20;
1053     private final LocalLog mWakelockLogs = new LocalLog(MAX_WAKELOCK_LOGS);
1054     private int mTotalWakelockAcquisitions = 0;
1055     private int mTotalWakelockReleases = 0;
1056     private long mTotalWakelockDurationMs = 0;
1057     private long mMaxWakelockDurationMs = 0;
1058     private long mLastWakeLockAcquireTimestamp = 0;
1059 
1060     private final IpConnectivityLog mMetricsLog;
1061 
1062     @Nullable private final NetworkRequestStateStatsMetrics mNetworkRequestStateStatsMetrics;
1063 
1064     @GuardedBy("mBandwidthRequests")
1065     private final SparseArray<Integer> mBandwidthRequests = new SparseArray<>(10);
1066 
1067     @VisibleForTesting
1068     final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
1069 
1070     @VisibleForTesting
1071     final Map<IBinder, ConnectivityDiagnosticsCallbackInfo> mConnectivityDiagnosticsCallbacks =
1072             new HashMap<>();
1073 
1074     // Rate limit applicable to all internet capable networks (-1 = disabled). This value is
1075     // configured via {@link
1076     // ConnectivitySettingsManager#INGRESS_RATE_LIMIT_BYTES_PER_SECOND}
1077     // Only the handler thread is allowed to access this field.
1078     private long mIngressRateLimit = -1;
1079 
1080     // This is the cache for the packageName -> ApplicationSelfCertifiedNetworkCapabilities. This
1081     // value can be accessed from both handler thread and any random binder thread. Therefore,
1082     // accessing this value requires holding a lock. The cache is the same across all the users.
1083     @GuardedBy("mSelfCertifiedCapabilityCache")
1084     private final Map<String, ApplicationSelfCertifiedNetworkCapabilities>
1085             mSelfCertifiedCapabilityCache = new HashMap<>();
1086 
1087     // Flag to enable the feature of closing frozen app sockets.
1088     private final boolean mDestroyFrozenSockets;
1089 
1090     // Flag to optimize closing app sockets by waiting for the cellular modem to wake up.
1091     private final boolean mDelayDestroySockets;
1092 
1093     // Flag to allow SysUI to receive connectivity reports for wifi picker UI.
1094     private final boolean mAllowSysUiConnectivityReports;
1095 
1096     // Uids that ConnectivityService is pending to close sockets of.
1097     // Key is uid and value is reasons of socket destroy
1098     private final SparseIntArray mDestroySocketPendingUids = new SparseIntArray();
1099 
1100     private static final int DESTROY_SOCKET_REASON_NONE = 0;
1101     private static final int DESTROY_SOCKET_REASON_FROZEN = 1 << 0;
1102     private static final int DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND = 1 << 1;
1103 
1104     // Flag to drop packets to VPN addresses ingressing via non-VPN interfaces.
1105     private final boolean mIngressToVpnAddressFiltering;
1106 
1107     /**
1108      * Implements support for the legacy "one network per network type" model.
1109      *
1110      * We used to have a static array of NetworkStateTrackers, one for each
1111      * network type, but that doesn't work any more now that we can have,
1112      * for example, more that one wifi network. This class stores all the
1113      * NetworkAgentInfo objects that support a given type, but the legacy
1114      * API will only see the first one.
1115      *
1116      * It serves two main purposes:
1117      *
1118      * 1. Provide information about "the network for a given type" (since this
1119      *    API only supports one).
1120      * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if
1121      *    the first network for a given type changes, or if the default network
1122      *    changes.
1123      */
1124     @VisibleForTesting
1125     static class LegacyTypeTracker {
1126 
1127         private static final boolean DBG = true;
1128         private static final boolean VDBG = false;
1129 
1130         /**
1131          * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS).
1132          * Each list holds references to all NetworkAgentInfos that are used to
1133          * satisfy requests for that network type.
1134          *
1135          * This array is built out at startup such that an unsupported network
1136          * doesn't get an ArrayList instance, making this a tristate:
1137          * unsupported, supported but not active and active.
1138          *
1139          * The actual lists are populated when we scan the network types that
1140          * are supported on this device.
1141          *
1142          * Threading model:
1143          *  - addSupportedType() is only called in the constructor
1144          *  - add(), update(), remove() are only called from the ConnectivityService handler thread.
1145          *    They are therefore not thread-safe with respect to each other.
1146          *  - getNetworkForType() can be called at any time on binder threads. It is synchronized
1147          *    on mTypeLists to be thread-safe with respect to a concurrent remove call.
1148          *  - getRestoreTimerForType(type) is also synchronized on mTypeLists.
1149          *  - dump is thread-safe with respect to concurrent add and remove calls.
1150          */
1151         private final ArrayList<NetworkAgentInfo>[] mTypeLists;
1152         @NonNull
1153         private final ConnectivityService mService;
1154 
1155         // Restore timers for requestNetworkForFeature (network type -> timer in ms). Types without
1156         // an entry have no timer (equivalent to -1). Lazily loaded.
1157         @NonNull
1158         private ArrayMap<Integer, Integer> mRestoreTimers = new ArrayMap<>();
1159 
LegacyTypeTracker(@onNull ConnectivityService service)1160         LegacyTypeTracker(@NonNull ConnectivityService service) {
1161             mService = service;
1162             mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
1163         }
1164 
1165         // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is
1166         //  addressed.
1167         @TargetApi(Build.VERSION_CODES.S)
loadSupportedTypes(@onNull Context ctx, @NonNull TelephonyManager tm)1168         public void loadSupportedTypes(@NonNull Context ctx, @NonNull TelephonyManager tm) {
1169             final PackageManager pm = ctx.getPackageManager();
1170             if (pm.hasSystemFeature(FEATURE_WIFI)) {
1171                 addSupportedType(TYPE_WIFI);
1172             }
1173             if (pm.hasSystemFeature(FEATURE_WIFI_DIRECT)) {
1174                 addSupportedType(TYPE_WIFI_P2P);
1175             }
1176             if (tm.isDataCapable()) {
1177                 // Telephony does not have granular support for these types: they are either all
1178                 // supported, or none is supported
1179                 addSupportedType(TYPE_MOBILE);
1180                 addSupportedType(TYPE_MOBILE_MMS);
1181                 addSupportedType(TYPE_MOBILE_SUPL);
1182                 addSupportedType(TYPE_MOBILE_DUN);
1183                 addSupportedType(TYPE_MOBILE_HIPRI);
1184                 addSupportedType(TYPE_MOBILE_FOTA);
1185                 addSupportedType(TYPE_MOBILE_IMS);
1186                 addSupportedType(TYPE_MOBILE_CBS);
1187                 addSupportedType(TYPE_MOBILE_IA);
1188                 addSupportedType(TYPE_MOBILE_EMERGENCY);
1189             }
1190             if (pm.hasSystemFeature(FEATURE_BLUETOOTH)) {
1191                 addSupportedType(TYPE_BLUETOOTH);
1192             }
1193             if (pm.hasSystemFeature(FEATURE_WATCH)) {
1194                 // TYPE_PROXY is only used on Wear
1195                 addSupportedType(TYPE_PROXY);
1196             }
1197             // Ethernet is often not specified in the configs, although many devices can use it via
1198             // USB host adapters. Add it as long as the ethernet service is here.
1199             if (deviceSupportsEthernet(ctx)) {
1200                 addSupportedType(TYPE_ETHERNET);
1201             }
1202 
1203             // Always add TYPE_VPN as a supported type
1204             addSupportedType(TYPE_VPN);
1205         }
1206 
addSupportedType(int type)1207         private void addSupportedType(int type) {
1208             if (mTypeLists[type] != null) {
1209                 throw new IllegalStateException(
1210                         "legacy list for type " + type + "already initialized");
1211             }
1212             mTypeLists[type] = new ArrayList<>();
1213         }
1214 
isTypeSupported(int type)1215         public boolean isTypeSupported(int type) {
1216             return isNetworkTypeValid(type) && mTypeLists[type] != null;
1217         }
1218 
getNetworkForType(int type)1219         public NetworkAgentInfo getNetworkForType(int type) {
1220             synchronized (mTypeLists) {
1221                 if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) {
1222                     return mTypeLists[type].get(0);
1223                 }
1224             }
1225             return null;
1226         }
1227 
getRestoreTimerForType(int type)1228         public int getRestoreTimerForType(int type) {
1229             synchronized (mTypeLists) {
1230                 if (mRestoreTimers == null) {
1231                     mRestoreTimers = loadRestoreTimers();
1232                 }
1233                 return mRestoreTimers.getOrDefault(type, -1);
1234             }
1235         }
1236 
loadRestoreTimers()1237         private ArrayMap<Integer, Integer> loadRestoreTimers() {
1238             final String[] configs = mService.mResources.get().getStringArray(
1239                     R.array.config_legacy_networktype_restore_timers);
1240             final ArrayMap<Integer, Integer> ret = new ArrayMap<>(configs.length);
1241             for (final String config : configs) {
1242                 final String[] splits = TextUtils.split(config, ",");
1243                 if (splits.length != 2) {
1244                     logwtf("Invalid restore timer token count: " + config);
1245                     continue;
1246                 }
1247                 try {
1248                     ret.put(Integer.parseInt(splits[0]), Integer.parseInt(splits[1]));
1249                 } catch (NumberFormatException e) {
1250                     logwtf("Invalid restore timer number format: " + config, e);
1251                 }
1252             }
1253             return ret;
1254         }
1255 
maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, boolean isDefaultNetwork)1256         private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type,
1257                 boolean isDefaultNetwork) {
1258             if (DBG) {
1259                 log("Sending " + state
1260                         + " broadcast for type " + type + " " + nai.toShortString()
1261                         + " isDefaultNetwork=" + isDefaultNetwork);
1262             }
1263         }
1264 
1265         // When a lockdown VPN connects, send another CONNECTED broadcast for the underlying
1266         // network type, to preserve previous behaviour.
maybeSendLegacyLockdownBroadcast(@onNull NetworkAgentInfo vpnNai)1267         private void maybeSendLegacyLockdownBroadcast(@NonNull NetworkAgentInfo vpnNai) {
1268             if (vpnNai != mService.getLegacyLockdownNai()) return;
1269 
1270             if (vpnNai.declaredUnderlyingNetworks == null
1271                     || vpnNai.declaredUnderlyingNetworks.length != 1) {
1272                 Log.wtf(TAG, "Legacy lockdown VPN must have exactly one underlying network: "
1273                         + Arrays.toString(vpnNai.declaredUnderlyingNetworks));
1274                 return;
1275             }
1276             final NetworkAgentInfo underlyingNai = mService.getNetworkAgentInfoForNetwork(
1277                     vpnNai.declaredUnderlyingNetworks[0]);
1278             if (underlyingNai == null) return;
1279 
1280             final int type = underlyingNai.networkInfo.getType();
1281             final DetailedState state = DetailedState.CONNECTED;
1282             maybeLogBroadcast(underlyingNai, state, type, true /* isDefaultNetwork */);
1283             mService.sendLegacyNetworkBroadcast(underlyingNai, state, type);
1284         }
1285 
1286         /** Adds the given network to the specified legacy type list. */
add(int type, NetworkAgentInfo nai)1287         public void add(int type, NetworkAgentInfo nai) {
1288             if (!isTypeSupported(type)) {
1289                 return;  // Invalid network type.
1290             }
1291             if (VDBG) log("Adding agent " + nai + " for legacy network type " + type);
1292 
1293             ArrayList<NetworkAgentInfo> list = mTypeLists[type];
1294             if (list.contains(nai)) {
1295                 return;
1296             }
1297             synchronized (mTypeLists) {
1298                 list.add(nai);
1299             }
1300 
1301             // Send a broadcast if this is the first network of its type or if it's the default.
1302             final boolean isDefaultNetwork = mService.isDefaultNetwork(nai);
1303 
1304             // If a legacy lockdown VPN is active, override the NetworkInfo state in all broadcasts
1305             // to preserve previous behaviour.
1306             final DetailedState state = mService.getLegacyLockdownState(DetailedState.CONNECTED);
1307             if ((list.size() == 1) || isDefaultNetwork) {
1308                 maybeLogBroadcast(nai, state, type, isDefaultNetwork);
1309                 mService.sendLegacyNetworkBroadcast(nai, state, type);
1310             }
1311 
1312             if (type == TYPE_VPN && state == DetailedState.CONNECTED) {
1313                 maybeSendLegacyLockdownBroadcast(nai);
1314             }
1315         }
1316 
1317         /** Removes the given network from the specified legacy type list. */
remove(int type, NetworkAgentInfo nai, boolean wasDefault)1318         public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) {
1319             ArrayList<NetworkAgentInfo> list = mTypeLists[type];
1320             if (list == null || list.isEmpty()) {
1321                 return;
1322             }
1323             final boolean wasFirstNetwork = list.get(0).equals(nai);
1324 
1325             synchronized (mTypeLists) {
1326                 if (!list.remove(nai)) {
1327                     return;
1328                 }
1329             }
1330 
1331             if (wasFirstNetwork || wasDefault) {
1332                 maybeLogBroadcast(nai, DetailedState.DISCONNECTED, type, wasDefault);
1333                 mService.sendLegacyNetworkBroadcast(nai, DetailedState.DISCONNECTED, type);
1334             }
1335 
1336             if (!list.isEmpty() && wasFirstNetwork) {
1337                 if (DBG) log("Other network available for type " + type +
1338                               ", sending connected broadcast");
1339                 final NetworkAgentInfo replacement = list.get(0);
1340                 maybeLogBroadcast(replacement, DetailedState.CONNECTED, type,
1341                         mService.isDefaultNetwork(replacement));
1342                 mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type);
1343             }
1344         }
1345 
1346         /** Removes the given network from all legacy type lists. */
remove(NetworkAgentInfo nai, boolean wasDefault)1347         public void remove(NetworkAgentInfo nai, boolean wasDefault) {
1348             if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault);
1349             for (int type = 0; type < mTypeLists.length; type++) {
1350                 remove(type, nai, wasDefault);
1351             }
1352         }
1353 
1354         // send out another legacy broadcast - currently only used for suspend/unsuspend toggle
update(NetworkAgentInfo nai)1355         public void update(NetworkAgentInfo nai) {
1356             final boolean isDefault = mService.isDefaultNetwork(nai);
1357             final DetailedState state = nai.networkInfo.getDetailedState();
1358             for (int type = 0; type < mTypeLists.length; type++) {
1359                 final ArrayList<NetworkAgentInfo> list = mTypeLists[type];
1360                 final boolean contains = (list != null && list.contains(nai));
1361                 final boolean isFirst = contains && (nai == list.get(0));
1362                 if (isFirst || contains && isDefault) {
1363                     maybeLogBroadcast(nai, state, type, isDefault);
1364                     mService.sendLegacyNetworkBroadcast(nai, state, type);
1365                 }
1366             }
1367         }
1368 
dump(IndentingPrintWriter pw)1369         public void dump(IndentingPrintWriter pw) {
1370             pw.println("mLegacyTypeTracker:");
1371             pw.increaseIndent();
1372             pw.print("Supported types:");
1373             for (int type = 0; type < mTypeLists.length; type++) {
1374                 if (mTypeLists[type] != null) pw.print(" " + type);
1375             }
1376             pw.println();
1377             pw.println("Current state:");
1378             pw.increaseIndent();
1379             synchronized (mTypeLists) {
1380                 for (int type = 0; type < mTypeLists.length; type++) {
1381                     if (mTypeLists[type] == null || mTypeLists[type].isEmpty()) continue;
1382                     for (NetworkAgentInfo nai : mTypeLists[type]) {
1383                         pw.println(type + " " + nai.toShortString());
1384                     }
1385                 }
1386             }
1387             pw.decreaseIndent();
1388             pw.decreaseIndent();
1389             pw.println();
1390         }
1391     }
1392     private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
1393 
1394     final LocalPriorityDump mPriorityDumper = new LocalPriorityDump();
1395     /**
1396      * Helper class which parses out priority arguments and dumps sections according to their
1397      * priority. If priority arguments are omitted, function calls the legacy dump command.
1398      */
1399     private class LocalPriorityDump {
1400         private static final String PRIORITY_ARG = "--dump-priority";
1401         private static final String PRIORITY_ARG_HIGH = "HIGH";
1402         private static final String PRIORITY_ARG_NORMAL = "NORMAL";
1403         private static final int DUMPSYS_DEFAULT_TIMEOUT_MS = 10_000;
1404 
LocalPriorityDump()1405         LocalPriorityDump() {}
1406 
dumpHigh(FileDescriptor fd, PrintWriter pw)1407         private void dumpHigh(FileDescriptor fd, PrintWriter pw) {
1408             if (!HandlerUtils.runWithScissorsForDump(mHandler, () -> {
1409                 doDump(fd, pw, new String[]{DIAG_ARG});
1410                 doDump(fd, pw, new String[]{SHORT_ARG});
1411             }, DUMPSYS_DEFAULT_TIMEOUT_MS)) {
1412                 pw.println("dumpHigh timeout");
1413             }
1414         }
1415 
dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args)1416         private void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
1417             if (!HandlerUtils.runWithScissorsForDump(mHandler, () -> doDump(fd, pw, args),
1418                     DUMPSYS_DEFAULT_TIMEOUT_MS)) {
1419                 pw.println("dumpNormal timeout");
1420             }
1421         }
1422 
dump(FileDescriptor fd, PrintWriter pw, String[] args)1423         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1424             if (args == null) {
1425                 dumpNormal(fd, pw, args);
1426                 return;
1427             }
1428 
1429             String priority = null;
1430             for (int argIndex = 0; argIndex < args.length; argIndex++) {
1431                 if (args[argIndex].equals(PRIORITY_ARG) && argIndex + 1 < args.length) {
1432                     argIndex++;
1433                     priority = args[argIndex];
1434                 }
1435             }
1436 
1437             if (PRIORITY_ARG_HIGH.equals(priority)) {
1438                 dumpHigh(fd, pw);
1439             } else if (PRIORITY_ARG_NORMAL.equals(priority)) {
1440                 dumpNormal(fd, pw, args);
1441             } else {
1442                 // ConnectivityService publishes binder service using publishBinderService() with
1443                 // no priority assigned will be treated as NORMAL priority. Dumpsys does not send
1444                 // "--dump-priority" arguments to the service. Thus, dump NORMAL only to align the
1445                 // legacy output for dumpsys connectivity.
1446                 // TODO: Integrate into signal dump.
1447                 dumpNormal(fd, pw, args);
1448             }
1449         }
1450     }
1451 
1452     /**
1453      * Dependencies of ConnectivityService, for injection in tests.
1454      */
1455     @VisibleForTesting
1456     public static class Dependencies {
getCallingUid()1457         public int getCallingUid() {
1458             return Binder.getCallingUid();
1459         }
1460 
isAtLeastS()1461         public boolean isAtLeastS() {
1462             return SdkLevel.isAtLeastS();
1463         }
1464 
isAtLeastT()1465         public boolean isAtLeastT() {
1466             return SdkLevel.isAtLeastT();
1467         }
1468 
isAtLeastU()1469         public boolean isAtLeastU() {
1470             return SdkLevel.isAtLeastU();
1471         }
1472 
isAtLeastV()1473         public boolean isAtLeastV() {
1474             return SdkLevel.isAtLeastV();
1475         }
1476 
isAtLeastB()1477         public boolean isAtLeastB() {
1478             return SdkLevel.isAtLeastB();
1479         }
1480 
1481         /**
1482          * Get system properties to use in ConnectivityService.
1483          */
getSystemProperties()1484         public MockableSystemProperties getSystemProperties() {
1485             return new MockableSystemProperties();
1486         }
1487 
1488         /**
1489          * Get the {@link ConnectivityResources} to use in ConnectivityService.
1490          */
getResources(@onNull Context ctx)1491         public ConnectivityResources getResources(@NonNull Context ctx) {
1492             return new ConnectivityResources(ctx);
1493         }
1494 
1495         /**
1496          * Create a HandlerThread to use in ConnectivityService.
1497          */
makeHandlerThread(@onNull final String tag)1498         public HandlerThread makeHandlerThread(@NonNull final String tag) {
1499             return new HandlerThread(tag);
1500         }
1501 
1502         /**
1503          * Get a reference to the ModuleNetworkStackClient.
1504          */
getNetworkStack()1505         public NetworkStackClientBase getNetworkStack() {
1506             return ModuleNetworkStackClient.getInstance(null);
1507         }
1508 
1509         /**
1510          * @see ProxyTracker
1511          */
makeProxyTracker(@onNull Context context, @NonNull Handler connServiceHandler)1512         public ProxyTracker makeProxyTracker(@NonNull Context context,
1513                 @NonNull Handler connServiceHandler) {
1514             return new ProxyTracker(context, connServiceHandler, EVENT_PAC_PROXY_HAS_CHANGED);
1515         }
1516 
1517         /**
1518          * @see NetIdManager
1519          */
makeNetIdManager()1520         public NetIdManager makeNetIdManager() {
1521             return new NetIdManager();
1522         }
1523 
1524         /**
1525          * @see NetworkUtils#queryUserAccess(int, int)
1526          */
queryUserAccess(int uid, Network network, ConnectivityService cs)1527         public boolean queryUserAccess(int uid, Network network, ConnectivityService cs) {
1528             return cs.queryUserAccess(uid, network);
1529         }
1530 
1531         /**
1532          * Gets the UID that owns a socket connection. Needed because opening SOCK_DIAG sockets
1533          * requires CAP_NET_ADMIN, which the unit tests do not have.
1534          */
getConnectionOwnerUid(int protocol, InetSocketAddress local, InetSocketAddress remote)1535         public int getConnectionOwnerUid(int protocol, InetSocketAddress local,
1536                 InetSocketAddress remote) {
1537             return InetDiagMessage.getConnectionOwnerUid(protocol, local, remote);
1538         }
1539 
1540         /**
1541          * @see MultinetworkPolicyTracker
1542          */
makeMultinetworkPolicyTracker( @onNull Context c, @NonNull Handler h, @NonNull Runnable r)1543         public MultinetworkPolicyTracker makeMultinetworkPolicyTracker(
1544                 @NonNull Context c, @NonNull Handler h, @NonNull Runnable r) {
1545             return new MultinetworkPolicyTracker(c, h, r);
1546         }
1547 
1548         /**
1549          * @see AutomaticOnOffKeepaliveTracker
1550          */
makeAutomaticOnOffKeepaliveTracker( @onNull Context c, @NonNull Handler h)1551         public AutomaticOnOffKeepaliveTracker makeAutomaticOnOffKeepaliveTracker(
1552                 @NonNull Context c, @NonNull Handler h) {
1553             return new AutomaticOnOffKeepaliveTracker(c, h);
1554         }
1555 
makeMulticastRoutingCoordinatorService( @onNull Handler h)1556         public MulticastRoutingCoordinatorService makeMulticastRoutingCoordinatorService(
1557                     @NonNull Handler h) {
1558             try {
1559                 return new MulticastRoutingCoordinatorService(h);
1560             } catch (UnsupportedOperationException e) {
1561                 // Multicast routing is not supported by the kernel
1562                 Log.i(TAG, "Skipping unsupported MulticastRoutingCoordinatorService");
1563                 return null;
1564             }
1565         }
1566 
1567         /**
1568          * @see NetworkRequestStateStatsMetrics
1569          */
makeNetworkRequestStateStatsMetrics( Context context)1570         public NetworkRequestStateStatsMetrics makeNetworkRequestStateStatsMetrics(
1571                 Context context) {
1572             // We currently have network requests metric for Watch devices only
1573             if (context.getPackageManager().hasSystemFeature(FEATURE_WATCH)) {
1574                 return new NetworkRequestStateStatsMetrics();
1575             } else {
1576                 return null;
1577             }
1578         }
1579 
1580         /**
1581          * @see BatteryStatsManager
1582          */
reportNetworkInterfaceForTransports(Context context, String iface, int[] transportTypes)1583         public void reportNetworkInterfaceForTransports(Context context, String iface,
1584                 int[] transportTypes) {
1585             final BatteryStatsManager batteryStats =
1586                     context.getSystemService(BatteryStatsManager.class);
1587             batteryStats.reportNetworkInterfaceForTransports(iface, transportTypes);
1588         }
1589 
getCellular464XlatEnabled()1590         public boolean getCellular464XlatEnabled() {
1591             return NetworkProperties.isCellular464XlatEnabled().orElse(true);
1592         }
1593 
1594         /**
1595          * @see PendingIntent#intentFilterEquals
1596          */
intentFilterEquals(PendingIntent a, PendingIntent b)1597         public boolean intentFilterEquals(PendingIntent a, PendingIntent b) {
1598             return a.intentFilterEquals(b);
1599         }
1600 
1601         /**
1602          * @see LocationPermissionChecker
1603          */
makeLocationPermissionChecker(Context context)1604         public LocationPermissionChecker makeLocationPermissionChecker(Context context) {
1605             return new LocationPermissionChecker(context);
1606         }
1607 
1608         /**
1609          * @see CarrierPrivilegeAuthenticator
1610          *
1611          * This method returns null in versions before T, where carrier privilege
1612          * authentication is not supported.
1613          */
1614         @Nullable
makeCarrierPrivilegeAuthenticator( @onNull final Context context, @NonNull final TelephonyManager tm, boolean requestRestrictedWifiEnabled, @NonNull BiConsumer<Integer, Integer> listener, @NonNull final Handler connectivityServiceHandler)1615         public CarrierPrivilegeAuthenticator makeCarrierPrivilegeAuthenticator(
1616                 @NonNull final Context context,
1617                 @NonNull final TelephonyManager tm,
1618                 boolean requestRestrictedWifiEnabled,
1619                 @NonNull BiConsumer<Integer, Integer> listener,
1620                 @NonNull final Handler connectivityServiceHandler) {
1621             if (isAtLeastT()) {
1622                 return new CarrierPrivilegeAuthenticator(context, tm, requestRestrictedWifiEnabled,
1623                         listener, connectivityServiceHandler);
1624             } else {
1625                 return null;
1626             }
1627         }
1628 
1629         /**
1630          * @see SatelliteAccessController
1631          */
1632         @Nullable
makeSatelliteAccessController( @onNull final Context context, Consumer<Set<Integer>> updateSatelliteNetworkFallbackUidCallback, @NonNull final Handler connectivityServiceInternalHandler)1633         public SatelliteAccessController makeSatelliteAccessController(
1634                 @NonNull final Context context,
1635                 Consumer<Set<Integer>> updateSatelliteNetworkFallbackUidCallback,
1636                 @NonNull final Handler connectivityServiceInternalHandler) {
1637             return new SatelliteAccessController(context, updateSatelliteNetworkFallbackUidCallback,
1638                     connectivityServiceInternalHandler);
1639         }
1640 
1641         /** Creates an L2capNetworkProvider */
makeL2capNetworkProvider(Context context)1642         public L2capNetworkProvider makeL2capNetworkProvider(Context context) {
1643             return new L2capNetworkProvider(context);
1644         }
1645 
1646         /** Returns the data inactivity timeout to be used for cellular networks */
getDefaultCellularDataInactivityTimeout()1647         public int getDefaultCellularDataInactivityTimeout() {
1648             return DeviceConfigUtils.getDeviceConfigPropertyInt(NAMESPACE_TETHERING_BOOT,
1649                     CELLULAR_DATA_INACTIVITY_TIMEOUT, 10);
1650         }
1651 
1652         /** Returns the data inactivity timeout to be used for WiFi networks */
getDefaultWifiDataInactivityTimeout()1653         public int getDefaultWifiDataInactivityTimeout() {
1654             return DeviceConfigUtils.getDeviceConfigPropertyInt(NAMESPACE_TETHERING_BOOT,
1655                     WIFI_DATA_INACTIVITY_TIMEOUT, 15);
1656         }
1657 
1658         /**
1659          * @see DeviceConfigUtils#isTetheringFeatureEnabled
1660          */
isFeatureEnabled(Context context, String name)1661         public boolean isFeatureEnabled(Context context, String name) {
1662             return DeviceConfigUtils.isTetheringFeatureEnabled(context, name);
1663         }
1664 
1665         /**
1666          * @see DeviceConfigUtils#isTetheringFeatureNotChickenedOut
1667          */
isFeatureNotChickenedOut(Context context, String name)1668         public boolean isFeatureNotChickenedOut(Context context, String name) {
1669             return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(context, name);
1670         }
1671 
1672         /**
1673          * Get the BpfNetMaps implementation to use in ConnectivityService.
1674          * @param netd a netd binder
1675          * @return BpfNetMaps implementation.
1676          */
getBpfNetMaps(Context context, INetd netd, InterfaceTracker interfaceTracker)1677         public BpfNetMaps getBpfNetMaps(Context context, INetd netd,
1678                 InterfaceTracker interfaceTracker) {
1679             return new BpfNetMaps(context, netd, interfaceTracker);
1680         }
1681 
1682         /**
1683          * Get the InterfaceTracker implementation to use in ConnectivityService.
1684          * @return InterfaceTracker implementation.
1685          */
getInterfaceTracker(Context context)1686         public InterfaceTracker getInterfaceTracker(Context context) {
1687             return new InterfaceTracker(context);
1688         }
1689 
1690         /**
1691          * @see ClatCoordinator
1692          */
1693         @RequiresApi(Build.VERSION_CODES.TIRAMISU)
getClatCoordinator(INetd netd)1694         public ClatCoordinator getClatCoordinator(INetd netd) {
1695             return new ClatCoordinator(
1696                 new ClatCoordinator.Dependencies() {
1697                     @NonNull
1698                     public INetd getNetd() {
1699                         return netd;
1700                     }
1701                 });
1702         }
1703 
1704         /**
1705          * Wraps {@link TcUtils#tcFilterAddDevIngressPolice}
1706          */
enableIngressRateLimit(String iface, long rateInBytesPerSecond)1707         public void enableIngressRateLimit(String iface, long rateInBytesPerSecond) {
1708             final InterfaceParams params = InterfaceParams.getByName(iface);
1709             if (params == null) {
1710                 // the interface might have disappeared.
1711                 logw("Failed to get interface params for interface " + iface);
1712                 return;
1713             }
1714             try {
1715                 // converting rateInBytesPerSecond from long to int is safe here because the
1716                 // setting's range is limited to INT_MAX.
1717                 // TODO: add long/uint64 support to tcFilterAddDevIngressPolice.
1718                 Log.i(TAG,
1719                         "enableIngressRateLimit on " + iface + ": " + rateInBytesPerSecond + "B/s");
1720                 TcUtils.tcFilterAddDevIngressPolice(params.index, TC_PRIO_POLICE, (short) ETH_P_ALL,
1721                         (int) rateInBytesPerSecond, TC_POLICE_BPF_PROG_PATH);
1722             } catch (IOException e) {
1723                 loge("TcUtils.tcFilterAddDevIngressPolice(ifaceIndex=" + params.index
1724                         + ", PRIO_POLICE, ETH_P_ALL, rateInBytesPerSecond="
1725                         + rateInBytesPerSecond + ", bpfProgPath=" + TC_POLICE_BPF_PROG_PATH
1726                         + ") failure: ", e);
1727             }
1728         }
1729 
1730         /**
1731          * Wraps {@link TcUtils#tcFilterDelDev}
1732          */
disableIngressRateLimit(String iface)1733         public void disableIngressRateLimit(String iface) {
1734             final InterfaceParams params = InterfaceParams.getByName(iface);
1735             if (params == null) {
1736                 // the interface might have disappeared.
1737                 logw("Failed to get interface params for interface " + iface);
1738                 return;
1739             }
1740             try {
1741                 Log.i(TAG,
1742                         "disableIngressRateLimit on " + iface);
1743                 TcUtils.tcFilterDelDev(params.index, true, TC_PRIO_POLICE, (short) ETH_P_ALL);
1744             } catch (IOException e) {
1745                 loge("TcUtils.tcFilterDelDev(ifaceIndex=" + params.index
1746                         + ", ingress=true, PRIO_POLICE, ETH_P_ALL) failure: ", e);
1747             }
1748         }
1749 
1750         /**
1751          * Get BPF program Id from CGROUP. See {@link BpfUtils#getProgramId}.
1752          */
getBpfProgramId(final int attachType)1753         public int getBpfProgramId(final int attachType)
1754                 throws IOException {
1755             return BpfUtils.getProgramId(attachType);
1756         }
1757 
1758         /**
1759          * Wraps {@link BroadcastOptionsShimImpl#newInstance(BroadcastOptions)}
1760          */
1761         // TODO: when available in all active branches:
1762         //  @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
1763         @RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT)
makeBroadcastOptionsShim(BroadcastOptions options)1764         public BroadcastOptionsShim makeBroadcastOptionsShim(BroadcastOptions options) {
1765             return BroadcastOptionsShimImpl.newInstance(options);
1766         }
1767 
1768         /**
1769          * Wrapper method for
1770          * {@link android.app.compat.CompatChanges#isChangeEnabled(long, String, UserHandle)}.
1771          *
1772          * @param changeId    The ID of the compatibility change in question.
1773          * @param packageName The package name of the app in question.
1774          * @param user        The user that the operation is done for.
1775          * @return {@code true} if the change is enabled for the specified package.
1776          */
isChangeEnabled(long changeId, @NonNull final String packageName, @NonNull final UserHandle user)1777         public boolean isChangeEnabled(long changeId, @NonNull final String packageName,
1778                 @NonNull final UserHandle user) {
1779             return CompatChanges.isChangeEnabled(changeId, packageName, user);
1780         }
1781 
1782         /**
1783          * As above but with a UID.
1784          * @see CompatChanges#isChangeEnabled(long, int)
1785          */
isChangeEnabled(final long changeId, final int uid)1786         public boolean isChangeEnabled(final long changeId, final int uid) {
1787             return CompatChanges.isChangeEnabled(changeId, uid);
1788         }
1789 
1790         /**
1791          * Call {@link InetDiagMessage#destroyLiveTcpSockets(Set, Set)}
1792          *
1793          * @param ranges target uid ranges
1794          * @param exemptUids uids to skip close socket
1795          */
destroyLiveTcpSockets(@onNull final Set<Range<Integer>> ranges, @NonNull final Set<Integer> exemptUids)1796         public void destroyLiveTcpSockets(@NonNull final Set<Range<Integer>> ranges,
1797                 @NonNull final Set<Integer> exemptUids)
1798                 throws SocketException, InterruptedIOException, ErrnoException {
1799             InetDiagMessage.destroyLiveTcpSockets(ranges, exemptUids);
1800         }
1801 
1802         /**
1803          * Call {@link InetDiagMessage#destroyLiveTcpSocketsByOwnerUids(Set)}
1804          *
1805          * @param ownerUids target uids to close sockets
1806          */
destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids)1807         public void destroyLiveTcpSocketsByOwnerUids(final Set<Integer> ownerUids)
1808                 throws SocketException, InterruptedIOException, ErrnoException {
1809             InetDiagMessage.destroyLiveTcpSocketsByOwnerUids(ownerUids);
1810         }
1811 
1812         /**
1813          * Schedule the evaluation timeout.
1814          *
1815          * When a network connects, it's "not evaluated" yet. Detection events cause the network
1816          * to be "evaluated" (typically, validation or detection of a captive portal). If none
1817          * of these events happen, this time will run out, after which the network is considered
1818          * "evaluated" even if nothing happened to it. Notionally that means the system gave up
1819          * on this network and considers it won't provide connectivity. In particular, that means
1820          * it's when the system prefers it to cell if it's wifi and configuration says it should
1821          * prefer bad wifi to cell.
1822          */
scheduleEvaluationTimeout(@onNull Handler handler, @NonNull final Network network, final long delayMs)1823         public void scheduleEvaluationTimeout(@NonNull Handler handler,
1824                 @NonNull final Network network, final long delayMs) {
1825             handler.sendMessageDelayed(
1826                     handler.obtainMessage(EVENT_INITIAL_EVALUATION_TIMEOUT, network), delayMs);
1827         }
1828     }
1829 
1830     public ConnectivityService(Context context) {
1831         this(context, getDnsResolver(context), new IpConnectivityLog(),
1832                 INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)),
1833                 new Dependencies(), new PermissionMonitor.Dependencies());
1834     }
1835 
1836     @VisibleForTesting
1837     protected ConnectivityService(Context context, IDnsResolver dnsresolver,
1838             IpConnectivityLog logger, INetd netd, Dependencies deps,
1839             PermissionMonitor.Dependencies mPermDeps) {
1840         if (DBG) log("ConnectivityService starting up");
1841 
1842         mDeps = Objects.requireNonNull(deps, "missing Dependencies");
1843         mFlags = new ConnectivityFlags();
1844         mSystemProperties = mDeps.getSystemProperties();
1845         mNetIdManager = mDeps.makeNetIdManager();
1846         mContext = Objects.requireNonNull(context, "missing Context");
1847         mResources = deps.getResources(mContext);
1848         // The legacy PerUidCounter is buggy and throwing exception at count == limit.
1849         // Pass limit - 1 to maintain backward compatibility.
1850         // TODO: Remove the workaround.
1851         mNetworkRequestCounter =
1852                 new RequestInfoPerUidCounter(MAX_NETWORK_REQUESTS_PER_UID - 1);
1853         mSystemNetworkRequestCounter =
1854                 new RequestInfoPerUidCounter(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1);
1855 
1856         mMetricsLog = logger;
1857         mNetworkRequestStateStatsMetrics = mDeps.makeNetworkRequestStateStatsMetrics(mContext);
1858         final NetworkRequest defaultInternetRequest = createDefaultRequest();
1859         mDefaultRequest = new NetworkRequestInfo(
1860                 Process.myUid(), defaultInternetRequest, null,
1861                 null /* binder */, NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
1862                 null /* attributionTags */, DECLARED_METHODS_NONE);
1863         mNetworkRequests.put(defaultInternetRequest, mDefaultRequest);
1864         mDefaultNetworkRequests.add(mDefaultRequest);
1865         mNetworkRequestInfoLogs.log("REGISTER " + mDefaultRequest);
1866 
1867         mDefaultMobileDataRequest = createDefaultInternetRequestForTransport(
1868                 NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST);
1869 
1870         // The default WiFi request is a background request so that apps using WiFi are
1871         // migrated to a better network (typically ethernet) when one comes up, instead
1872         // of staying on WiFi forever.
1873         mDefaultWifiRequest = createDefaultInternetRequestForTransport(
1874                 NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST);
1875 
1876         mDefaultVehicleRequest = createAlwaysOnRequestForCapability(
1877                 NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL,
1878                 NetworkRequest.Type.BACKGROUND_REQUEST);
1879 
1880         mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
1881         // TODO: Consider making the timer customizable.
1882         mNascentDelayMs = DEFAULT_NASCENT_DELAY_MS;
1883         mCellularRadioTimesharingCapable =
1884                 mResources.get().getBoolean(R.bool.config_cellular_radio_timesharing_capable);
1885 
1886         int mark = mResources.get().getInteger(R.integer.config_networkWakeupPacketMark);
1887         int mask = mResources.get().getInteger(R.integer.config_networkWakeupPacketMask);
1888 
1889         if (SdkLevel.isAtLeastU()) {
1890             // U+ default value of both mark & mask, this is the top bit of the skb->mark,
1891             // see //system/netd/include/FwMark.h union Fwmark, field ingress_cpu_wakeup
1892             final int defaultUMarkMask = 0x80000000;  // u32
1893 
1894             if ((mark == 0) || (mask == 0)) {
1895                 // simply treat unset/disabled as the default U value
1896                 mark = defaultUMarkMask;
1897                 mask = defaultUMarkMask;
1898             }
1899             if ((mark != defaultUMarkMask) || (mask != defaultUMarkMask)) {
1900                 // invalid device overlay settings
1901                 throw new IllegalArgumentException(
1902                         "Bad config_networkWakeupPacketMark/Mask " + mark + "/" + mask);
1903             }
1904         }
1905 
1906         mWakeUpMark = mark;
1907         mWakeUpMask = mask;
1908 
1909         mNetd = netd;
1910         mInterfaceTracker = mDeps.getInterfaceTracker(mContext);
1911         mBpfNetMaps = mDeps.getBpfNetMaps(mContext, netd, mInterfaceTracker);
1912         mHandlerThread = mDeps.makeHandlerThread("ConnectivityServiceThread");
1913         mPermissionMonitorDeps = mPermDeps;
1914         mPermissionMonitor =
1915                 new PermissionMonitor(mContext, mNetd, mBpfNetMaps, mPermissionMonitorDeps,
1916                         mHandlerThread);
1917         mHandlerThread.start();
1918         mHandler = new InternalHandler(mHandlerThread.getLooper());
1919         mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper());
1920         mConnectivityDiagnosticsHandler =
1921                 new ConnectivityDiagnosticsHandler(mHandlerThread.getLooper());
1922 
1923         mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(),
1924                 ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000);
1925 
1926         mStatsManager = mContext.getSystemService(NetworkStatsManager.class);
1927         mPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
1928         mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver");
1929         mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
1930 
1931         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
1932         mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
1933         mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext);
1934         mRequestRestrictedWifiEnabled = mDeps.isAtLeastU()
1935                 && mDeps.isFeatureEnabled(context, REQUEST_RESTRICTED_WIFI);
1936         mBackgroundFirewallChainEnabled = mDeps.isAtLeastV() && mDeps.isFeatureNotChickenedOut(
1937                 context, ConnectivityFlags.BACKGROUND_FIREWALL_CHAIN);
1938         mUseDeclaredMethodsForCallbacksEnabled =
1939                 mDeps.isFeatureNotChickenedOut(context,
1940                         ConnectivityFlags.USE_DECLARED_METHODS_FOR_CALLBACKS);
1941         mQueueNetworkAgentEventsInSystemServer = mDeps.isAtLeastB()
1942                 && mDeps.isFeatureNotChickenedOut(context,
1943                         ConnectivityFlags.QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER);
1944         // registerUidFrozenStateChangedCallback is only available on U+
1945         mQueueCallbacksForFrozenApps = mDeps.isAtLeastU()
1946                 && mDeps.isFeatureNotChickenedOut(context, QUEUE_CALLBACKS_FOR_FROZEN_APPS);
1947         mCarrierPrivilegeAuthenticator = mDeps.makeCarrierPrivilegeAuthenticator(
1948                 mContext, mTelephonyManager, mRequestRestrictedWifiEnabled,
1949                 this::handleUidCarrierPrivilegesLost, mHandler);
1950 
1951         if (mDeps.isAtLeastU()
1952                 && mDeps
1953                 .isFeatureNotChickenedOut(mContext, ALLOW_SATALLITE_NETWORK_FALLBACK)) {
1954             mSatelliteAccessController = mDeps.makeSatelliteAccessController(
1955                     mContext, this::updateSatelliteNetworkPreferenceUids, mHandler);
1956         } else {
1957             mSatelliteAccessController = null;
1958         }
1959 
1960         // To ensure uid state is synchronized with Network Policy, register for
1961         // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
1962         // reading existing policy from disk.
1963         // If shouldTrackUidsForBlockedStatusCallbacks() is true (On V+), ConnectivityService
1964         // updates blocked reasons when firewall chain and data saver status is updated based on
1965         // bpf map contents instead of receiving callbacks from NPMS
1966         if (!shouldTrackUidsForBlockedStatusCallbacks()) {
1967             mPolicyManager.registerNetworkPolicyCallback(null, mPolicyCallback);
1968         }
1969 
1970         final PowerManager powerManager = (PowerManager) context.getSystemService(
1971                 Context.POWER_SERVICE);
1972         mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
1973         mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
1974 
1975         mLegacyTypeTracker.loadSupportedTypes(mContext, mTelephonyManager);
1976         mProtectedNetworks = new ArrayList<>();
1977         int[] protectedNetworks = mResources.get().getIntArray(R.array.config_protectedNetworks);
1978         for (int p : protectedNetworks) {
1979             if (mLegacyTypeTracker.isTypeSupported(p) && !mProtectedNetworks.contains(p)) {
1980                 mProtectedNetworks.add(p);
1981             } else {
1982                 if (DBG) loge("Ignoring protectedNetwork " + p);
1983             }
1984         }
1985 
1986         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
1987 
1988         mUserAllContext = mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */);
1989         // Listen for user add/removes to inform PermissionMonitor.
1990         // Should run on mHandler to avoid any races.
1991         final IntentFilter userIntentFilter = new IntentFilter();
1992         userIntentFilter.addAction(Intent.ACTION_USER_ADDED);
1993         userIntentFilter.addAction(Intent.ACTION_USER_REMOVED);
1994         mUserAllContext.registerReceiver(mUserIntentReceiver, userIntentFilter,
1995                 null /* broadcastPermission */, mHandler);
1996 
1997         // Listen to package add/removes for netd
1998         final IntentFilter packageIntentFilter = new IntentFilter();
1999         packageIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
2000         packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
2001         packageIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
2002         packageIntentFilter.addDataScheme("package");
2003         mUserAllContext.registerReceiver(mPackageIntentReceiver, packageIntentFilter,
2004                 null /* broadcastPermission */, mHandler);
2005 
2006         // This is needed for pre-V devices to propagate the data saver status
2007         // to the BPF map. This isn't supported before Android T because BPF maps are
2008         // unsupported, and it's also unnecessary on Android V and later versions,
2009         // as the platform code handles data saver bit updates. Additionally, checking
2010         // the initial data saver status here is superfluous because the intent won't
2011         // be sent until the system is ready.
2012         if (mDeps.isAtLeastT() && !mDeps.isAtLeastV()) {
2013             final IntentFilter dataSaverIntentFilter =
2014                     new IntentFilter(ACTION_RESTRICT_BACKGROUND_CHANGED);
2015             mUserAllContext.registerReceiver(mDataSaverReceiver, dataSaverIntentFilter,
2016                     null /* broadcastPermission */, mHandler);
2017         }
2018 
2019         // TrackMultiNetworkActivities feature should be enabled by trunk stable flag.
2020         // But reading the trunk stable flags from mainline modules is not supported yet.
2021         // So enabling this feature on V+ release.
2022         mTrackMultiNetworkActivities = mDeps.isAtLeastV();
2023         final int defaultCellularDataInactivityTimeout =
2024                 mDeps.getDefaultCellularDataInactivityTimeout();
2025         final int defaultWifiDataInactivityTimeout =
2026                 mDeps.getDefaultWifiDataInactivityTimeout();
2027         mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mNetd, mHandler,
2028                 mTrackMultiNetworkActivities, defaultCellularDataInactivityTimeout,
2029                 defaultWifiDataInactivityTimeout);
2030 
2031         final NetdCallback netdCallback = new NetdCallback();
2032         try {
2033             mNetd.registerUnsolicitedEventListener(netdCallback);
2034         } catch (RemoteException | ServiceSpecificException e) {
2035             loge("Error registering event listener :" + e);
2036         }
2037 
2038         mSettingsObserver = new SettingsObserver(mContext, mHandler);
2039         registerSettingsCallbacks();
2040 
2041         mKeepaliveTracker = mDeps.makeAutomaticOnOffKeepaliveTracker(mContext, mHandler);
2042         mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager);
2043         mQosCallbackTracker = new QosCallbackTracker(mHandler, mNetworkRequestCounter);
2044 
2045         final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(),
2046                 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT,
2047                 LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT);
2048         final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(),
2049                 ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS,
2050                 LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS);
2051         mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit);
2052 
2053         mMultinetworkPolicyTracker = mDeps.makeMultinetworkPolicyTracker(
2054                 mContext, mHandler, () -> updateAvoidBadWifi());
2055         mNetworkRanker =
2056                 new NetworkRanker(new NetworkRanker.Configuration(activelyPreferBadWifi()));
2057 
2058         mMultinetworkPolicyTracker.start();
2059 
2060         mDnsManager = new DnsManager(mContext, mDnsResolver);
2061         registerPrivateDnsSettingsCallbacks();
2062 
2063         // This NAI is a sentinel used to offer no service to apps that are on a multi-layer
2064         // request that doesn't allow fallback to the default network. It should never be visible
2065         // to apps. As such, it's not in the list of NAIs and doesn't need many of the normal
2066         // arguments like the handler or the DnsResolver.
2067         // TODO : remove this ; it is probably better handled with a sentinel request.
2068         mNoServiceNetwork = new NetworkAgentInfo(null,
2069                 new Network(INetd.UNREACHABLE_NET_ID),
2070                 new NetworkInfo(TYPE_NONE, 0, "", ""),
2071                 new LinkProperties(), new NetworkCapabilities(), null /* localNetworkConfig */,
2072                 new NetworkScore.Builder().setLegacyInt(0).build(), mContext, null,
2073                 new NetworkAgentConfig(), this, null, null, 0, INVALID_UID,
2074                 mLingerDelayMs, mQosCallbackTracker, mDeps);
2075 
2076         try {
2077             // DscpPolicyTracker cannot run on S because on S the tethering module can only load
2078             // BPF programs/maps into /sys/fs/tethering/bpf, which the system server cannot access.
2079             // Even if it could, running on S would at least require mocking out the BPF map,
2080             // otherwise the unit tests will fail on pre-T devices where the seccomp filter blocks
2081             // the bpf syscall. http://aosp/1907693
2082             if (mDeps.isAtLeastT()) {
2083                 mDscpPolicyTracker = new DscpPolicyTracker();
2084             }
2085         } catch (ErrnoException e) {
2086             loge("Unable to create DscpPolicyTracker");
2087         }
2088 
2089         mIngressRateLimit = ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond(
2090                 mContext);
2091 
2092         if (mDeps.isAtLeastT()) {
2093             mCdmps = new CompanionDeviceManagerProxyService(context);
2094         } else {
2095             mCdmps = null;
2096         }
2097 
2098         mRoutingCoordinatorService =
2099                 new RoutingCoordinatorService(netd, this::getAllNetworks, mContext);
2100         mMulticastRoutingCoordinatorService =
2101                 mDeps.makeMulticastRoutingCoordinatorService(mHandler);
2102 
2103         mDestroyFrozenSockets = mDeps.isAtLeastV() || (mDeps.isAtLeastU()
2104                 && mDeps.isFeatureEnabled(context, KEY_DESTROY_FROZEN_SOCKETS_VERSION));
2105         mDelayDestroySockets = mDeps.isFeatureNotChickenedOut(context, DELAY_DESTROY_SOCKETS);
2106         mAllowSysUiConnectivityReports = mDeps.isFeatureNotChickenedOut(
2107                 mContext, ALLOW_SYSUI_CONNECTIVITY_REPORTS);
2108         if (mDestroyFrozenSockets || mQueueCallbacksForFrozenApps) {
2109             final UidFrozenStateChangedCallback frozenStateChangedCallback =
2110                     new UidFrozenStateChangedCallback() {
2111                 @Override
2112                 public void onUidFrozenStateChanged(int[] uids, int[] frozenStates) {
2113                     if (uids.length != frozenStates.length) {
2114                         Log.wtf(TAG, "uids has length " + uids.length
2115                                 + " but frozenStates has length " + frozenStates.length);
2116                         return;
2117                     }
2118 
2119                     final UidFrozenStateChangedArgs args =
2120                             new UidFrozenStateChangedArgs(uids, frozenStates);
2121 
2122                     mHandler.sendMessage(
2123                             mHandler.obtainMessage(EVENT_UID_FROZEN_STATE_CHANGED, args));
2124                 }
2125             };
2126 
2127             final ActivityManager activityManager =
2128                     mContext.getSystemService(ActivityManager.class);
2129             activityManager.registerUidFrozenStateChangedCallback(
2130                     (Runnable r) -> r.run(), frozenStateChangedCallback);
2131         }
2132         mIngressToVpnAddressFiltering = mDeps.isAtLeastT()
2133                 && mDeps.isFeatureNotChickenedOut(mContext, INGRESS_TO_VPN_ADDRESS_FILTERING);
2134 
2135         mL2capNetworkProvider = mDeps.makeL2capNetworkProvider(mContext);
2136     }
2137 
2138     /**
2139      * Check whether or not the device supports Ethernet transport.
2140      */
2141     public static boolean deviceSupportsEthernet(final Context context) {
2142         final PackageManager pm = context.getPackageManager();
2143         return pm.hasSystemFeature(PackageManager.FEATURE_ETHERNET)
2144                 || pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST);
2145     }
2146 
2147     private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
2148         return createDefaultNetworkCapabilitiesForUidRangeSet(Collections.singleton(
2149                 new UidRange(uid, uid)));
2150     }
2151 
2152     private static NetworkCapabilities createDefaultNetworkCapabilitiesForUidRangeSet(
2153             @NonNull final Set<UidRange> uidRangeSet) {
2154         final NetworkCapabilities netCap = new NetworkCapabilities();
2155         netCap.addCapability(NET_CAPABILITY_INTERNET);
2156         netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
2157         netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
2158         netCap.setUids(UidRange.toIntRanges(uidRangeSet));
2159         return netCap;
2160     }
2161 
2162     private NetworkRequest createDefaultRequest() {
2163         return createDefaultInternetRequestForTransport(
2164                 TYPE_NONE, NetworkRequest.Type.REQUEST);
2165     }
2166 
2167     private NetworkRequest createVpnRequest() {
2168         final NetworkCapabilities netCap = new NetworkCapabilities.Builder()
2169                 .withoutDefaultCapabilities()
2170                 .addTransportType(TRANSPORT_VPN)
2171                 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
2172                 .addCapability(NET_CAPABILITY_NOT_RESTRICTED)
2173                 .build();
2174         netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
2175         return createNetworkRequest(NetworkRequest.Type.REQUEST, netCap);
2176     }
2177 
2178     private NetworkRequest createDefaultInternetRequestForTransport(
2179             int transportType, NetworkRequest.Type type) {
2180         final NetworkCapabilities netCap = new NetworkCapabilities();
2181         netCap.addCapability(NET_CAPABILITY_INTERNET);
2182         netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
2183         netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
2184         if (transportType > TYPE_NONE) {
2185             netCap.addTransportType(transportType);
2186         }
2187         return createNetworkRequest(type, netCap);
2188     }
2189 
2190     private NetworkRequest createNetworkRequest(
2191             NetworkRequest.Type type, NetworkCapabilities netCap) {
2192         return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type);
2193     }
2194 
2195     private NetworkRequest createAlwaysOnRequestForCapability(int capability,
2196             NetworkRequest.Type type) {
2197         final NetworkCapabilities netCap = new NetworkCapabilities();
2198         netCap.clearAll();
2199         netCap.addCapability(capability);
2200         netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
2201         return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type);
2202     }
2203 
2204     // Used only for testing.
2205     // TODO: Delete this and either:
2206     // 1. Give FakeSettingsProvider the ability to send settings change notifications (requires
2207     //    changing ContentResolver to make registerContentObserver non-final).
2208     // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it
2209     //    by subclassing SettingsObserver.
2210     @VisibleForTesting
2211     void updateAlwaysOnNetworks() {
2212         mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
2213     }
2214 
2215     // See FakeSettingsProvider comment above.
2216     @VisibleForTesting
2217     void updatePrivateDnsSettings() {
2218         mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
2219     }
2220 
2221     @VisibleForTesting
2222     public void updateMobileDataPreferredUids() {
2223         mHandler.sendEmptyMessage(EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED);
2224     }
2225 
2226     @VisibleForTesting
2227     void updateIngressRateLimit() {
2228         mHandler.sendEmptyMessage(EVENT_INGRESS_RATE_LIMIT_CHANGED);
2229     }
2230 
2231     @VisibleForTesting
2232     void simulateUpdateProxyInfo(@Nullable final Network network,
2233             @NonNull final ProxyInfo proxyInfo) {
2234         Message.obtain(mHandler, EVENT_PAC_PROXY_HAS_CHANGED,
2235                 new Pair<>(network, proxyInfo)).sendToTarget();
2236     }
2237 
2238     /**
2239      * Called when satellite network fallback uids at {@link SatelliteAccessController}
2240      * cache was updated based on {@link
2241      * android.app.role.OnRoleHoldersChangedListener#onRoleHoldersChanged(String, UserHandle)},
2242      * to create multilayer request with preference order
2243      * {@link #PREFERENCE_ORDER_SATELLITE_FALLBACK} there on.
2244      *
2245      */
2246     private void updateSatelliteNetworkPreferenceUids(Set<Integer> satelliteNetworkFallbackUids) {
2247         handleSetSatelliteNetworkPreference(satelliteNetworkFallbackUids);
2248     }
2249 
2250     private void handleAlwaysOnNetworkRequest(
2251             NetworkRequest networkRequest, String settingName, boolean defaultValue) {
2252         final boolean enable = toBool(Settings.Global.getInt(
2253                 mContext.getContentResolver(), settingName, encodeBool(defaultValue)));
2254         handleAlwaysOnNetworkRequest(networkRequest, enable);
2255     }
2256 
2257     private void handleAlwaysOnNetworkRequest(NetworkRequest networkRequest, boolean enable) {
2258         final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null);
2259         if (enable == isEnabled) {
2260             return;  // Nothing to do.
2261         }
2262 
2263         if (enable) {
2264             handleRegisterNetworkRequest(new NetworkRequestInfo(
2265                     Process.myUid(), networkRequest, null /* messenger */, null /* binder */,
2266                     NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
2267                     null /* attributionTags */, DECLARED_METHODS_NONE));
2268         } else {
2269             handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID,
2270                     /* callOnUnavailable */ false);
2271         }
2272     }
2273 
2274     private void handleConfigureAlwaysOnNetworks() {
2275         handleAlwaysOnNetworkRequest(mDefaultMobileDataRequest,
2276                 ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON, true /* defaultValue */);
2277         handleAlwaysOnNetworkRequest(mDefaultWifiRequest,
2278                 ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED, false /* defaultValue */);
2279         final boolean vehicleAlwaysRequested = mResources.get().getBoolean(
2280                 R.bool.config_vehicleInternalNetworkAlwaysRequested);
2281         handleAlwaysOnNetworkRequest(mDefaultVehicleRequest, vehicleAlwaysRequested);
2282     }
2283 
2284     // Note that registering observer for setting do not get initial callback when registering,
2285     // callers must fetch the initial value of the setting themselves if needed.
2286     private void registerSettingsCallbacks() {
2287         // Watch for global HTTP proxy changes.
2288         mSettingsObserver.observe(
2289                 Settings.Global.getUriFor(Settings.Global.HTTP_PROXY),
2290                 EVENT_APPLY_GLOBAL_HTTP_PROXY);
2291 
2292         // Watch for whether to keep mobile data always on.
2293         mSettingsObserver.observe(
2294                 Settings.Global.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON),
2295                 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
2296 
2297         // Watch for whether to keep wifi always on.
2298         mSettingsObserver.observe(
2299                 Settings.Global.getUriFor(ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED),
2300                 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
2301 
2302         // Watch for mobile data preferred uids changes.
2303         mSettingsObserver.observe(
2304                 Settings.Secure.getUriFor(ConnectivitySettingsManager.MOBILE_DATA_PREFERRED_UIDS),
2305                 EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED);
2306 
2307         // Watch for ingress rate limit changes.
2308         mSettingsObserver.observe(
2309                 Settings.Global.getUriFor(
2310                         ConnectivitySettingsManager.INGRESS_RATE_LIMIT_BYTES_PER_SECOND),
2311                 EVENT_INGRESS_RATE_LIMIT_CHANGED);
2312     }
2313 
2314     private void registerPrivateDnsSettingsCallbacks() {
2315         for (Uri uri : DnsManager.getPrivateDnsSettingsUris()) {
2316             mSettingsObserver.observe(uri, EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
2317         }
2318     }
2319 
2320     private synchronized int nextNetworkRequestId() {
2321         // TODO: Consider handle wrapping and exclude {@link NetworkRequest#REQUEST_ID_NONE} if
2322         //  doing that.
2323         return mNextNetworkRequestId++;
2324     }
2325 
2326     @VisibleForTesting
2327     @Nullable
2328     protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
2329         if (network == null) {
2330             return null;
2331         }
2332         return getNetworkAgentInfoForNetId(network.getNetId());
2333     }
2334 
2335     private NetworkAgentInfo getNetworkAgentInfoForNetId(int netId) {
2336         synchronized (mNetworkForNetId) {
2337             return mNetworkForNetId.get(netId);
2338         }
2339     }
2340 
2341     // TODO: determine what to do when more than one VPN applies to |uid|.
2342     @Nullable
2343     private NetworkAgentInfo getVpnForUid(int uid) {
2344         synchronized (mNetworkForNetId) {
2345             for (int i = 0; i < mNetworkForNetId.size(); i++) {
2346                 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
2347                 if (nai.isVPN() && nai.everConnected()
2348                         && nai.networkCapabilities.appliesToUid(uid)) {
2349                     return nai;
2350                 }
2351             }
2352         }
2353         return null;
2354     }
2355 
2356     @Nullable
2357     private Network[] getVpnUnderlyingNetworks(int uid) {
2358         if (mLockdownEnabled) return null;
2359         final NetworkAgentInfo nai = getVpnForUid(uid);
2360         if (nai != null) return nai.declaredUnderlyingNetworks;
2361         return null;
2362     }
2363 
2364     private NetworkAgentInfo getNetworkAgentInfoForUid(int uid) {
2365         NetworkAgentInfo nai = getDefaultNetworkForUid(uid);
2366 
2367         final Network[] networks = getVpnUnderlyingNetworks(uid);
2368         if (networks != null) {
2369             // getUnderlyingNetworks() returns:
2370             // null => there was no VPN, or the VPN didn't specify anything, so we use the default.
2371             // empty array => the VPN explicitly said "no default network".
2372             // non-empty array => the VPN specified one or more default networks; we use the
2373             //                    first one.
2374             if (networks.length > 0) {
2375                 nai = getNetworkAgentInfoForNetwork(networks[0]);
2376             } else {
2377                 nai = null;
2378             }
2379         }
2380         return nai;
2381     }
2382 
2383     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
2384     private boolean hasInternetPermission(final int uid) {
2385         return (mBpfNetMaps.getNetPermForUid(uid) & PERMISSION_INTERNET) != 0;
2386     }
2387 
2388     /**
2389      * Check if UID should be blocked from using the specified network.
2390      */
2391     private boolean isNetworkWithCapabilitiesBlocked(@Nullable final NetworkCapabilities nc,
2392             final int uid, final boolean ignoreBlocked) {
2393         // Networks aren't blocked when ignoring blocked status
2394         if (ignoreBlocked) {
2395             return false;
2396         }
2397         if (isUidBlockedByVpn(uid, mVpnBlockedUidRanges)) return true;
2398         final long ident = Binder.clearCallingIdentity();
2399         try {
2400             final boolean metered = nc == null ? true : nc.isMetered();
2401             if (mDeps.isAtLeastV()) {
2402                 final boolean hasInternetPermission = hasInternetPermission(uid);
2403                 final boolean blockedByUidRules = mBpfNetMaps.isUidNetworkingBlocked(uid, metered);
2404                 if (mDeps.isChangeEnabled(NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION, uid)) {
2405                     return blockedByUidRules || !hasInternetPermission;
2406                 } else {
2407                     return hasInternetPermission && blockedByUidRules;
2408                 }
2409             } else {
2410                 return mPolicyManager.isUidNetworkingBlocked(uid, metered);
2411             }
2412         } finally {
2413             Binder.restoreCallingIdentity(ident);
2414         }
2415     }
2416 
2417     private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) {
2418         if (ni == null || !LOGD_BLOCKED_NETWORKINFO) {
2419             return;
2420         }
2421         final boolean blocked;
2422         synchronized (mBlockedAppUids) {
2423             if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) {
2424                 blocked = true;
2425             } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) {
2426                 blocked = false;
2427             } else {
2428                 return;
2429             }
2430         }
2431         String action = blocked ? "BLOCKED" : "UNBLOCKED";
2432         log(String.format("Returning %s NetworkInfo to uid=%d", action, uid));
2433         mNetworkInfoBlockingLogs.log(action + " " + uid);
2434     }
2435 
2436     private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, int blocked) {
2437         if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) {
2438             return;
2439         }
2440         final String action = (blocked != 0) ? "BLOCKED" : "UNBLOCKED";
2441         final int requestId = nri.getActiveRequest() != null
2442                 ? nri.getActiveRequest().requestId : nri.mRequests.get(0).requestId;
2443         mNetworkInfoBlockingLogs.log(String.format(
2444                 "%s %d(%d) on netId %d: %s", action, nri.mAsUid, requestId, net.getNetId(),
2445                 Integer.toHexString(blocked)));
2446     }
2447 
2448     /**
2449      * Apply any relevant filters to the specified {@link NetworkInfo} for the given UID. For
2450      * example, this may mark the network as {@link DetailedState#BLOCKED} based
2451      * on {@link #isNetworkWithCapabilitiesBlocked}.
2452      */
2453     @NonNull
2454     private NetworkInfo filterNetworkInfo(@NonNull NetworkInfo networkInfo, int type,
2455             @NonNull NetworkCapabilities nc, int uid, boolean ignoreBlocked) {
2456         final NetworkInfo filtered = new NetworkInfo(networkInfo);
2457         // Many legacy types (e.g,. TYPE_MOBILE_HIPRI) are not actually a property of the network
2458         // but only exists if an app asks about them or requests them. Ensure the requesting app
2459         // gets the type it asks for.
2460         filtered.setType(type);
2461         if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) {
2462             filtered.setDetailedState(DetailedState.BLOCKED, null /* reason */,
2463                     null /* extraInfo */);
2464         }
2465         filterForLegacyLockdown(filtered);
2466         return filtered;
2467     }
2468 
2469     private NetworkInfo getFilteredNetworkInfo(NetworkAgentInfo nai, int uid,
2470             boolean ignoreBlocked) {
2471         return filterNetworkInfo(nai.networkInfo, nai.networkInfo.getType(),
2472                 nai.networkCapabilities, uid, ignoreBlocked);
2473     }
2474 
2475     /**
2476      * Return NetworkInfo for the active (i.e., connected) network interface.
2477      * It is assumed that at most one network is active at a time. If more
2478      * than one is active, it is indeterminate which will be returned.
2479      * @return the info for the active network, or {@code null} if none is
2480      * active
2481      */
2482     @Override
2483     @Nullable
2484     public NetworkInfo getActiveNetworkInfo() {
2485         enforceAccessPermission();
2486         final int uid = mDeps.getCallingUid();
2487         final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
2488         if (nai == null) return null;
2489         final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false /* ignoreBlocked */);
2490         maybeLogBlockedNetworkInfo(networkInfo, uid);
2491         return networkInfo;
2492     }
2493 
2494     @Override
2495     @Nullable
2496     public Network getActiveNetwork() {
2497         enforceAccessPermission();
2498         return getActiveNetworkForUidInternal(mDeps.getCallingUid(), false);
2499     }
2500 
2501     @Override
2502     @Nullable
2503     public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
2504         enforceNetworkStackPermission(mContext);
2505         return getActiveNetworkForUidInternal(uid, ignoreBlocked);
2506     }
2507 
2508     @Nullable
2509     private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) {
2510         final NetworkAgentInfo vpnNai = getVpnForUid(uid);
2511         if (vpnNai != null) {
2512             final NetworkCapabilities requiredCaps = createDefaultNetworkCapabilitiesForUid(uid);
2513             if (requiredCaps.satisfiedByNetworkCapabilities(vpnNai.networkCapabilities)) {
2514                 return vpnNai.network;
2515             }
2516         }
2517 
2518         NetworkAgentInfo nai = getDefaultNetworkForUid(uid);
2519         if (nai == null || isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid,
2520                 ignoreBlocked)) {
2521             return null;
2522         }
2523         return nai.network;
2524     }
2525 
2526     @Override
2527     @Nullable
2528     public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
2529         enforceNetworkStackPermission(mContext);
2530         final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
2531         if (nai == null) return null;
2532         return getFilteredNetworkInfo(nai, uid, ignoreBlocked);
2533     }
2534 
2535     /** Returns a NetworkInfo object for a network that doesn't exist. */
2536     private NetworkInfo makeFakeNetworkInfo(int networkType, int uid) {
2537         final NetworkInfo info = new NetworkInfo(networkType, 0 /* subtype */,
2538                 getNetworkTypeName(networkType), "" /* subtypeName */);
2539         info.setIsAvailable(true);
2540         // For compatibility with legacy code, return BLOCKED instead of DISCONNECTED when
2541         // background data is restricted.
2542         final NetworkCapabilities nc = new NetworkCapabilities();  // Metered.
2543         final DetailedState state = isNetworkWithCapabilitiesBlocked(nc, uid, false)
2544                 ? DetailedState.BLOCKED
2545                 : DetailedState.DISCONNECTED;
2546         info.setDetailedState(state, null /* reason */, null /* extraInfo */);
2547         filterForLegacyLockdown(info);
2548         return info;
2549     }
2550 
2551     private NetworkInfo getFilteredNetworkInfoForType(int networkType, int uid) {
2552         if (!mLegacyTypeTracker.isTypeSupported(networkType)) {
2553             return null;
2554         }
2555         final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
2556         if (nai == null) {
2557             return makeFakeNetworkInfo(networkType, uid);
2558         }
2559         return filterNetworkInfo(nai.networkInfo, networkType, nai.networkCapabilities, uid,
2560                 false);
2561     }
2562 
2563     @Override
2564     @Nullable
2565     public NetworkInfo getNetworkInfo(int networkType) {
2566         enforceAccessPermission();
2567         final int uid = mDeps.getCallingUid();
2568         if (getVpnUnderlyingNetworks(uid) != null) {
2569             // A VPN is active, so we may need to return one of its underlying networks. This
2570             // information is not available in LegacyTypeTracker, so we have to get it from
2571             // getNetworkAgentInfoForUid.
2572             final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
2573             if (nai == null) return null;
2574             final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false);
2575             if (networkInfo.getType() == networkType) {
2576                 return networkInfo;
2577             }
2578         }
2579         return getFilteredNetworkInfoForType(networkType, uid);
2580     }
2581 
2582     @Override
2583     @Nullable
2584     public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
2585         enforceAccessPermission();
2586         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
2587         if (nai == null) return null;
2588         return getFilteredNetworkInfo(nai, uid, ignoreBlocked);
2589     }
2590 
2591     @Override
2592     public NetworkInfo[] getAllNetworkInfo() {
2593         enforceAccessPermission();
2594         final ArrayList<NetworkInfo> result = new ArrayList<>();
2595         for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE;
2596                 networkType++) {
2597             NetworkInfo info = getNetworkInfo(networkType);
2598             if (info != null) {
2599                 result.add(info);
2600             }
2601         }
2602         return result.toArray(new NetworkInfo[result.size()]);
2603     }
2604 
2605     @Override
2606     @Nullable
2607     public Network getNetworkForType(int networkType) {
2608         enforceAccessPermission();
2609         if (!mLegacyTypeTracker.isTypeSupported(networkType)) {
2610             return null;
2611         }
2612         final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
2613         if (nai == null) {
2614             return null;
2615         }
2616         final int uid = mDeps.getCallingUid();
2617         if (isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, false)) {
2618             return null;
2619         }
2620         return nai.network;
2621     }
2622 
2623     @Override
2624     @NonNull
2625     public Network[] getAllNetworks() {
2626         enforceAccessPermission();
2627         synchronized (mNetworkForNetId) {
2628             final Network[] result = new Network[mNetworkForNetId.size()];
2629             for (int i = 0; i < mNetworkForNetId.size(); i++) {
2630                 result[i] = mNetworkForNetId.valueAt(i).network;
2631             }
2632             return result;
2633         }
2634     }
2635 
2636     @Override
2637     public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(
2638                 int userId, String callingPackageName, @Nullable String callingAttributionTag) {
2639         // The basic principle is: if an app's traffic could possibly go over a
2640         // network, without the app doing anything multinetwork-specific,
2641         // (hence, by "default"), then include that network's capabilities in
2642         // the array.
2643         //
2644         // In the normal case, app traffic only goes over the system's default
2645         // network connection, so that's the only network returned.
2646         //
2647         // With a VPN in force, some app traffic may go into the VPN, and thus
2648         // over whatever underlying networks the VPN specifies, while other app
2649         // traffic may go over the system default network (e.g.: a split-tunnel
2650         // VPN, or an app disallowed by the VPN), so the set of networks
2651         // returned includes the VPN's underlying networks and the system
2652         // default.
2653         enforceAccessPermission();
2654 
2655         HashMap<Network, NetworkCapabilities> result = new HashMap<>();
2656 
2657         for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
2658             if (!nri.isBeingSatisfied()) {
2659                 continue;
2660             }
2661             final NetworkAgentInfo nai = nri.getSatisfier();
2662             final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
2663             if (null != nc
2664                     && nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
2665                     && !result.containsKey(nai.network)) {
2666                 result.put(
2667                         nai.network,
2668                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
2669                                 nc, false /* includeLocationSensitiveInfo */,
2670                                 getCallingPid(), mDeps.getCallingUid(), callingPackageName,
2671                                 callingAttributionTag));
2672             }
2673         }
2674 
2675         // No need to check mLockdownEnabled. If it's true, getVpnUnderlyingNetworks returns null.
2676         final Network[] networks = getVpnUnderlyingNetworks(mDeps.getCallingUid());
2677         if (null != networks) {
2678             for (final Network network : networks) {
2679                 final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
2680                 if (null != nc) {
2681                     result.put(
2682                             network,
2683                             createWithLocationInfoSanitizedIfNecessaryWhenParceled(
2684                                     nc,
2685                                     false /* includeLocationSensitiveInfo */,
2686                                     getCallingPid(), mDeps.getCallingUid(), callingPackageName,
2687                                     callingAttributionTag));
2688                 }
2689             }
2690         }
2691 
2692         NetworkCapabilities[] out = new NetworkCapabilities[result.size()];
2693         out = result.values().toArray(out);
2694         return out;
2695     }
2696 
2697     // Because StatsEvent is not usable in tests (everything inside it is hidden), this
2698     // method is used to convert a ConnectivityStateSample into a StatsEvent, so that tests
2699     // can call sampleConnectivityState and make the checks on it.
2700     @NonNull
2701     private StatsEvent sampleConnectivityStateToStatsEvent() {
2702         final ConnectivityStateSample sample = sampleConnectivityState();
2703         return ConnectivityStatsLog.buildStatsEvent(
2704                 ConnectivityStatsLog.CONNECTIVITY_STATE_SAMPLE,
2705                 sample.getNetworkCountPerTransports().toByteArray(),
2706                 sample.getConnectionDurationPerTransports().toByteArray(),
2707                 sample.getNetworkRequestCount().toByteArray(),
2708                 sample.getNetworks().toByteArray());
2709     }
2710 
2711     /**
2712      * Gather and return a snapshot of the current connectivity state, to be used as a sample.
2713      *
2714      * This is used for metrics. These snapshots will be sampled and constitute a base for
2715      * statistics about connectivity state of devices.
2716      */
2717     @VisibleForTesting
2718     @NonNull
2719     public ConnectivityStateSample sampleConnectivityState() {
2720         ensureRunningOnConnectivityServiceThread();
2721         final ConnectivityStateSample.Builder builder = ConnectivityStateSample.newBuilder();
2722         builder.setNetworkCountPerTransports(sampleNetworkCount(mNetworkAgentInfos));
2723         builder.setConnectionDurationPerTransports(sampleConnectionDuration(mNetworkAgentInfos));
2724         builder.setNetworkRequestCount(sampleNetworkRequestCount(mNetworkRequests.values()));
2725         builder.setNetworks(sampleNetworks(mNetworkAgentInfos));
2726         return builder.build();
2727     }
2728 
2729     private static NetworkCountPerTransports sampleNetworkCount(
2730             @NonNull final ArraySet<NetworkAgentInfo> nais) {
2731         final SparseIntArray countPerTransports = new SparseIntArray();
2732         for (final NetworkAgentInfo nai : nais) {
2733             int transports = (int) nai.networkCapabilities.getTransportTypesInternal();
2734             countPerTransports.put(transports, 1 + countPerTransports.get(transports, 0));
2735         }
2736         final NetworkCountPerTransports.Builder builder = NetworkCountPerTransports.newBuilder();
2737         for (int i = countPerTransports.size() - 1; i >= 0; --i) {
2738             final NetworkCountForTransports.Builder c = NetworkCountForTransports.newBuilder();
2739             c.setTransportTypes(countPerTransports.keyAt(i));
2740             c.setNetworkCount(countPerTransports.valueAt(i));
2741             builder.addNetworkCountForTransports(c);
2742         }
2743         return builder.build();
2744     }
2745 
2746     private static ConnectionDurationPerTransports sampleConnectionDuration(
2747             @NonNull final ArraySet<NetworkAgentInfo> nais) {
2748         final ConnectionDurationPerTransports.Builder builder =
2749                 ConnectionDurationPerTransports.newBuilder();
2750         for (final NetworkAgentInfo nai : nais) {
2751             final ConnectionDurationForTransports.Builder c =
2752                     ConnectionDurationForTransports.newBuilder();
2753             c.setTransportTypes((int) nai.networkCapabilities.getTransportTypesInternal());
2754             final long durationMillis = SystemClock.elapsedRealtime() - nai.getConnectedTime();
2755             final long millisPerSecond = TimeUnit.SECONDS.toMillis(1);
2756             // Add millisPerSecond/2 to round up or down to the nearest value
2757             c.setDurationSec((int) ((durationMillis + millisPerSecond / 2) / millisPerSecond));
2758             builder.addConnectionDurationForTransports(c);
2759         }
2760         return builder.build();
2761     }
2762 
2763     private static NetworkRequestCount sampleNetworkRequestCount(
2764             @NonNull final Collection<NetworkRequestInfo> nris) {
2765         final NetworkRequestCount.Builder builder = NetworkRequestCount.newBuilder();
2766         final SparseIntArray countPerType = new SparseIntArray();
2767         for (final NetworkRequestInfo nri : nris) {
2768             final int type;
2769             if (Process.SYSTEM_UID == nri.mAsUid) {
2770                 // The request is filed "as" the system, so it's the system on its own behalf.
2771                 type = RequestType.RT_SYSTEM.getNumber();
2772             } else if (Process.SYSTEM_UID == nri.mUid) {
2773                 // The request is filed by the system as some other app, so it's the system on
2774                 // behalf of an app.
2775                 type = RequestType.RT_SYSTEM_ON_BEHALF_OF_APP.getNumber();
2776             } else {
2777                 // Not the system, so it's an app requesting on its own behalf.
2778                 type = RequestType.RT_APP.getNumber();
2779             }
2780             countPerType.put(type, countPerType.get(type, 0) + 1);
2781         }
2782         for (int i = countPerType.size() - 1; i >= 0; --i) {
2783             final RequestCountForType.Builder r = RequestCountForType.newBuilder();
2784             r.setRequestType(RequestType.forNumber(countPerType.keyAt(i)));
2785             r.setRequestCount(countPerType.valueAt(i));
2786             builder.addRequestCountForType(r);
2787         }
2788         return builder.build();
2789     }
2790 
2791     private static NetworkList sampleNetworks(@NonNull final ArraySet<NetworkAgentInfo> nais) {
2792         final NetworkList.Builder builder = NetworkList.newBuilder();
2793         for (final NetworkAgentInfo nai : nais) {
2794             final NetworkCapabilities nc = nai.networkCapabilities;
2795             final NetworkDescription.Builder d = NetworkDescription.newBuilder();
2796             d.setTransportTypes((int) nc.getTransportTypesInternal());
2797             final MeteredState meteredState;
2798             if (nc.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)) {
2799                 meteredState = MeteredState.METERED_TEMPORARILY_UNMETERED;
2800             } else if (nc.hasCapability(NET_CAPABILITY_NOT_METERED)) {
2801                 meteredState = MeteredState.METERED_NO;
2802             } else {
2803                 meteredState = MeteredState.METERED_YES;
2804             }
2805             d.setMeteredState(meteredState);
2806             final ValidatedState validatedState;
2807             if (nc.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) {
2808                 validatedState = ValidatedState.VS_PORTAL;
2809             } else if (nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)) {
2810                 validatedState = ValidatedState.VS_PARTIAL;
2811             } else if (nc.hasCapability(NET_CAPABILITY_VALIDATED)) {
2812                 validatedState = ValidatedState.VS_VALID;
2813             } else {
2814                 validatedState = ValidatedState.VS_INVALID;
2815             }
2816             d.setValidatedState(validatedState);
2817             d.setScorePolicies(nai.getScore().getPoliciesInternal());
2818             d.setCapabilities(nc.getCapabilitiesInternal());
2819             d.setEnterpriseId(nc.getEnterpriseIdsInternal());
2820             builder.addNetworkDescription(d);
2821         }
2822         return builder.build();
2823     }
2824 
2825     @Override
2826     public boolean isNetworkSupported(int networkType) {
2827         enforceAccessPermission();
2828         return mLegacyTypeTracker.isTypeSupported(networkType);
2829     }
2830 
2831     /**
2832      * Return LinkProperties for the active (i.e., connected) default
2833      * network interface for the calling uid.
2834      * @return the ip properties for the active network, or {@code null} if
2835      * none is active
2836      */
2837     @Override
2838     public LinkProperties getActiveLinkProperties() {
2839         enforceAccessPermission();
2840         final int uid = mDeps.getCallingUid();
2841         NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
2842         if (nai == null) return null;
2843         return linkPropertiesRestrictedForCallerPermissions(nai.linkProperties,
2844                 Binder.getCallingPid(), uid);
2845     }
2846 
2847     @Override
2848     public LinkProperties getLinkPropertiesForType(int networkType) {
2849         enforceAccessPermission();
2850         NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
2851         final LinkProperties lp = getLinkProperties(nai);
2852         if (lp == null) return null;
2853         return linkPropertiesRestrictedForCallerPermissions(
2854                 lp, Binder.getCallingPid(), mDeps.getCallingUid());
2855     }
2856 
2857     // TODO - this should be ALL networks
2858     @Override
2859     public LinkProperties getLinkProperties(Network network) {
2860         enforceAccessPermission();
2861         final LinkProperties lp = getLinkProperties(getNetworkAgentInfoForNetwork(network));
2862         if (lp == null) return null;
2863         return linkPropertiesRestrictedForCallerPermissions(
2864                 lp, Binder.getCallingPid(), mDeps.getCallingUid());
2865     }
2866 
2867     @Nullable
2868     private LinkProperties getLinkProperties(@Nullable NetworkAgentInfo nai) {
2869         if (nai == null) {
2870             return null;
2871         }
2872         synchronized (nai) {
2873             return nai.linkProperties;
2874         }
2875     }
2876 
2877     @Override
2878     @Nullable
2879     public LinkProperties getRedactedLinkPropertiesForPackage(@NonNull LinkProperties lp, int uid,
2880             @NonNull String packageName, @Nullable String callingAttributionTag) {
2881         Objects.requireNonNull(packageName);
2882         Objects.requireNonNull(lp);
2883         enforceNetworkStackOrSettingsPermission();
2884         if (!hasAccessPermission(-1 /* pid */, uid)) {
2885             return null;
2886         }
2887         return linkPropertiesRestrictedForCallerPermissions(lp, -1 /* callerPid */, uid);
2888     }
2889 
2890     private NetworkCapabilities getNetworkCapabilitiesInternal(Network network) {
2891         return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
2892     }
2893 
2894     private NetworkCapabilities getNetworkCapabilitiesInternal(NetworkAgentInfo nai) {
2895         if (nai == null) return null;
2896         synchronized (nai) {
2897             return networkCapabilitiesRestrictedForCallerPermissions(
2898                     nai.networkCapabilities, Binder.getCallingPid(), mDeps.getCallingUid());
2899         }
2900     }
2901 
2902     @Override
2903     public NetworkCapabilities getNetworkCapabilities(Network network, String callingPackageName,
2904             @Nullable String callingAttributionTag) {
2905         mAppOpsManager.checkPackage(mDeps.getCallingUid(), callingPackageName);
2906         enforceAccessPermission();
2907         return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
2908                 getNetworkCapabilitiesInternal(network),
2909                 false /* includeLocationSensitiveInfo */,
2910                 getCallingPid(), mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
2911     }
2912 
2913     @Override
2914     public NetworkCapabilities getRedactedNetworkCapabilitiesForPackage(
2915             @NonNull NetworkCapabilities nc, int uid, @NonNull String packageName,
2916             @Nullable String callingAttributionTag) {
2917         Objects.requireNonNull(nc);
2918         Objects.requireNonNull(packageName);
2919         enforceNetworkStackOrSettingsPermission();
2920         if (!hasAccessPermission(-1 /* pid */, uid)) {
2921             return null;
2922         }
2923         return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
2924                 networkCapabilitiesRestrictedForCallerPermissions(nc, -1 /* callerPid */, uid),
2925                 true /* includeLocationSensitiveInfo */, -1 /* callingPid */, uid, packageName,
2926                 callingAttributionTag);
2927     }
2928 
2929     private void redactUnderlyingNetworksForCapabilities(NetworkCapabilities nc, int pid, int uid) {
2930         if (nc.getUnderlyingNetworks() != null
2931                 && !hasNetworkFactoryOrSettingsPermission(pid, uid)) {
2932             nc.setUnderlyingNetworks(null);
2933         }
2934     }
2935 
2936     private boolean canSeeAllowedUids(final int pid, final int uid, final int netOwnerUid) {
2937         return Process.SYSTEM_UID == uid
2938                 || netOwnerUid == uid
2939                 || hasAnyPermissionOf(mContext, pid, uid,
2940                         android.Manifest.permission.NETWORK_FACTORY);
2941     }
2942 
2943     @VisibleForTesting
2944     NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
2945             NetworkCapabilities nc, int callerPid, int callerUid) {
2946         // Note : here it would be nice to check ACCESS_NETWORK_STATE and return null, but
2947         // this would be expensive (one more permission check every time any NC callback is
2948         // sent) and possibly dangerous : apps normally can't lose ACCESS_NETWORK_STATE, if
2949         // it happens for some reason (e.g. the package is uninstalled while CS is trying to
2950         // send the callback) it would crash the system server with NPE.
2951         final NetworkCapabilities newNc = new NetworkCapabilities(nc);
2952         if (!hasSettingsPermission(callerPid, callerUid)) {
2953             newNc.setUids(null);
2954             newNc.setSSID(null);
2955         }
2956         if (newNc.getNetworkSpecifier() != null) {
2957             newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact());
2958         }
2959         if (!hasAnyPermissionOf(mContext, callerPid, callerUid,
2960                 android.Manifest.permission.NETWORK_STACK,
2961                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)) {
2962             newNc.setAdministratorUids(new int[0]);
2963         }
2964         if (!canSeeAllowedUids(callerPid, callerUid, newNc.getOwnerUid())) {
2965             newNc.setAllowedUids(new ArraySet<>());
2966         }
2967         redactUnderlyingNetworksForCapabilities(newNc, callerPid, callerUid);
2968 
2969         return newNc;
2970     }
2971 
2972     /**
2973      * Wrapper used to cache the permission check results performed for the corresponding
2974      * app. This avoids performing multiple permission checks for different fields in
2975      * NetworkCapabilities.
2976      * Note: This wrapper does not support any sort of invalidation and thus must not be
2977      * persistent or long-lived. It may only be used for the time necessary to
2978      * compute the redactions required by one particular NetworkCallback or
2979      * synchronous call.
2980      */
2981     private class RedactionPermissionChecker {
2982         private final int mCallingPid;
2983         private final int mCallingUid;
2984         @NonNull private final String mCallingPackageName;
2985         @Nullable private final String mCallingAttributionTag;
2986 
2987         private Boolean mHasLocationPermission = null;
2988         private Boolean mHasLocalMacAddressPermission = null;
2989         private Boolean mHasSettingsPermission = null;
2990 
2991         RedactionPermissionChecker(int callingPid, int callingUid,
2992                 @NonNull String callingPackageName, @Nullable String callingAttributionTag) {
2993             mCallingPid = callingPid;
2994             mCallingUid = callingUid;
2995             mCallingPackageName = callingPackageName;
2996             mCallingAttributionTag = callingAttributionTag;
2997         }
2998 
2999         private boolean hasLocationPermissionInternal() {
3000             final long token = Binder.clearCallingIdentity();
3001             try {
3002                 return mLocationPermissionChecker.checkLocationPermission(
3003                         mCallingPackageName, mCallingAttributionTag, mCallingUid,
3004                         null /* message */);
3005             } finally {
3006                 Binder.restoreCallingIdentity(token);
3007             }
3008         }
3009 
3010         /**
3011          * Returns whether the app holds location permission or not (might return cached result
3012          * if the permission was already checked before).
3013          */
3014         public boolean hasLocationPermission() {
3015             if (mHasLocationPermission == null) {
3016                 // If there is no cached result, perform the check now.
3017                 mHasLocationPermission = hasLocationPermissionInternal();
3018             }
3019             return mHasLocationPermission;
3020         }
3021 
3022         /**
3023          * Returns whether the app holds local mac address permission or not (might return cached
3024          * result if the permission was already checked before).
3025          */
3026         @CheckResult
3027         public boolean hasLocalMacAddressPermission() {
3028             if (mHasLocalMacAddressPermission == null) {
3029                 // If there is no cached result, perform the check now.
3030                 mHasLocalMacAddressPermission = ConnectivityService.this
3031                         .hasLocalMacAddressPermission(mCallingPid, mCallingUid);
3032             }
3033             return mHasLocalMacAddressPermission;
3034         }
3035 
3036         /**
3037          * Returns whether the app holds settings permission or not (might return cached
3038          * result if the permission was already checked before).
3039          */
3040         @CheckResult
3041         public boolean hasSettingsPermission() {
3042             if (mHasSettingsPermission == null) {
3043                 // If there is no cached result, perform the check now.
3044                 mHasSettingsPermission =
3045                         ConnectivityService.this.hasSettingsPermission(mCallingPid, mCallingUid);
3046             }
3047             return mHasSettingsPermission;
3048         }
3049     }
3050 
3051     private static boolean shouldRedact(@NetworkCapabilities.RedactionType long redactions,
3052             @NetworkCapabilities.NetCapability long redaction) {
3053         return (redactions & redaction) != 0;
3054     }
3055 
3056     /**
3057      * Use the provided |applicableRedactions| to check the receiving app's
3058      * permissions and clear/set the corresponding bit in the returned bitmask. The bitmask
3059      * returned will be used to ensure the necessary redactions are performed by NetworkCapabilities
3060      * before being sent to the corresponding app.
3061      */
3062     private @NetworkCapabilities.RedactionType long retrieveRequiredRedactions(
3063             @NetworkCapabilities.RedactionType long applicableRedactions,
3064             @NonNull RedactionPermissionChecker redactionPermissionChecker,
3065             boolean includeLocationSensitiveInfo) {
3066         long redactions = applicableRedactions;
3067         if (shouldRedact(redactions, REDACT_FOR_ACCESS_FINE_LOCATION)) {
3068             if (includeLocationSensitiveInfo
3069                     && redactionPermissionChecker.hasLocationPermission()) {
3070                 redactions &= ~REDACT_FOR_ACCESS_FINE_LOCATION;
3071             }
3072         }
3073         if (shouldRedact(redactions, REDACT_FOR_LOCAL_MAC_ADDRESS)) {
3074             if (redactionPermissionChecker.hasLocalMacAddressPermission()) {
3075                 redactions &= ~REDACT_FOR_LOCAL_MAC_ADDRESS;
3076             }
3077         }
3078         if (shouldRedact(redactions, REDACT_FOR_NETWORK_SETTINGS)) {
3079             if (redactionPermissionChecker.hasSettingsPermission()) {
3080                 redactions &= ~REDACT_FOR_NETWORK_SETTINGS;
3081             }
3082         }
3083         return redactions;
3084     }
3085 
3086     @VisibleForTesting
3087     @Nullable
3088     NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled(
3089             @Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo,
3090             int callingPid, int callingUid, @NonNull String callingPkgName,
3091             @Nullable String callingAttributionTag) {
3092         if (nc == null) {
3093             return null;
3094         }
3095         // Avoid doing location permission check if the transport info has no location sensitive
3096         // data.
3097         final RedactionPermissionChecker redactionPermissionChecker =
3098                 new RedactionPermissionChecker(callingPid, callingUid, callingPkgName,
3099                         callingAttributionTag);
3100         final long redactions = retrieveRequiredRedactions(
3101                 nc.getApplicableRedactions(), redactionPermissionChecker,
3102                 includeLocationSensitiveInfo);
3103         final NetworkCapabilities newNc = new NetworkCapabilities(nc, redactions);
3104         // Reset owner uid if not destined for the owner app.
3105         // TODO : calling UID is redacted because apps should generally not know what UID is
3106         // bringing up the VPN, but this should not apply to some very privileged apps like settings
3107         if (callingUid != nc.getOwnerUid()) {
3108             newNc.setOwnerUid(INVALID_UID);
3109             return newNc;
3110         }
3111         // Allow VPNs to see ownership of their own VPN networks - not location sensitive.
3112         if (nc.hasTransport(TRANSPORT_VPN)) {
3113             // Owner UIDs already checked above. No need to re-check.
3114             return newNc;
3115         }
3116         // If the calling does not want location sensitive data & target SDK >= S, then mask info.
3117         // Else include the owner UID iff the calling has location permission to provide backwards
3118         // compatibility for older apps.
3119         if (!includeLocationSensitiveInfo
3120                 && isTargetSdkAtleast(
3121                         Build.VERSION_CODES.S, callingUid, callingPkgName)) {
3122             newNc.setOwnerUid(INVALID_UID);
3123             return newNc;
3124         }
3125         // Reset owner uid if the app has no location permission.
3126         if (!redactionPermissionChecker.hasLocationPermission()) {
3127             newNc.setOwnerUid(INVALID_UID);
3128         }
3129         return newNc;
3130     }
3131 
3132     @NonNull
3133     private LinkProperties linkPropertiesRestrictedForCallerPermissions(
3134             LinkProperties lp, int callerPid, int callerUid) {
3135         if (lp == null) return new LinkProperties();
3136         // Note : here it would be nice to check ACCESS_NETWORK_STATE and return null, but
3137         // this would be expensive (one more permission check every time any LP callback is
3138         // sent) and possibly dangerous : apps normally can't lose ACCESS_NETWORK_STATE, if
3139         // it happens for some reason (e.g. the package is uninstalled while CS is trying to
3140         // send the callback) it would crash the system server with NPE.
3141 
3142         // Only do a permission check if sanitization is needed, to avoid unnecessary binder calls.
3143         final boolean needsSanitization =
3144                 (lp.getCaptivePortalApiUrl() != null || lp.getCaptivePortalData() != null);
3145         if (!needsSanitization) {
3146             return new LinkProperties(lp);
3147         }
3148 
3149         if (hasSettingsPermission(callerPid, callerUid)) {
3150             return new LinkProperties(lp, true /* parcelSensitiveFields */);
3151         }
3152 
3153         final LinkProperties newLp = new LinkProperties(lp);
3154         // Sensitive fields would not be parceled anyway, but sanitize for consistency before the
3155         // object gets parceled.
3156         newLp.setCaptivePortalApiUrl(null);
3157         newLp.setCaptivePortalData(null);
3158         return newLp;
3159     }
3160 
3161     private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc,
3162             int callerUid, String callerPackageName) {
3163         // There is no need to track the effective UID of the request here. If the caller
3164         // lacks the settings permission, the effective UID is the same as the calling ID.
3165         if (!hasSettingsPermission()) {
3166             // Unprivileged apps can only pass in null or their own UID.
3167             if (nc.getUids() == null) {
3168                 // If the caller passes in null, the callback will also match networks that do not
3169                 // apply to its UID, similarly to what it would see if it called getAllNetworks.
3170                 // In this case, redact everything in the request immediately. This ensures that the
3171                 // app is not able to get any redacted information by filing an unredacted request
3172                 // and observing whether the request matches something.
3173                 if (nc.getNetworkSpecifier() != null) {
3174                     nc.setNetworkSpecifier(nc.getNetworkSpecifier().redact());
3175                 }
3176             } else {
3177                 nc.setSingleUid(callerUid);
3178             }
3179         }
3180         nc.setRequestorUidAndPackageName(callerUid, callerPackageName);
3181         nc.setAdministratorUids(new int[0]);
3182 
3183         // Clear owner UID; this can never come from an app.
3184         nc.setOwnerUid(INVALID_UID);
3185     }
3186 
3187     private void restrictBackgroundRequestForCaller(NetworkCapabilities nc) {
3188         if (!mPermissionMonitor.hasUseBackgroundNetworksPermission(mDeps.getCallingUid())) {
3189             nc.addCapability(NET_CAPABILITY_FOREGROUND);
3190         }
3191     }
3192 
3193     private void maybeDisableLocalNetworkMatching(NetworkCapabilities nc, int callingUid) {
3194         // If disabled, NetworkRequest cannot match non-thread local networks even if
3195         // specified explicitly. Compat change is enabled by default on apps targeting B+.
3196         // Agent should not be visible on U- even if it's rolled out.
3197         nc.setMatchNonThreadLocalNetworks(mDeps.isAtLeastV() && mDeps.isChangeEnabled(
3198                 ENABLE_MATCH_NON_THREAD_LOCAL_NETWORKS, callingUid));
3199         if (mDeps.isChangeEnabled(ENABLE_MATCH_LOCAL_NETWORK, callingUid)) {
3200             return;
3201         }
3202         // If NET_CAPABILITY_LOCAL_NETWORK is not added to capability, request should not be
3203         // satisfied by local networks.
3204         if (!nc.hasCapability(NET_CAPABILITY_LOCAL_NETWORK)) {
3205             nc.addForbiddenCapability(NET_CAPABILITY_LOCAL_NETWORK);
3206         }
3207     }
3208 
3209     private void restrictRequestNetworkCapabilitiesForCaller(NetworkCapabilities nc,
3210             int callingUid, String callerPackageName) {
3211         restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callerPackageName);
3212         maybeDisableLocalNetworkMatching(nc, callingUid);
3213     }
3214 
3215     @Override
3216     public @RestrictBackgroundStatus int getRestrictBackgroundStatusByCaller() {
3217         enforceAccessPermission();
3218         final int callerUid = Binder.getCallingUid();
3219         final long token = Binder.clearCallingIdentity();
3220         try {
3221             return mPolicyManager.getRestrictBackgroundStatus(callerUid);
3222         } finally {
3223             Binder.restoreCallingIdentity(token);
3224         }
3225     }
3226 
3227     // TODO: Consider delete this function or turn it into a no-op method.
3228     @Override
3229     public NetworkState[] getAllNetworkState() {
3230         // This contains IMSI details, so make sure the caller is privileged.
3231         enforceNetworkStackPermission(mContext);
3232 
3233         final ArrayList<NetworkState> result = new ArrayList<>();
3234         for (NetworkStateSnapshot snapshot : getAllNetworkStateSnapshots()) {
3235             // NetworkStateSnapshot doesn't contain NetworkInfo, so need to fetch it from the
3236             // NetworkAgentInfo.
3237             final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(snapshot.getNetwork());
3238             if (nai != null && nai.networkInfo.isConnected()) {
3239                 result.add(new NetworkState(new NetworkInfo(nai.networkInfo),
3240                         snapshot.getLinkProperties(), snapshot.getNetworkCapabilities(),
3241                         snapshot.getNetwork(), snapshot.getSubscriberId()));
3242             }
3243         }
3244         return result.toArray(new NetworkState[0]);
3245     }
3246 
3247     @Override
3248     @NonNull
3249     public List<NetworkStateSnapshot> getAllNetworkStateSnapshots() {
3250         // This contains IMSI details, so make sure the caller is privileged.
3251         enforceNetworkStackOrSettingsPermission();
3252 
3253         final ArrayList<NetworkStateSnapshot> result = new ArrayList<>();
3254         for (Network network : getAllNetworks()) {
3255             final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3256             final boolean includeNetwork = (nai != null) && nai.isCreated();
3257             if (includeNetwork) {
3258                 // TODO (b/73321673) : NetworkStateSnapshot contains a copy of the
3259                 // NetworkCapabilities, which may contain UIDs of apps to which the
3260                 // network applies. Should the UIDs be cleared so as not to leak or
3261                 // interfere ?
3262                 result.add(nai.getNetworkStateSnapshot());
3263             }
3264         }
3265         return result;
3266     }
3267 
3268     @Override
3269     public boolean isActiveNetworkMetered() {
3270         enforceAccessPermission();
3271 
3272         final NetworkCapabilities caps = getNetworkCapabilitiesInternal(getActiveNetwork());
3273         if (caps != null) {
3274             return !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
3275         } else {
3276             // Always return the most conservative value
3277             return true;
3278         }
3279     }
3280 
3281     /**
3282      * Ensures that the system cannot call a particular method.
3283      */
3284     private boolean disallowedBecauseSystemCaller() {
3285         // TODO: start throwing a SecurityException when GnssLocationProvider stops calling
3286         // requestRouteToHost. In Q, GnssLocationProvider is changed to not call requestRouteToHost
3287         // for devices launched with Q and above. However, existing devices upgrading to Q and
3288         // above must continued to be supported for few more releases.
3289         if (isSystem(mDeps.getCallingUid()) && SystemProperties.getInt(
3290                 "ro.product.first_api_level", 0) > Build.VERSION_CODES.P) {
3291             log("This method exists only for app backwards compatibility"
3292                     + " and must not be called by system services.");
3293             return true;
3294         }
3295         return false;
3296     }
3297 
3298     /**
3299      * Ensure that a network route exists to deliver traffic to the specified
3300      * host via the specified network interface.
3301      * @param networkType the type of the network over which traffic to the
3302      * specified host is to be routed
3303      * @param hostAddress the IP address of the host to which the route is
3304      * desired
3305      * @return {@code true} on success, {@code false} on failure
3306      */
3307     @Override
3308     public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress,
3309             String callingPackageName, String callingAttributionTag) {
3310         if (disallowedBecauseSystemCaller()) {
3311             return false;
3312         }
3313         PermissionUtils.enforcePackageNameMatchesUid(
3314                 mContext, mDeps.getCallingUid(), callingPackageName);
3315         enforceChangePermission(callingPackageName, callingAttributionTag);
3316         if (mProtectedNetworks.contains(networkType)) {
3317             enforceConnectivityRestrictedNetworksPermission(true /* checkUidsAllowedList */);
3318         }
3319 
3320         InetAddress addr;
3321         try {
3322             addr = InetAddress.getByAddress(hostAddress);
3323         } catch (UnknownHostException e) {
3324             if (DBG) log("requestRouteToHostAddress got " + e);
3325             return false;
3326         }
3327 
3328         if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
3329             if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
3330             return false;
3331         }
3332 
3333         NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
3334         if (nai == null) {
3335             if (!mLegacyTypeTracker.isTypeSupported(networkType)) {
3336                 if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType);
3337             } else {
3338                 if (DBG) log("requestRouteToHostAddress on down network: " + networkType);
3339             }
3340             return false;
3341         }
3342 
3343         DetailedState netState;
3344         synchronized (nai) {
3345             netState = nai.networkInfo.getDetailedState();
3346         }
3347 
3348         if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) {
3349             if (VDBG) {
3350                 log("requestRouteToHostAddress on down network "
3351                         + "(" + networkType + ") - dropped"
3352                         + " netState=" + netState);
3353             }
3354             return false;
3355         }
3356 
3357         final int uid = mDeps.getCallingUid();
3358         final long token = Binder.clearCallingIdentity();
3359         try {
3360             LinkProperties lp;
3361             int netId;
3362             synchronized (nai) {
3363                 lp = nai.linkProperties;
3364                 netId = nai.network.getNetId();
3365             }
3366             boolean ok = addLegacyRouteToHost(lp, addr, netId, uid);
3367             if (DBG) {
3368                 log("requestRouteToHostAddress " + addr + nai.toShortString() + " ok=" + ok);
3369             }
3370             return ok;
3371         } finally {
3372             Binder.restoreCallingIdentity(token);
3373         }
3374     }
3375 
3376     private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) {
3377         RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr);
3378         if (bestRoute == null) {
3379             bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName());
3380         } else {
3381             String iface = bestRoute.getInterface();
3382             if (bestRoute.getGateway().equals(addr)) {
3383                 // if there is no better route, add the implied hostroute for our gateway
3384                 bestRoute = RouteInfo.makeHostRoute(addr, iface);
3385             } else {
3386                 // if we will connect to this through another route, add a direct route
3387                 // to it's gateway
3388                 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface);
3389             }
3390         }
3391         if (DBG) log("Adding legacy route " + bestRoute +
3392                 " for UID/PID " + uid + "/" + Binder.getCallingPid());
3393 
3394         final String dst = bestRoute.getDestinationLinkAddress().toString();
3395         final String nextHop = bestRoute.hasGateway()
3396                 ? bestRoute.getGateway().getHostAddress() : "";
3397         try {
3398             mNetd.networkAddLegacyRoute(netId, bestRoute.getInterface(), dst, nextHop , uid);
3399         } catch (RemoteException | ServiceSpecificException e) {
3400             if (DBG) loge("Exception trying to add a route: " + e);
3401             return false;
3402         }
3403         return true;
3404     }
3405 
3406     class DnsResolverUnsolicitedEventCallback extends
3407             IDnsResolverUnsolicitedEventListener.Stub {
3408         @Override
3409         public void onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event) {
3410             try {
3411                 mHandler.sendMessage(mHandler.obtainMessage(
3412                         EVENT_PRIVATE_DNS_VALIDATION_UPDATE,
3413                         new PrivateDnsValidationUpdate(event.netId,
3414                                 InetAddresses.parseNumericAddress(event.ipAddress),
3415                                 event.hostname, event.validation)));
3416             } catch (IllegalArgumentException e) {
3417                 loge("Error parsing ip address in validation event");
3418             }
3419         }
3420 
3421         @Override
3422         public void onDnsHealthEvent(final DnsHealthEventParcel event) {
3423             NetworkAgentInfo nai = getNetworkAgentInfoForNetId(event.netId);
3424             // Netd event only allow registrants from system. Each NetworkMonitor thread is under
3425             // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd
3426             // event callback for certain nai. e.g. cellular. Register here to pass to
3427             // NetworkMonitor instead.
3428             // TODO: Move the Dns Event to NetworkMonitor. NetdEventListenerService only allows one
3429             // callback from each caller type. Need to re-factor NetdEventListenerService to allow
3430             // multiple NetworkMonitor registrants.
3431             if (nai != null && nai.satisfies(mDefaultRequest.mRequests.get(0))) {
3432                 nai.networkMonitor().notifyDnsResponse(event.healthResult);
3433             }
3434         }
3435 
3436         @Override
3437         public void onNat64PrefixEvent(final Nat64PrefixEventParcel event) {
3438             mHandler.post(() -> handleNat64PrefixEvent(event.netId, event.prefixOperation,
3439                     event.prefixAddress, event.prefixLength));
3440         }
3441 
3442         @Override
3443         public int getInterfaceVersion() {
3444             return this.VERSION;
3445         }
3446 
3447         @Override
3448         public String getInterfaceHash() {
3449             return this.HASH;
3450         }
3451     }
3452 
3453     @VisibleForTesting
3454     protected final DnsResolverUnsolicitedEventCallback mResolverUnsolEventCallback =
3455             new DnsResolverUnsolicitedEventCallback();
3456 
3457     private void registerDnsResolverUnsolicitedEventListener() {
3458         try {
3459             mDnsResolver.registerUnsolicitedEventListener(mResolverUnsolEventCallback);
3460         } catch (Exception e) {
3461             loge("Error registering DnsResolver unsolicited event callback: " + e);
3462         }
3463     }
3464 
3465     private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() {
3466         @Override
3467         public void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {
3468             if (shouldTrackUidsForBlockedStatusCallbacks()) {
3469                 Log.wtf(TAG, "Received unexpected NetworkPolicy callback");
3470                 return;
3471             }
3472             mHandler.sendMessage(mHandler.obtainMessage(
3473                     EVENT_BLOCKED_REASONS_CHANGED,
3474                     List.of(new Pair<>(uid, blockedReasons))));
3475         }
3476     };
3477 
3478     private boolean shouldTrackUidsForBlockedStatusCallbacks() {
3479         return mDeps.isAtLeastV();
3480     }
3481 
3482     @VisibleForTesting
3483     public void handleBlockedReasonsChanged(List<Pair<Integer, Integer>> reasonsList) {
3484         for (Pair<Integer, Integer> reasons: reasonsList) {
3485             final int uid = reasons.first;
3486             final int blockedReasons = reasons.second;
3487             if (shouldTrackUidsForBlockedStatusCallbacks()) {
3488                 synchronized (mBlockedStatusTrackingUids) {
3489                     if (mBlockedStatusTrackingUids.get(uid) == 0) {
3490                         // This uid is not tracked anymore.
3491                         // This can happen if the network request is unregistered while
3492                         // EVENT_BLOCKED_REASONS_CHANGED is posted but not processed yet.
3493                         continue;
3494                     }
3495                 }
3496             }
3497             maybeNotifyNetworkBlockedForNewState(uid, blockedReasons);
3498             setUidBlockedReasons(uid, blockedReasons);
3499         }
3500     }
3501 
3502     static final class UidFrozenStateChangedArgs {
3503         final int[] mUids;
3504         final int[] mFrozenStates;
3505 
3506         UidFrozenStateChangedArgs(int[] uids, int[] frozenStates) {
3507             mUids = uids;
3508             mFrozenStates = frozenStates;
3509         }
3510     }
3511 
3512     /**
3513      * Check if the cell network is idle.
3514      * @return true if the cell network state is idle
3515      *         false if the cell network state is active or unknown
3516      */
3517     private boolean isCellNetworkIdle() {
3518         final NetworkAgentInfo defaultNai = getDefaultNetwork();
3519         if (defaultNai == null
3520                 || !defaultNai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
3521             // mNetworkActivityTracker only tracks the activity of the default network. So if the
3522             // cell network is not the default network, cell network state is unknown.
3523             // TODO(b/279380356): Track cell network state when the cell is not the default network
3524             return false;
3525         }
3526 
3527         return !mNetworkActivityTracker.isDefaultNetworkActive();
3528     }
3529 
3530     private boolean shouldTrackFirewallDestroySocketReasons() {
3531         return mDeps.isAtLeastV();
3532     }
3533 
3534     private void updateDestroySocketReasons(final int uid, final int reason,
3535             final boolean addReason) {
3536         final int destroyReasons = mDestroySocketPendingUids.get(uid, DESTROY_SOCKET_REASON_NONE);
3537         if (addReason) {
3538             mDestroySocketPendingUids.put(uid, destroyReasons | reason);
3539         } else {
3540             final int newDestroyReasons = destroyReasons & ~reason;
3541             if (newDestroyReasons == DESTROY_SOCKET_REASON_NONE) {
3542                 mDestroySocketPendingUids.delete(uid);
3543             } else {
3544                 mDestroySocketPendingUids.put(uid, newDestroyReasons);
3545             }
3546         }
3547     }
3548 
3549     private void handleFrozenUids(int[] uids, int[] frozenStates) {
3550         ensureRunningOnConnectivityServiceThread();
3551         handleDestroyFrozenSockets(uids, frozenStates);
3552         handleFreezeNetworkCallbacks(uids, frozenStates);
3553     }
3554 
3555     private void handleDestroyFrozenSockets(int[] uids, int[] frozenStates) {
3556         if (!mDestroyFrozenSockets) {
3557             return;
3558         }
3559         for (int i = 0; i < uids.length; i++) {
3560             final int uid = uids[i];
3561             final boolean addReason = frozenStates[i] == UID_FROZEN_STATE_FROZEN;
3562             updateDestroySocketReasons(uid, DESTROY_SOCKET_REASON_FROZEN, addReason);
3563         }
3564 
3565         if (!mDelayDestroySockets || !isCellNetworkIdle()) {
3566             destroyPendingSockets();
3567         }
3568     }
3569 
3570     private void handleFreezeNetworkCallbacks(int[] uids, int[] frozenStates) {
3571         if (!mQueueCallbacksForFrozenApps) {
3572             return;
3573         }
3574         for (int i = 0; i < uids.length; i++) {
3575             final int uid = uids[i];
3576             // These counters may be modified on different threads, but using them here is fine
3577             // because this is only an optimization where wrong behavior would only happen if they
3578             // are zero even though there is a request registered. This is not possible as they are
3579             // always incremented before posting messages to register, and decremented on the
3580             // handler thread when unregistering.
3581             if (mSystemNetworkRequestCounter.get(uid) == 0
3582                     && mNetworkRequestCounter.get(uid) == 0) {
3583                 // Avoid iterating requests if there isn't any. The counters only track app requests
3584                 // and not internal requests (for example always-on requests which do not have a
3585                 // mMessenger), so it does not completely match the content of mRequests. This is OK
3586                 // as only app requests need to be frozen.
3587                 continue;
3588             }
3589 
3590             if (frozenStates[i] == UID_FROZEN_STATE_FROZEN) {
3591                 freezeNetworkCallbacksForUid(uid);
3592             } else {
3593                 unfreezeNetworkCallbacksForUid(uid);
3594             }
3595         }
3596     }
3597 
3598     /**
3599      * Suspend callbacks for a UID that was just frozen.
3600      *
3601      * <p>Note that it is not possible for a process to be frozen during a blocking binder call
3602      * (see CachedAppOptimizer.freezeBinder), and IConnectivityManager callback registrations are
3603      * blocking binder calls, so no callback can be registered while the UID is frozen. This means
3604      * it is not necessary to check frozen state on new callback registrations, and calling this
3605      * method when a UID is newly frozen is sufficient.
3606      *
3607      * <p>If it ever becomes possible for a process to be frozen during a blocking binder call,
3608      * ConnectivityService will need to handle freezing callbacks that reach ConnectivityService
3609      * after the app was frozen when being registered.
3610      */
3611     private void freezeNetworkCallbacksForUid(int uid) {
3612         if (DDBG) Log.d(TAG, "Freezing callbacks for UID " + uid);
3613         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
3614             if (nri.mUid != uid) continue;
3615             // mNetworkRequests can have duplicate values for multilayer requests, but calling
3616             // onFrozen multiple times is fine.
3617             // If freezeNetworkCallbacksForUid was called multiple times in a raw for a frozen UID
3618             // (which would be incorrect), this would also handle it gracefully.
3619             nri.onFrozen();
3620         }
3621     }
3622 
3623     private void unfreezeNetworkCallbacksForUid(int uid) {
3624         // This sends all callbacks for one NetworkRequest at a time, which may not be the
3625         // same order they were queued in, but different network requests use different
3626         // binder objects, so the relative order of their callbacks is not guaranteed.
3627         // If callbacks are not queued, callbacks from different binder objects may be
3628         // posted on different threads when the process is unfrozen, so even if they were
3629         // called a long time apart while the process was frozen, they may still appear in
3630         // different order when unfreezing it.
3631         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
3632             if (nri.mUid != uid) continue;
3633             nri.sendQueuedCallbacks();
3634         }
3635     }
3636 
3637     private void handleUpdateFirewallDestroySocketReasons(
3638             List<Pair<Integer, Integer>> reasonsList) {
3639         if (!shouldTrackFirewallDestroySocketReasons()) {
3640             Log.wtf(TAG, "handleUpdateFirewallDestroySocketReasons is called unexpectedly");
3641             return;
3642         }
3643         ensureRunningOnConnectivityServiceThread();
3644 
3645         for (Pair<Integer, Integer> uidSocketDestroyReasons: reasonsList) {
3646             final int uid = uidSocketDestroyReasons.first;
3647             final int reasons = uidSocketDestroyReasons.second;
3648             final boolean destroyByFirewallBackground =
3649                     (reasons & DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND)
3650                             != DESTROY_SOCKET_REASON_NONE;
3651             updateDestroySocketReasons(uid, DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND,
3652                     destroyByFirewallBackground);
3653         }
3654 
3655         if (!mDelayDestroySockets || !isCellNetworkIdle()) {
3656             destroyPendingSockets();
3657         }
3658     }
3659 
3660     private void handleClearFirewallDestroySocketReasons(final int reason) {
3661         if (!shouldTrackFirewallDestroySocketReasons()) {
3662             Log.wtf(TAG, "handleClearFirewallDestroySocketReasons is called uexpectedly");
3663             return;
3664         }
3665         ensureRunningOnConnectivityServiceThread();
3666 
3667         // Unset reason from all pending uids
3668         for (int i = mDestroySocketPendingUids.size() - 1; i >= 0; i--) {
3669             final int uid = mDestroySocketPendingUids.keyAt(i);
3670             updateDestroySocketReasons(uid, reason, false /* addReason */);
3671         }
3672     }
3673 
3674     private void destroyPendingSockets() {
3675         ensureRunningOnConnectivityServiceThread();
3676         if (mDestroySocketPendingUids.size() == 0) {
3677             return;
3678         }
3679 
3680         Set<Integer> uids = new ArraySet<>();
3681         for (int i = 0; i < mDestroySocketPendingUids.size(); i++) {
3682             uids.add(mDestroySocketPendingUids.keyAt(i));
3683         }
3684 
3685         try {
3686             mDeps.destroyLiveTcpSocketsByOwnerUids(uids);
3687         } catch (SocketException | InterruptedIOException | ErrnoException e) {
3688             loge("Failed to destroy sockets: " + e);
3689         }
3690         mDestroySocketPendingUids.clear();
3691     }
3692 
3693     private void handleReportNetworkActivity(final NetworkActivityParams params) {
3694         mNetworkActivityTracker.handleReportNetworkActivity(params);
3695 
3696         final boolean isCellNetworkActivity;
3697         if (mTrackMultiNetworkActivities) {
3698             final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(params.label);
3699             // nai could be null if netd receives a netlink message and calls the network
3700             // activity change callback after the network is unregistered from ConnectivityService.
3701             isCellNetworkActivity = nai != null
3702                     && nai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR);
3703         } else {
3704             isCellNetworkActivity = params.label == TRANSPORT_CELLULAR;
3705         }
3706 
3707         if (mDelayDestroySockets && params.isActive && isCellNetworkActivity) {
3708             destroyPendingSockets();
3709         }
3710     }
3711 
3712     /**
3713      * If the cellular network is no longer the default network, destroy pending sockets.
3714      *
3715      * @param newNetwork new default network
3716      * @param oldNetwork old default network
3717      */
3718     private void maybeDestroyPendingSockets(NetworkAgentInfo newNetwork,
3719             NetworkAgentInfo oldNetwork) {
3720         final boolean isOldNetworkCellular = oldNetwork != null
3721                 && oldNetwork.networkCapabilities.hasTransport(TRANSPORT_CELLULAR);
3722         final boolean isNewNetworkCellular = newNetwork != null
3723                 && newNetwork.networkCapabilities.hasTransport(TRANSPORT_CELLULAR);
3724 
3725         if (isOldNetworkCellular && !isNewNetworkCellular) {
3726             destroyPendingSockets();
3727         }
3728     }
3729 
3730     private void dumpDestroySockets(IndentingPrintWriter pw) {
3731         pw.println("DestroySockets:");
3732         pw.increaseIndent();
3733         pw.print("mDestroyFrozenSockets="); pw.println(mDestroyFrozenSockets);
3734         pw.print("mDelayDestroySockets="); pw.println(mDelayDestroySockets);
3735         pw.print("mDestroySocketPendingUids:");
3736         pw.increaseIndent();
3737         for (int i = 0; i < mDestroySocketPendingUids.size(); i++) {
3738             final int uid = mDestroySocketPendingUids.keyAt(i);
3739             final int reasons = mDestroySocketPendingUids.valueAt(i);
3740             pw.print(uid + ": reasons=" + reasons);
3741         }
3742         pw.decreaseIndent();
3743         pw.decreaseIndent();
3744     }
3745 
3746     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
3747     private void dumpBpfProgramStatus(IndentingPrintWriter pw) {
3748         pw.println("Bpf Program Status:");
3749         pw.increaseIndent();
3750         try {
3751             pw.print("CGROUP_INET_INGRESS: ");
3752             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_INGRESS));
3753             pw.print("CGROUP_INET_EGRESS: ");
3754             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_EGRESS));
3755 
3756             pw.print("CGROUP_INET_SOCK_CREATE: ");
3757             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_SOCK_CREATE));
3758 
3759             pw.print("CGROUP_INET4_BIND: ");
3760             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET4_BIND));
3761             pw.print("CGROUP_INET6_BIND: ");
3762             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET6_BIND));
3763 
3764             pw.print("CGROUP_INET4_CONNECT: ");
3765             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET4_CONNECT));
3766             pw.print("CGROUP_INET6_CONNECT: ");
3767             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET6_CONNECT));
3768 
3769             pw.print("CGROUP_UDP4_SENDMSG: ");
3770             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP4_SENDMSG));
3771             pw.print("CGROUP_UDP6_SENDMSG: ");
3772             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP6_SENDMSG));
3773 
3774             pw.print("CGROUP_UDP4_RECVMSG: ");
3775             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP4_RECVMSG));
3776             pw.print("CGROUP_UDP6_RECVMSG: ");
3777             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP6_RECVMSG));
3778 
3779             pw.print("CGROUP_GETSOCKOPT: ");
3780             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_GETSOCKOPT));
3781             pw.print("CGROUP_SETSOCKOPT: ");
3782             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_SETSOCKOPT));
3783 
3784             pw.print("CGROUP_INET_SOCK_RELEASE: ");
3785             pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_SOCK_RELEASE));
3786         } catch (IOException e) {
3787             pw.println("  IOException");
3788         }
3789         pw.decreaseIndent();
3790     }
3791 
3792     @VisibleForTesting
3793     static final String KEY_DESTROY_FROZEN_SOCKETS_VERSION = "destroy_frozen_sockets_version";
3794 
3795     @VisibleForTesting
3796     public static final String ALLOW_SYSUI_CONNECTIVITY_REPORTS =
3797             "allow_sysui_connectivity_reports";
3798 
3799     public static final String ALLOW_SATALLITE_NETWORK_FALLBACK =
3800             "allow_satallite_network_fallback";
3801 
3802     private void enforceInternetPermission() {
3803         mContext.enforceCallingOrSelfPermission(
3804                 android.Manifest.permission.INTERNET,
3805                 "ConnectivityService");
3806     }
3807 
3808     private void enforceAccessPermission() {
3809         mContext.enforceCallingOrSelfPermission(
3810                 android.Manifest.permission.ACCESS_NETWORK_STATE,
3811                 "ConnectivityService");
3812     }
3813 
3814     @CheckResult
3815     private boolean hasAccessPermission(int pid, int uid) {
3816         return mContext.checkPermission(android.Manifest.permission.ACCESS_NETWORK_STATE, pid, uid)
3817                 == PERMISSION_GRANTED;
3818     }
3819 
3820     /**
3821      * Performs a strict and comprehensive check of whether a calling package is allowed to
3822      * change the state of network, as the condition differs for pre-M, M+, and
3823      * privileged/preinstalled apps. The caller is expected to have either the
3824      * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these
3825      * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and
3826      * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal
3827      * permission and cannot be revoked. See http://b/23597341
3828      *
3829      * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation
3830      * of this app will be updated to the current time.
3831      */
3832     private void enforceChangePermission(String callingPkg, String callingAttributionTag) {
3833         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE)
3834                 == PackageManager.PERMISSION_GRANTED) {
3835             return;
3836         }
3837 
3838         if (callingPkg == null) {
3839             throw new SecurityException("Calling package name is null.");
3840         }
3841 
3842         final AppOpsManager appOpsMgr = mContext.getSystemService(AppOpsManager.class);
3843         final int uid = mDeps.getCallingUid();
3844         final int mode = appOpsMgr.noteOpNoThrow(AppOpsManager.OPSTR_WRITE_SETTINGS, uid,
3845                 callingPkg, callingAttributionTag, null /* message */);
3846 
3847         if (mode == AppOpsManager.MODE_ALLOWED) {
3848             return;
3849         }
3850 
3851         if ((mode == AppOpsManager.MODE_DEFAULT) && (mContext.checkCallingOrSelfPermission(
3852                 android.Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED)) {
3853             return;
3854         }
3855 
3856         throw new SecurityException(callingPkg + " was not granted either of these permissions:"
3857                 + android.Manifest.permission.CHANGE_NETWORK_STATE + ","
3858                 + android.Manifest.permission.WRITE_SETTINGS + ".");
3859     }
3860 
3861     private void enforceSettingsPermission() {
3862         enforceAnyPermissionOf(mContext,
3863                 android.Manifest.permission.NETWORK_SETTINGS,
3864                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
3865     }
3866 
3867     private void enforceSettingsOrSetupWizardOrUseRestrictedNetworksPermission() {
3868         enforceAnyPermissionOf(mContext,
3869                 android.Manifest.permission.NETWORK_SETTINGS,
3870                 android.Manifest.permission.NETWORK_SETUP_WIZARD,
3871                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
3872                 Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS);
3873     }
3874 
3875     private void enforceNetworkFactoryPermission() {
3876         // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface.
3877         if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return;
3878         enforceAnyPermissionOf(mContext,
3879                 android.Manifest.permission.NETWORK_FACTORY,
3880                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
3881     }
3882 
3883     private void enforceNetworkFactoryOrSettingsPermission() {
3884         // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface.
3885         if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return;
3886         enforceAnyPermissionOf(mContext,
3887                 android.Manifest.permission.NETWORK_SETTINGS,
3888                 android.Manifest.permission.NETWORK_FACTORY,
3889                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
3890     }
3891 
3892     private void enforceNetworkFactoryOrTestNetworksPermission() {
3893         // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface.
3894         if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return;
3895         enforceAnyPermissionOf(mContext,
3896                 android.Manifest.permission.MANAGE_TEST_NETWORKS,
3897                 android.Manifest.permission.NETWORK_FACTORY,
3898                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
3899     }
3900 
3901     @CheckResult
3902     private boolean hasNetworkFactoryOrSettingsPermission(int pid, int uid) {
3903         return PERMISSION_GRANTED == mContext.checkPermission(
3904                 android.Manifest.permission.NETWORK_FACTORY, pid, uid)
3905                 || PERMISSION_GRANTED == mContext.checkPermission(
3906                 android.Manifest.permission.NETWORK_SETTINGS, pid, uid)
3907                 || PERMISSION_GRANTED == mContext.checkPermission(
3908                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid)
3909                 || UserHandle.getAppId(uid) == Process.BLUETOOTH_UID;
3910     }
3911 
3912     @CheckResult
3913     private boolean hasSettingsPermission() {
3914         return hasAnyPermissionOf(mContext, android.Manifest.permission.NETWORK_SETTINGS,
3915                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
3916     }
3917 
3918     @CheckResult
3919     private boolean hasSettingsPermission(int pid, int uid) {
3920         return PERMISSION_GRANTED == mContext.checkPermission(
3921                 android.Manifest.permission.NETWORK_SETTINGS, pid, uid)
3922                 || PERMISSION_GRANTED == mContext.checkPermission(
3923                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid);
3924     }
3925 
3926     private void enforceNetworkStackOrSettingsPermission() {
3927         enforceNetworkStackPermissionOr(mContext,
3928                 android.Manifest.permission.NETWORK_SETTINGS);
3929     }
3930 
3931     private void enforceNetworkStackSettingsOrSetup() {
3932         enforceNetworkStackPermissionOr(mContext,
3933                 android.Manifest.permission.NETWORK_SETTINGS,
3934                 android.Manifest.permission.NETWORK_SETUP_WIZARD);
3935     }
3936 
3937     private void enforceAirplaneModePermission() {
3938         enforceNetworkStackPermissionOr(mContext,
3939                 android.Manifest.permission.NETWORK_AIRPLANE_MODE,
3940                 android.Manifest.permission.NETWORK_SETTINGS,
3941                 android.Manifest.permission.NETWORK_SETUP_WIZARD);
3942     }
3943 
3944     private void enforceOemNetworkPreferencesPermission() {
3945         mContext.enforceCallingOrSelfPermission(
3946                 android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE,
3947                 "ConnectivityService");
3948     }
3949 
3950     private void enforceManageTestNetworksPermission() {
3951         mContext.enforceCallingOrSelfPermission(
3952                 android.Manifest.permission.MANAGE_TEST_NETWORKS,
3953                 "ConnectivityService");
3954     }
3955 
3956     @CheckResult
3957     private boolean hasNetworkStackPermission() {
3958         return hasAnyPermissionOf(mContext, android.Manifest.permission.NETWORK_STACK,
3959                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
3960     }
3961 
3962     @CheckResult
3963     private boolean hasNetworkStackPermission(int pid, int uid) {
3964         return hasAnyPermissionOf(mContext, pid, uid, android.Manifest.permission.NETWORK_STACK,
3965                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
3966     }
3967 
3968     @CheckResult
3969     private boolean hasSystemBarServicePermission(int pid, int uid) {
3970         return hasAnyPermissionOf(mContext, pid, uid,
3971                 android.Manifest.permission.STATUS_BAR_SERVICE);
3972     }
3973 
3974     @CheckResult
3975     private boolean hasNetworkSignalStrengthWakeupPermission(int pid, int uid) {
3976         return hasAnyPermissionOf(mContext, pid, uid,
3977                 android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP,
3978                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
3979                 android.Manifest.permission.NETWORK_SETTINGS);
3980     }
3981 
3982     @CheckResult
3983     private boolean hasConnectivityRestrictedNetworksPermission(int callingUid,
3984             boolean checkUidsAllowedList) {
3985         if (hasAnyPermissionOf(mContext,
3986                 android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS)) {
3987             return true;
3988         }
3989 
3990         // fallback to ConnectivityInternalPermission
3991         // TODO: Remove this fallback check after all apps have declared
3992         //  CONNECTIVITY_USE_RESTRICTED_NETWORKS.
3993         if (hasAnyPermissionOf(mContext, android.Manifest.permission.CONNECTIVITY_INTERNAL)) {
3994             return true;
3995         }
3996 
3997         // Check whether uid is in allowed on restricted networks list.
3998         if (checkUidsAllowedList
3999                 && mPermissionMonitor.isUidAllowedOnRestrictedNetworks(callingUid)) {
4000             return true;
4001         }
4002         return false;
4003     }
4004 
4005     private void enforceConnectivityRestrictedNetworksPermission(boolean checkUidsAllowedList) {
4006         final int callingUid = mDeps.getCallingUid();
4007         if (!hasConnectivityRestrictedNetworksPermission(callingUid, checkUidsAllowedList)) {
4008             throw new SecurityException("ConnectivityService: user " + callingUid
4009                     + " has no permission to access restricted network.");
4010         }
4011     }
4012 
4013     private void enforceKeepalivePermission() {
4014         mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
4015     }
4016 
4017     @CheckResult
4018     private boolean hasLocalMacAddressPermission(int pid, int uid) {
4019         return PERMISSION_GRANTED == mContext.checkPermission(
4020                 Manifest.permission.LOCAL_MAC_ADDRESS, pid, uid);
4021     }
4022 
4023     private void sendConnectedBroadcast(NetworkInfo info) {
4024         sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
4025     }
4026 
4027     private void sendInetConditionBroadcast(NetworkInfo info) {
4028         sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
4029     }
4030 
4031     private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
4032         Intent intent = new Intent(bcastType);
4033         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info));
4034         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
4035         if (info.isFailover()) {
4036             intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
4037             info.setFailover(false);
4038         }
4039         if (info.getReason() != null) {
4040             intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
4041         }
4042         if (info.getExtraInfo() != null) {
4043             intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
4044                     info.getExtraInfo());
4045         }
4046         intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
4047         return intent;
4048     }
4049 
4050     private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
4051         sendStickyBroadcast(makeGeneralIntent(info, bcastType));
4052     }
4053 
4054     // TODO(b/193460475): Remove when tooling supports SystemApi to public API.
4055     @SuppressLint("NewApi")
4056     // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed.
4057     @TargetApi(Build.VERSION_CODES.S)
4058     private void sendStickyBroadcast(Intent intent) {
4059         synchronized (this) {
4060             if (!mSystemReady
4061                     && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
4062                 mInitialBroadcast = new Intent(intent);
4063             }
4064             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
4065             if (VDBG) {
4066                 log("sendStickyBroadcast: action=" + intent.getAction());
4067             }
4068 
4069             Bundle options = null;
4070             final long ident = Binder.clearCallingIdentity();
4071             if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
4072                 final NetworkInfo ni = intent.getParcelableExtra(
4073                         ConnectivityManager.EXTRA_NETWORK_INFO);
4074                 final BroadcastOptions opts = BroadcastOptions.makeBasic();
4075                 opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M);
4076                 applyMostRecentPolicyForConnectivityAction(opts, ni);
4077                 options = opts.toBundle();
4078                 intent.addFlags(Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
4079             }
4080             try {
4081                 mUserAllContext.sendStickyBroadcast(intent, options);
4082             } finally {
4083                 Binder.restoreCallingIdentity(ident);
4084             }
4085         }
4086     }
4087 
4088     private void applyMostRecentPolicyForConnectivityAction(BroadcastOptions options,
4089             NetworkInfo info) {
4090         // Delivery group policy APIs are only available on U+.
4091         if (!mDeps.isAtLeastU()) return;
4092 
4093         final BroadcastOptionsShim optsShim = mDeps.makeBroadcastOptionsShim(options);
4094         try {
4095             // This allows us to discard older broadcasts still waiting to be delivered
4096             // which have the same namespace and key.
4097             optsShim.setDeliveryGroupPolicy(ConstantsShim.DELIVERY_GROUP_POLICY_MOST_RECENT);
4098             optsShim.setDeliveryGroupMatchingKey(ConnectivityManager.CONNECTIVITY_ACTION,
4099                     createDeliveryGroupKeyForConnectivityAction(info));
4100             optsShim.setDeferralPolicy(ConstantsShim.DEFERRAL_POLICY_UNTIL_ACTIVE);
4101         } catch (UnsupportedApiLevelException e) {
4102             Log.wtf(TAG, "Using unsupported API" + e);
4103         }
4104     }
4105 
4106     @VisibleForTesting
4107     static String createDeliveryGroupKeyForConnectivityAction(NetworkInfo info) {
4108         final StringBuilder sb = new StringBuilder();
4109         sb.append(info.getType()).append(DELIVERY_GROUP_KEY_DELIMITER);
4110         sb.append(info.getSubtype()).append(DELIVERY_GROUP_KEY_DELIMITER);
4111         sb.append(info.getExtraInfo());
4112         return sb.toString();
4113     }
4114 
4115     /**
4116      * Called by SystemServer through ConnectivityManager when the system is ready.
4117      */
4118     @Override
4119     public void systemReady() {
4120         if (mDeps.getCallingUid() != Process.SYSTEM_UID) {
4121             throw new SecurityException("Calling Uid is not system uid.");
4122         }
4123         systemReadyInternal();
4124     }
4125 
4126     /**
4127      * Called when ConnectivityService can initialize remaining components.
4128      */
4129     @VisibleForTesting
4130     public void systemReadyInternal() {
4131         // Load flags after PackageManager is ready to query module version
4132         mFlags.loadFlags(mDeps, mContext);
4133 
4134         // Since mApps in PermissionMonitor needs to be populated first to ensure that
4135         // listening network request which is sent by MultipathPolicyTracker won't be added
4136         // NET_CAPABILITY_FOREGROUND capability. Thus, MultipathPolicyTracker.start() must
4137         // be called after PermissionMonitor#startMonitoring().
4138         // Calling PermissionMonitor#startMonitoring() in systemReadyInternal() and the
4139         // MultipathPolicyTracker.start() is called in NetworkPolicyManagerService#systemReady()
4140         // to ensure the tracking will be initialized correctly.
4141         final ConditionVariable startMonitoringDone = new ConditionVariable();
4142         mHandler.post(() -> {
4143             mPermissionMonitor.startMonitoring();
4144             startMonitoringDone.open();
4145         });
4146         mProxyTracker.loadGlobalProxy();
4147         registerDnsResolverUnsolicitedEventListener();
4148 
4149         synchronized (this) {
4150             mSystemReady = true;
4151             if (mInitialBroadcast != null) {
4152                 mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL);
4153                 mInitialBroadcast = null;
4154             }
4155         }
4156 
4157         // Create network requests for always-on networks.
4158         mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS));
4159 
4160         // Update mobile data preference if necessary.
4161         // Note that updating can be skipped here if the list is empty only because no uid
4162         // rules are applied before system ready. Normally, the empty uid list means to clear
4163         // the uids rules on netd.
4164         if (!ConnectivitySettingsManager.getMobileDataPreferredUids(mContext).isEmpty()) {
4165             updateMobileDataPreferredUids();
4166         }
4167 
4168         if (mSatelliteAccessController != null) {
4169             mSatelliteAccessController.start();
4170         }
4171 
4172         if (mCarrierPrivilegeAuthenticator != null) {
4173             mCarrierPrivilegeAuthenticator.start();
4174         }
4175 
4176         if (mL2capNetworkProvider != null) {
4177             mL2capNetworkProvider.start();
4178         }
4179 
4180         // On T+ devices, register callback for statsd to pull NETWORK_BPF_MAP_INFO atom
4181         if (mDeps.isAtLeastT()) {
4182             mBpfNetMaps.setPullAtomCallback(mContext);
4183         }
4184         ConnectivitySampleMetricsHelper.start(mContext, mHandler,
4185                 CONNECTIVITY_STATE_SAMPLE, this::sampleConnectivityStateToStatsEvent);
4186         // Wait PermissionMonitor to finish the permission update. Then MultipathPolicyTracker won't
4187         // have permission problem. While CV#block() is unbounded in time and can in principle block
4188         // forever, this replaces a synchronous call to PermissionMonitor#startMonitoring, which
4189         // could have blocked forever too.
4190         startMonitoringDone.block();
4191     }
4192 
4193     /**
4194      * Start listening for default data network activity state changes.
4195      */
4196     @Override
4197     public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
4198         mNetworkActivityTracker.registerNetworkActivityListener(l);
4199     }
4200 
4201     /**
4202      * Stop listening for default data network activity state changes.
4203      */
4204     @Override
4205     public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
4206         mNetworkActivityTracker.unregisterNetworkActivityListener(l);
4207     }
4208 
4209     /**
4210      * Check whether the default network radio is currently active.
4211      */
4212     @Override
4213     public boolean isDefaultNetworkActive() {
4214         return mNetworkActivityTracker.isDefaultNetworkActive();
4215     }
4216 
4217     /**
4218      * Reads the network specific MTU size from resources.
4219      * and set it on it's iface.
4220      */
4221     private void updateMtu(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp) {
4222         final String iface = newLp.getInterfaceName();
4223         final int mtu = newLp.getMtu();
4224         if (mtu == 0) {
4225             // Silently ignore unset MTU value.
4226             return;
4227         }
4228         if (oldLp != null && newLp.isIdenticalMtu(oldLp)
4229                 && TextUtils.equals(oldLp.getInterfaceName(), iface)) {
4230             if (VDBG) log("identical MTU and iface - not setting");
4231             return;
4232         }
4233         // Cannot set MTU without interface name
4234         if (TextUtils.isEmpty(iface)) {
4235             if (VDBG) log("Setting MTU size with null iface.");
4236             return;
4237         }
4238 
4239         if (!LinkProperties.isValidMtu(mtu, newLp.hasGlobalIpv6Address())) {
4240             loge("Unexpected mtu value: " + mtu + ", " + iface);
4241             return;
4242         }
4243 
4244         try {
4245             if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu);
4246             mNetd.interfaceSetMtu(iface, mtu);
4247         } catch (RemoteException | ServiceSpecificException e) {
4248             loge("exception in interfaceSetMtu()" + e);
4249         }
4250     }
4251 
4252     @VisibleForTesting
4253     protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208";
4254 
4255     private void updateTcpBufferSizes(@Nullable String tcpBufferSizes) {
4256         String[] values = null;
4257         if (tcpBufferSizes != null) {
4258             values = tcpBufferSizes.split(",");
4259         }
4260 
4261         if (values == null || values.length != 6) {
4262             if (DBG) log("Invalid tcpBufferSizes string: " + tcpBufferSizes +", using defaults");
4263             tcpBufferSizes = DEFAULT_TCP_BUFFER_SIZES;
4264             values = tcpBufferSizes.split(",");
4265         }
4266 
4267         if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return;
4268 
4269         try {
4270             if (VDBG || DDBG) log("Setting tx/rx TCP buffers to " + tcpBufferSizes);
4271 
4272             String rmemValues = String.join(" ", values[0], values[1], values[2]);
4273             String wmemValues = String.join(" ", values[3], values[4], values[5]);
4274             mNetd.setTcpRWmemorySize(rmemValues, wmemValues);
4275             mCurrentTcpBufferSizes = tcpBufferSizes;
4276         } catch (RemoteException | ServiceSpecificException e) {
4277             loge("Can't set TCP buffer sizes:" + e);
4278         }
4279     }
4280 
4281     @Override
4282     public int getRestoreDefaultNetworkDelay(int networkType) {
4283         String restoreDefaultNetworkDelayStr = mSystemProperties.get(
4284                 NETWORK_RESTORE_DELAY_PROP_NAME);
4285         if(restoreDefaultNetworkDelayStr != null &&
4286                 restoreDefaultNetworkDelayStr.length() != 0) {
4287             try {
4288                 return Integer.parseInt(restoreDefaultNetworkDelayStr);
4289             } catch (NumberFormatException e) {
4290             }
4291         }
4292         // if the system property isn't set, use the value for the apn type
4293         int ret = RESTORE_DEFAULT_NETWORK_DELAY;
4294 
4295         if (mLegacyTypeTracker.isTypeSupported(networkType)) {
4296             ret = mLegacyTypeTracker.getRestoreTimerForType(networkType);
4297         }
4298         return ret;
4299     }
4300 
4301     private void dumpNetworkDiagnostics(IndentingPrintWriter pw) {
4302         final List<NetworkDiagnostics> netDiags = new ArrayList<>();
4303         final long DIAG_TIME_MS = 5000;
4304         for (NetworkAgentInfo nai : networksSortedById()) {
4305             PrivateDnsConfig privateDnsCfg = mDnsManager.getPrivateDnsConfig(nai.network);
4306             // Start gathering diagnostic information.
4307             netDiags.add(new NetworkDiagnostics(
4308                     nai.network,
4309                     new LinkProperties(nai.linkProperties),  // Must be a copy.
4310                     privateDnsCfg,
4311                     DIAG_TIME_MS));
4312         }
4313 
4314         for (NetworkDiagnostics netDiag : netDiags) {
4315             pw.println();
4316             netDiag.waitForMeasurements();
4317             netDiag.dump(pw);
4318         }
4319     }
4320 
4321     @Override
4322     protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
4323             @Nullable String[] args) {
4324         if (!hasDumpPermission(mContext, TAG, writer)) return;
4325 
4326         mPriorityDumper.dump(fd, writer, args);
4327     }
4328 
4329     @CheckResult
4330     private boolean hasDumpPermission(Context context, String tag, PrintWriter pw) {
4331         if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
4332                 != PackageManager.PERMISSION_GRANTED) {
4333             pw.println("Permission Denial: can't dump " + tag + " from from pid="
4334                     + Binder.getCallingPid() + ", uid=" + mDeps.getCallingUid()
4335                     + " due to missing android.permission.DUMP permission");
4336             return false;
4337         } else {
4338             return true;
4339         }
4340     }
4341 
4342     private void doDump(FileDescriptor fd, PrintWriter writer, String[] args) {
4343         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
4344 
4345         if (CollectionUtils.contains(args, DIAG_ARG)) {
4346             dumpNetworkDiagnostics(pw);
4347             return;
4348         } else if (CollectionUtils.contains(args, NETWORK_ARG)) {
4349             dumpNetworks(pw);
4350             return;
4351         } else if (CollectionUtils.contains(args, REQUEST_ARG)) {
4352             dumpNetworkRequests(pw);
4353             return;
4354         } else if (CollectionUtils.contains(args, TRAFFICCONTROLLER_ARG)) {
4355             boolean verbose = !CollectionUtils.contains(args, SHORT_ARG);
4356             dumpTrafficController(pw, fd, verbose);
4357             return;
4358         } else if (CollectionUtils.contains(args, CLATEGRESS4RAWBPFMAP_ARG)) {
4359             dumpClatBpfRawMap(pw, true /* isEgress4Map */);
4360             return;
4361         } else if (CollectionUtils.contains(args, CLATINGRESS6RAWBPFMAP_ARG)) {
4362             dumpClatBpfRawMap(pw, false /* isEgress4Map */);
4363             return;
4364         }
4365 
4366         pw.println("NetworkProviders for:");
4367         pw.increaseIndent();
4368         for (NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
4369             pw.println(npi.providerId + ": " + npi.name);
4370         }
4371         pw.decreaseIndent();
4372         pw.println();
4373 
4374         final NetworkAgentInfo defaultNai = getDefaultNetwork();
4375         pw.print("Active default network: ");
4376         if (defaultNai == null) {
4377             pw.println("none");
4378         } else {
4379             pw.println(defaultNai.network.getNetId());
4380         }
4381         pw.println();
4382 
4383         pw.println("Current network preferences: ");
4384         pw.increaseIndent();
4385         dumpNetworkPreferences(pw);
4386         pw.decreaseIndent();
4387         pw.println();
4388 
4389         pw.println("Current Networks:");
4390         pw.increaseIndent();
4391         dumpNetworks(pw);
4392         pw.decreaseIndent();
4393         pw.println();
4394 
4395         pw.println("Status for known UIDs:");
4396         pw.increaseIndent();
4397         final int size = mUidBlockedReasons.size();
4398         for (int i = 0; i < size; i++) {
4399             // Don't crash if the array is modified while dumping in bugreports.
4400             try {
4401                 final int uid = mUidBlockedReasons.keyAt(i);
4402                 final int blockedReasons = mUidBlockedReasons.valueAt(i);
4403                 pw.println("UID=" + uid + " blockedReasons="
4404                         + Integer.toHexString(blockedReasons));
4405             } catch (ArrayIndexOutOfBoundsException e) {
4406                 pw.println("  ArrayIndexOutOfBoundsException");
4407             } catch (ConcurrentModificationException e) {
4408                 pw.println("  ConcurrentModificationException");
4409             }
4410         }
4411         pw.println();
4412         pw.decreaseIndent();
4413 
4414         pw.println("Network Requests:");
4415         pw.increaseIndent();
4416         dumpNetworkRequests(pw);
4417         pw.decreaseIndent();
4418         pw.println();
4419 
4420         pw.println("Network Offers:");
4421         pw.increaseIndent();
4422         for (final NetworkOfferInfo offerInfo : mNetworkOffers) {
4423             pw.println(offerInfo.offer);
4424         }
4425         pw.decreaseIndent();
4426         pw.println();
4427 
4428         mLegacyTypeTracker.dump(pw);
4429 
4430         pw.println();
4431         mKeepaliveTracker.dump(pw);
4432 
4433         pw.println();
4434         dumpAvoidBadWifiSettings(pw);
4435 
4436         pw.println();
4437         dumpDestroySockets(pw);
4438 
4439         if (mDeps.isAtLeastT()) {
4440             // R: https://android.googlesource.com/platform/system/core/+/refs/heads/android11-release/rootdir/init.rc
4441             //   shows /dev/cg2_bpf
4442             // S: https://android.googlesource.com/platform/system/core/+/refs/heads/android12-release/rootdir/init.rc
4443             //   does not
4444             // Thus cgroups are mounted at /dev/cg2_bpf on R and not on /sys/fs/cgroup
4445             // so the following won't work (on R) anyway.
4446             // The /sys/fs/cgroup path is only actually enforced/required starting with U,
4447             // but it is very likely to already be the case (though not guaranteed) on T.
4448             // I'm not at all sure about S - let's just skip it to get rid of lint warnings.
4449             pw.println();
4450             dumpBpfProgramStatus(pw);
4451         }
4452 
4453         if (null != mCarrierPrivilegeAuthenticator) {
4454             pw.println();
4455             mCarrierPrivilegeAuthenticator.dump(pw);
4456         }
4457 
4458         pw.println();
4459 
4460         if (!CollectionUtils.contains(args, SHORT_ARG)) {
4461             pw.println();
4462             pw.println("mNetworkRequestInfoLogs (most recent first):");
4463             pw.increaseIndent();
4464             mNetworkRequestInfoLogs.reverseDump(pw);
4465             pw.decreaseIndent();
4466 
4467             pw.println();
4468             pw.println("mNetworkInfoBlockingLogs (most recent first):");
4469             pw.increaseIndent();
4470             mNetworkInfoBlockingLogs.reverseDump(pw);
4471             pw.decreaseIndent();
4472 
4473             pw.println();
4474             pw.println("NetTransition WakeLock activity (most recent first):");
4475             pw.increaseIndent();
4476             pw.println("total acquisitions: " + mTotalWakelockAcquisitions);
4477             pw.println("total releases: " + mTotalWakelockReleases);
4478             pw.println("cumulative duration: " + (mTotalWakelockDurationMs / 1000) + "s");
4479             pw.println("longest duration: " + (mMaxWakelockDurationMs / 1000) + "s");
4480             if (mTotalWakelockAcquisitions > mTotalWakelockReleases) {
4481                 long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
4482                 pw.println("currently holding WakeLock for: " + (duration / 1000) + "s");
4483             }
4484             mWakelockLogs.reverseDump(pw);
4485 
4486             pw.println();
4487             pw.println("bandwidth update requests (by uid):");
4488             pw.increaseIndent();
4489             synchronized (mBandwidthRequests) {
4490                 for (int i = 0; i < mBandwidthRequests.size(); i++) {
4491                     pw.println("[" + mBandwidthRequests.keyAt(i)
4492                             + "]: " + mBandwidthRequests.valueAt(i));
4493                 }
4494             }
4495             pw.decreaseIndent();
4496             pw.decreaseIndent();
4497 
4498             pw.println();
4499             pw.println("mOemNetworkPreferencesLogs (most recent first):");
4500             pw.increaseIndent();
4501             mOemNetworkPreferencesLogs.reverseDump(pw);
4502             pw.decreaseIndent();
4503         }
4504 
4505         pw.println();
4506 
4507         pw.println();
4508         pw.println("Permission Monitor:");
4509         pw.increaseIndent();
4510         mPermissionMonitor.dump(pw);
4511         pw.decreaseIndent();
4512 
4513         pw.println();
4514         pw.println("Legacy network activity:");
4515         pw.increaseIndent();
4516         mNetworkActivityTracker.dump(pw);
4517         pw.decreaseIndent();
4518 
4519         pw.println();
4520         pw.println("Multicast routing supported: " +
4521                 (mMulticastRoutingCoordinatorService != null));
4522         pw.println("Background firewall chain enabled: " + mBackgroundFirewallChainEnabled);
4523         pw.println("IngressToVpnAddressFiltering: " + mIngressToVpnAddressFiltering);
4524     }
4525 
4526     private void dumpNetworks(IndentingPrintWriter pw) {
4527         for (NetworkAgentInfo nai : networksSortedById()) {
4528             pw.println(nai.toString());
4529             pw.increaseIndent();
4530             pw.println("Nat464Xlat:");
4531             pw.increaseIndent();
4532             nai.dumpNat464Xlat(pw);
4533             pw.decreaseIndent();
4534             pw.println(String.format(
4535                     "Requests: REQUEST:%d LISTEN:%d BACKGROUND_REQUEST:%d total:%d",
4536                     nai.numForegroundNetworkRequests(),
4537                     nai.numNetworkRequests() - nai.numRequestNetworkRequests(),
4538                     nai.numBackgroundNetworkRequests(),
4539                     nai.numNetworkRequests()));
4540             pw.increaseIndent();
4541             for (int i = 0; i < nai.numNetworkRequests(); i++) {
4542                 pw.println(nai.requestAt(i).toString());
4543             }
4544             pw.decreaseIndent();
4545             pw.println("Inactivity Timers:");
4546             pw.increaseIndent();
4547             nai.dumpInactivityTimers(pw);
4548             pw.decreaseIndent();
4549             pw.decreaseIndent();
4550         }
4551     }
4552 
4553     private void dumpNetworkPreferences(IndentingPrintWriter pw) {
4554         if (!mProfileNetworkPreferences.isEmpty()) {
4555             pw.println("Profile preferences:");
4556             pw.increaseIndent();
4557             pw.println(mProfileNetworkPreferences);
4558             pw.decreaseIndent();
4559         }
4560         if (!mOemNetworkPreferences.isEmpty()) {
4561             pw.println("OEM preferences:");
4562             pw.increaseIndent();
4563             pw.println(mOemNetworkPreferences);
4564             pw.decreaseIndent();
4565         }
4566         if (!mMobileDataPreferredUids.isEmpty()) {
4567             pw.println("Mobile data preferred UIDs:");
4568             pw.increaseIndent();
4569             pw.println(mMobileDataPreferredUids);
4570             pw.decreaseIndent();
4571         }
4572 
4573         pw.println("Default requests:");
4574         pw.increaseIndent();
4575         dumpPerAppDefaultRequests(pw);
4576         pw.decreaseIndent();
4577     }
4578 
4579     private void dumpPerAppDefaultRequests(IndentingPrintWriter pw) {
4580         for (final NetworkRequestInfo defaultRequest : mDefaultNetworkRequests) {
4581             if (mDefaultRequest == defaultRequest) {
4582                 continue;
4583             }
4584 
4585             final NetworkAgentInfo satisfier = defaultRequest.getSatisfier();
4586             final String networkOutput;
4587             if (null == satisfier) {
4588                 networkOutput = "null";
4589             } else if (mNoServiceNetwork.equals(satisfier)) {
4590                 networkOutput = "no service network";
4591             } else {
4592                 networkOutput = String.valueOf(satisfier.network.netId);
4593             }
4594             final String asUidString = (defaultRequest.mAsUid == defaultRequest.mUid)
4595                     ? "" : " asUid: " + defaultRequest.mAsUid;
4596             final String requestInfo = "Request: [uid/pid:" + defaultRequest.mUid + "/"
4597                     + defaultRequest.mPid + asUidString + "]";
4598             final String satisfierOutput = "Satisfier: [" + networkOutput + "]"
4599                     + " Preference order: " + defaultRequest.mPreferenceOrder
4600                     + " Tracked UIDs: " + defaultRequest.getUids();
4601             pw.println(requestInfo + " - " + satisfierOutput);
4602         }
4603     }
4604 
4605     private void dumpNetworkRequests(IndentingPrintWriter pw) {
4606         NetworkRequestInfo[] infos = null;
4607         while (infos == null) {
4608             try {
4609                 infos = requestsSortedById();
4610             } catch (ConcurrentModificationException e) {
4611                 // mNetworkRequests should only be accessed from handler thread, except dump().
4612                 // As dump() is never called in normal usage, it would be needlessly expensive
4613                 // to lock the collection only for its benefit. Instead, retry getting the
4614                 // requests if ConcurrentModificationException is thrown during dump().
4615             }
4616         }
4617         for (NetworkRequestInfo nri : infos) {
4618             pw.println(nri.toString());
4619         }
4620     }
4621 
4622     private void dumpTrafficController(IndentingPrintWriter pw, final FileDescriptor fd,
4623             boolean verbose) {
4624         try {
4625             mBpfNetMaps.dump(pw, fd, verbose);
4626         } catch (ServiceSpecificException e) {
4627             pw.println(e.getMessage());
4628         } catch (IOException e) {
4629             loge("Dump BPF maps failed, " + e);
4630         }
4631     }
4632 
4633     private void dumpClatBpfRawMap(IndentingPrintWriter pw, boolean isEgress4Map) {
4634         for (NetworkAgentInfo nai : networksSortedById()) {
4635             if (nai.clatd != null) {
4636                 nai.clatd.dumpRawBpfMap(pw, isEgress4Map);
4637                 break;
4638             }
4639         }
4640     }
4641 
4642     private void dumpAllRequestInfoLogsToLogcat() {
4643         try (PrintWriter logPw = new PrintWriter(new Writer() {
4644             @Override
4645             public void write(final char[] cbuf, final int off, final int len) {
4646                 // This method is called with 0-length and 1-length arrays for empty strings
4647                 // or strings containing only the DEL character.
4648                 if (len <= 1) return;
4649                 Log.e(TAG, new String(cbuf, off, len));
4650             }
4651             @Override public void flush() {}
4652             @Override public void close() {}
4653         })) {
4654             mNetworkRequestInfoLogs.dump(logPw);
4655         }
4656     }
4657 
4658     /**
4659      * Return an array of all current NetworkAgentInfos sorted by network id.
4660      */
4661     private NetworkAgentInfo[] networksSortedById() {
4662         NetworkAgentInfo[] networks = new NetworkAgentInfo[0];
4663         networks = mNetworkAgentInfos.toArray(networks);
4664         Arrays.sort(networks, Comparator.comparingInt(nai -> nai.network.getNetId()));
4665         return networks;
4666     }
4667 
4668     /**
4669      * Return an array of all current NetworkRequest sorted by request id.
4670      */
4671     @VisibleForTesting
4672     NetworkRequestInfo[] requestsSortedById() {
4673         NetworkRequestInfo[] requests = new NetworkRequestInfo[0];
4674         requests = getNrisFromGlobalRequests().toArray(requests);
4675         // Sort the array based off the NRI containing the min requestId in its requests.
4676         Arrays.sort(requests,
4677                 Comparator.comparingInt(nri -> Collections.min(nri.mRequests,
4678                         Comparator.comparingInt(req -> req.requestId)).requestId
4679                 )
4680         );
4681         return requests;
4682     }
4683 
4684     private boolean isLiveNetworkAgent(NetworkAgentInfo nai, int what) {
4685         final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network);
4686         if (officialNai != null && officialNai.equals(nai)) return true;
4687         if (officialNai != null || VDBG) {
4688             loge(eventName(what) + " - isLiveNetworkAgent found mismatched netId: " + officialNai +
4689                 " - " + nai);
4690         }
4691         return false;
4692     }
4693 
4694     private boolean isDisconnectRequest(Message msg) {
4695         if (msg.what != NetworkAgent.EVENT_NETWORK_INFO_CHANGED) return false;
4696         final NetworkInfo info = (NetworkInfo) ((Pair) msg.obj).second;
4697         return info.getState() == NetworkInfo.State.DISCONNECTED;
4698     }
4699 
4700     // must be stateless - things change under us.
4701     private class NetworkStateTrackerHandler extends Handler {
4702         public NetworkStateTrackerHandler(Looper looper) {
4703             super(looper);
4704         }
4705 
4706         private void maybeHandleNetworkAgentMessage(Message msg) {
4707             final Pair<NetworkAgentInfo, Object> arg = (Pair<NetworkAgentInfo, Object>) msg.obj;
4708             final NetworkAgentInfo nai = arg.first;
4709 
4710             // If the network has been destroyed, the only thing that it can do is disconnect.
4711             if (nai.isDestroyed() && !isDisconnectRequest(msg)) {
4712                 if (DBG) {
4713                     log("Message " + eventName(msg.what) + " from destroyed agent with netId "
4714                             + nai.network.netId);
4715                 }
4716                 return;
4717             }
4718 
4719             if (mQueueNetworkAgentEventsInSystemServer && nai.maybeEnqueueMessage(msg)) {
4720                 // If the message is enqueued, the NAI will replay it immediately
4721                 // when registration is complete. It does this by sending all the
4722                 // messages in the order received immediately after the
4723                 // EVENT_AGENT_REGISTERED message.
4724                 if (DBG) {
4725                     log("Message " + eventName(msg.what) + " enqueued for agent with netId "
4726                             + nai.network.netId);
4727                 }
4728                 return;
4729             }
4730 
4731             // If the nai has been registered (and doesn't enqueue), it should now be
4732             // in the list of NAIs.
4733             if (!mNetworkAgentInfos.contains(nai)) {
4734                 // TODO : this is supposed to be impossible
4735                 if (VDBG) {
4736                     log(String.format("%s from unknown NetworkAgent", eventName(msg.what)));
4737                 }
4738                 return;
4739             }
4740 
4741             switch (msg.what) {
4742                 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
4743                     final NetworkCapabilities proposed = (NetworkCapabilities) arg.second;
4744                     if (!nai.respectsNcStructuralConstraints(proposed)) {
4745                         Log.wtf(TAG, "Agent " + nai + " violates nc structural constraints : "
4746                                 + nai.networkCapabilities + " -> " + proposed);
4747                         disconnectAndDestroyNetwork(nai);
4748                         return;
4749                     }
4750                     nai.setDeclaredCapabilities(proposed);
4751                     final NetworkCapabilities sanitized =
4752                             nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator);
4753                     maybeUpdateWifiRoamTimestamp(nai, sanitized);
4754                     updateCapabilities(nai.getScore(), nai, sanitized);
4755                     break;
4756                 }
4757                 case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: {
4758                     LinkProperties newLp = (LinkProperties) arg.second;
4759                     processLinkPropertiesFromAgent(nai, newLp);
4760                     handleUpdateLinkProperties(nai, newLp);
4761                     break;
4762                 }
4763                 case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {
4764                     NetworkInfo info = (NetworkInfo) arg.second;
4765                     updateNetworkInfo(nai, info);
4766                     break;
4767                 }
4768                 case NetworkAgent.EVENT_LOCAL_NETWORK_CONFIG_CHANGED: {
4769                     final LocalNetworkConfig config = (LocalNetworkConfig) arg.second;
4770                     handleUpdateLocalNetworkConfig(nai, nai.localNetworkConfig, config);
4771                     break;
4772                 }
4773                 case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
4774                     updateNetworkScore(nai, (NetworkScore) arg.second);
4775                     break;
4776                 }
4777                 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
4778                     if (nai.everConnected()) {
4779                         loge("ERROR: cannot call explicitlySelected on already-connected network");
4780                         // Note that if the NAI had been connected, this would affect the
4781                         // score, and therefore would require re-mixing the score and performing
4782                         // a rematch.
4783                     }
4784                     nai.networkAgentConfig.explicitlySelected = toBool(msg.arg1);
4785                     nai.networkAgentConfig.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2);
4786                     // Mark the network as temporarily accepting partial connectivity so that it
4787                     // will be validated (and possibly become default) even if it only provides
4788                     // partial internet access. Note that if user connects to partial connectivity
4789                     // and choose "don't ask again", then wifi disconnected by some reasons(maybe
4790                     // out of wifi coverage) and if the same wifi is available again, the device
4791                     // will auto connect to this wifi even though the wifi has "no internet".
4792                     // TODO: Evaluate using a separate setting in IpMemoryStore.
4793                     nai.networkAgentConfig.acceptPartialConnectivity = toBool(msg.arg2);
4794                     break;
4795                 }
4796                 case NetworkAgent.EVENT_SOCKET_KEEPALIVE: {
4797                     mKeepaliveTracker.handleEventSocketKeepalive(nai, msg.arg1, msg.arg2);
4798                     break;
4799                 }
4800                 case NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED: {
4801                     // TODO: prevent loops, e.g., if a network declares itself as underlying.
4802                     final List<Network> underlying = (List<Network>) arg.second;
4803 
4804                     if (isLegacyLockdownNai(nai)
4805                             && (underlying == null || underlying.size() != 1)) {
4806                         Log.wtf(TAG, "Legacy lockdown VPN " + nai.toShortString()
4807                                 + " must have exactly one underlying network: " + underlying);
4808                     }
4809 
4810                     final Network[] oldUnderlying = nai.declaredUnderlyingNetworks;
4811                     nai.declaredUnderlyingNetworks = (underlying != null)
4812                             ? underlying.toArray(new Network[0]) : null;
4813 
4814                     if (!Arrays.equals(oldUnderlying, nai.declaredUnderlyingNetworks)) {
4815                         if (DBG) {
4816                             log(nai.toShortString() + " changed underlying networks to "
4817                                     + Arrays.toString(nai.declaredUnderlyingNetworks));
4818                         }
4819                         updateCapabilitiesForNetwork(nai);
4820                         notifyIfacesChangedForNetworkStats();
4821                     }
4822                     break;
4823                 }
4824                 case NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED: {
4825                     if (msg.arg1 >= 0 && msg.arg1 <= NetworkAgent.MAX_TEARDOWN_DELAY_MS) {
4826                         nai.teardownDelayMs = msg.arg1;
4827                     } else {
4828                         logwtf(nai.toShortString() + " set invalid teardown delay " + msg.arg1);
4829                     }
4830                     break;
4831                 }
4832                 case NetworkAgent.EVENT_LINGER_DURATION_CHANGED: {
4833                     nai.setLingerDuration((int) arg.second);
4834                     break;
4835                 }
4836                 case NetworkAgent.EVENT_ADD_DSCP_POLICY: {
4837                     DscpPolicy policy = (DscpPolicy) arg.second;
4838                     if (mDscpPolicyTracker != null) {
4839                         mDscpPolicyTracker.addDscpPolicy(nai, policy);
4840                     }
4841                     break;
4842                 }
4843                 case NetworkAgent.EVENT_REMOVE_DSCP_POLICY: {
4844                     if (mDscpPolicyTracker != null) {
4845                         mDscpPolicyTracker.removeDscpPolicy(nai, (int) arg.second);
4846                     }
4847                     break;
4848                 }
4849                 case NetworkAgent.EVENT_REMOVE_ALL_DSCP_POLICIES: {
4850                     if (mDscpPolicyTracker != null) {
4851                         mDscpPolicyTracker.removeAllDscpPolicies(nai, true);
4852                     }
4853                     break;
4854                 }
4855                 case NetworkAgent.EVENT_UNREGISTER_AFTER_REPLACEMENT: {
4856                     if (!nai.everConnected()) {
4857                         Log.d(TAG, "unregisterAfterReplacement on never-connected "
4858                                 + nai.toShortString() + ", tearing down instead");
4859                         teardownUnneededNetwork(nai);
4860                         break;
4861                     }
4862 
4863                     if (nai.isDestroyed()) {
4864                         Log.d(TAG, "unregisterAfterReplacement on destroyed " + nai.toShortString()
4865                                 + ", ignoring");
4866                         break;
4867                     }
4868 
4869                     final int timeoutMs = (int) arg.second;
4870                     if (timeoutMs < 0 || timeoutMs > NetworkAgent.MAX_TEARDOWN_DELAY_MS) {
4871                         Log.e(TAG, "Invalid network replacement timer " + timeoutMs
4872                                 + ", must be between 0 and " + NetworkAgent.MAX_TEARDOWN_DELAY_MS);
4873                     }
4874 
4875                     // Marking a network awaiting replacement is used to ensure that any requests
4876                     // satisfied by the network do not switch to another network until a
4877                     // replacement is available or the wait for a replacement times out.
4878                     // If the network is inactive (i.e., nascent or lingering), then there are no
4879                     // such requests, and there is no point keeping it. Just tear it down.
4880                     // Note that setLingerDuration(0) cannot be used to do this because the network
4881                     // could be nascent.
4882                     nai.clearInactivityState();
4883                     if (unneeded(nai, UnneededFor.TEARDOWN)) {
4884                         Log.d(TAG, nai.toShortString()
4885                                 + " marked awaiting replacement is unneeded, tearing down instead");
4886                         teardownUnneededNetwork(nai);
4887                         break;
4888                     }
4889 
4890                     Log.d(TAG, "Marking " + nai.toShortString()
4891                             + " destroyed, awaiting replacement within " + timeoutMs + "ms");
4892                     destroyNativeNetwork(nai);
4893 
4894                     // TODO: deduplicate this call with the one in disconnectAndDestroyNetwork.
4895                     // This is not trivial because KeepaliveTracker#handleStartKeepalive does not
4896                     // consider the fact that the network could already have disconnected or been
4897                     // destroyed. Fix the code to send ERROR_INVALID_NETWORK when this happens
4898                     // (taking care to ensure no dup'd FD leaks), then remove the code duplication
4899                     // and move this code to a sensible location (destroyNativeNetwork perhaps?).
4900                     mKeepaliveTracker.handleStopAllKeepalives(nai,
4901                             SocketKeepalive.ERROR_INVALID_NETWORK);
4902 
4903                     nai.updateScoreForNetworkAgentUpdate();
4904                     // This rematch is almost certainly not going to result in any changes, because
4905                     // the destroyed flag is only just above the "current satisfier wins"
4906                     // tie-breaker. But technically anything that affects scoring should rematch.
4907                     rematchAllNetworksAndRequests();
4908                     if (mQueueNetworkAgentEventsInSystemServer) {
4909                         mHandler.postDelayed(() -> disconnectAndDestroyNetwork(nai), timeoutMs);
4910                     } else {
4911                         mHandler.postDelayed(() -> nai.disconnect(), timeoutMs);
4912                     }
4913                     break;
4914                 }
4915             }
4916         }
4917 
4918         private boolean maybeHandleNetworkMonitorMessage(Message msg) {
4919             final int netId = msg.arg2;
4920             final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
4921             // If a network has already been destroyed, all NetworkMonitor updates are ignored.
4922             if (nai != null && nai.isDestroyed()) return true;
4923             switch (msg.what) {
4924                 default:
4925                     return false;
4926                 case EVENT_PROBE_STATUS_CHANGED: {
4927                     if (nai == null) {
4928                         break;
4929                     }
4930                     final int probesCompleted = ((Pair<Integer, Integer>) msg.obj).first;
4931                     final int probesSucceeded = ((Pair<Integer, Integer>) msg.obj).second;
4932                     final boolean probePrivateDnsCompleted =
4933                             ((probesCompleted & NETWORK_VALIDATION_PROBE_PRIVDNS) != 0);
4934                     final boolean privateDnsBroken =
4935                             ((probesSucceeded & NETWORK_VALIDATION_PROBE_PRIVDNS) == 0);
4936                     if (probePrivateDnsCompleted) {
4937                         if (nai.networkCapabilities.isPrivateDnsBroken() != privateDnsBroken) {
4938                             nai.networkCapabilities.setPrivateDnsBroken(privateDnsBroken);
4939                             updateCapabilitiesForNetwork(nai);
4940                         }
4941                         // Only show the notification when the private DNS is broken and the
4942                         // PRIVATE_DNS_BROKEN notification hasn't shown since last valid.
4943                         if (privateDnsBroken && !nai.networkAgentConfig.hasShownBroken) {
4944                             showNetworkNotification(nai, NotificationType.PRIVATE_DNS_BROKEN);
4945                         }
4946                         nai.networkAgentConfig.hasShownBroken = privateDnsBroken;
4947                     } else if (nai.networkCapabilities.isPrivateDnsBroken()) {
4948                         // If probePrivateDnsCompleted is false but nai.networkCapabilities says
4949                         // private DNS is broken, it means this network is being reevaluated.
4950                         // Either probing private DNS is not necessary any more or it hasn't been
4951                         // done yet. In either case, the networkCapabilities should be updated to
4952                         // reflect the new status.
4953                         nai.networkCapabilities.setPrivateDnsBroken(false);
4954                         updateCapabilitiesForNetwork(nai);
4955                         nai.networkAgentConfig.hasShownBroken = false;
4956                     }
4957                     break;
4958                 }
4959                 case EVENT_NETWORK_TESTED: {
4960                     final NetworkTestedResults results = (NetworkTestedResults) msg.obj;
4961 
4962                     if (nai == null) break;
4963 
4964                     handleNetworkTested(nai, results.mTestResult,
4965                             (results.mRedirectUrl == null) ? "" : results.mRedirectUrl);
4966                     break;
4967                 }
4968                 case EVENT_PROVISIONING_NOTIFICATION: {
4969                     final boolean visible = toBool(msg.arg1);
4970                     // If captive portal status has changed, update capabilities or disconnect.
4971                     if (!visible) {
4972                         // Only clear SIGN_IN and NETWORK_SWITCH notifications here, or else other
4973                         // notifications belong to the same network may be cleared unexpectedly.
4974                         mNotifier.clearNotification(netId, NotificationType.SIGN_IN);
4975                         mNotifier.clearNotification(netId, NotificationType.NETWORK_SWITCH);
4976                     } else {
4977                         if (nai == null) {
4978                             loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
4979                             break;
4980                         }
4981                         if (!nai.networkAgentConfig.provisioningNotificationDisabled) {
4982                             mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai, null,
4983                                     (PendingIntent) msg.obj,
4984                                     nai.networkAgentConfig.explicitlySelected);
4985                         }
4986                     }
4987                     break;
4988                 }
4989                 case EVENT_PRIVATE_DNS_CONFIG_RESOLVED: {
4990                     if (nai == null) break;
4991 
4992                     updatePrivateDns(nai, (PrivateDnsConfig) msg.obj);
4993                     break;
4994                 }
4995                 case EVENT_CAPPORT_DATA_CHANGED: {
4996                     if (nai == null) break;
4997                     handleCapportApiDataUpdate(nai, (CaptivePortalData) msg.obj);
4998                     break;
4999                 }
5000             }
5001             return true;
5002         }
5003 
5004         private void handleNetworkTested(
5005                 @NonNull NetworkAgentInfo nai, int testResult, @NonNull String redirectUrl) {
5006             final boolean valid = (testResult & NETWORK_VALIDATION_RESULT_VALID) != 0;
5007             final boolean partial = (testResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0;
5008             final boolean portal = !TextUtils.isEmpty(redirectUrl);
5009 
5010             // If there is any kind of working networking, then the NAI has been evaluated
5011             // once. {@see NetworkAgentInfo#setEvaluated}, which returns whether this is
5012             // the first time this ever happened.
5013             final boolean someConnectivity = (valid || partial || portal);
5014             final boolean becameEvaluated = someConnectivity && nai.setEvaluated();
5015             // Because of b/245893397, if the score is updated when updateCapabilities is called,
5016             // any callback that receives onAvailable for that rematch receives an extra caps
5017             // callback. To prevent that, update the score in the agent so the updates below won't
5018             // see an update to both caps and score at the same time.
5019             // TODO : fix b/245893397 and remove this.
5020             if (becameEvaluated) nai.updateScoreForNetworkAgentUpdate();
5021 
5022             if (!valid && shouldIgnoreValidationFailureAfterRoam(nai)) {
5023                 // Assume the validation failure is due to a temporary failure after roaming
5024                 // and ignore it. NetworkMonitor will continue to retry validation. If it
5025                 // continues to fail after the block timeout expires, the network will be
5026                 // marked unvalidated. If it succeeds, then validation state will not change.
5027                 return;
5028             }
5029 
5030             final boolean wasValidated = nai.isValidated();
5031             final boolean wasPartial = nai.partialConnectivity();
5032             final boolean wasPortal = nai.captivePortalDetected();
5033             nai.setPartialConnectivity(partial);
5034             nai.setCaptivePortalDetected(portal);
5035             nai.updateScoreForNetworkAgentUpdate();
5036             final boolean partialConnectivityChanged = (wasPartial != partial);
5037             final boolean portalChanged = (wasPortal != portal);
5038 
5039             if (DBG) {
5040                 final String logMsg = !TextUtils.isEmpty(redirectUrl)
5041                         ? " with redirect to " + redirectUrl
5042                         : "";
5043                 final String statusMsg;
5044                 if (valid) {
5045                     statusMsg = "passed";
5046                 } else if (!TextUtils.isEmpty(redirectUrl)) {
5047                     statusMsg = "detected a portal";
5048                 } else {
5049                     statusMsg = "failed";
5050                 }
5051                 log(nai.toShortString() + " validation " + statusMsg + logMsg);
5052             }
5053             if (valid != wasValidated) {
5054                 final FullScore oldScore = nai.getScore();
5055                 nai.setValidated(valid);
5056                 updateCapabilities(oldScore, nai, nai.networkCapabilities);
5057                 if (valid) {
5058                     handleFreshlyValidatedNetwork(nai);
5059                     // Clear NO_INTERNET, PRIVATE_DNS_BROKEN, PARTIAL_CONNECTIVITY and
5060                     // LOST_INTERNET notifications if network becomes valid.
5061                     mNotifier.clearNotification(nai.network.getNetId(),
5062                             NotificationType.NO_INTERNET);
5063                     mNotifier.clearNotification(nai.network.getNetId(),
5064                             NotificationType.LOST_INTERNET);
5065                     mNotifier.clearNotification(nai.network.getNetId(),
5066                             NotificationType.PARTIAL_CONNECTIVITY);
5067                     mNotifier.clearNotification(nai.network.getNetId(),
5068                             NotificationType.PRIVATE_DNS_BROKEN);
5069                     // If network becomes valid, the hasShownBroken should be reset for
5070                     // that network so that the notification will be fired when the private
5071                     // DNS is broken again.
5072                     nai.networkAgentConfig.hasShownBroken = false;
5073                 }
5074             } else if (partialConnectivityChanged) {
5075                 updateCapabilitiesForNetwork(nai);
5076             } else if (portalChanged) {
5077                 if (portal && ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID
5078                         == getCaptivePortalMode(nai)) {
5079                     if (DBG) log("Avoiding captive portal network: " + nai.toShortString());
5080                     nai.onPreventAutomaticReconnect();
5081                     teardownUnneededNetwork(nai);
5082                     return;
5083                 } else {
5084                     updateCapabilitiesForNetwork(nai);
5085                 }
5086             } else if (becameEvaluated) {
5087                 // If valid or partial connectivity changed, updateCapabilities* has
5088                 // done the rematch.
5089                 rematchAllNetworksAndRequests();
5090             }
5091             updateInetCondition(nai);
5092 
5093             // Let the NetworkAgent know the state of its network
5094             // TODO: Evaluate to update partial connectivity to status to NetworkAgent.
5095             nai.onValidationStatusChanged(
5096                     valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK,
5097                     redirectUrl);
5098 
5099             // If NetworkMonitor detects partial connectivity before
5100             // EVENT_INITIAL_EVALUATION_TIMEOUT arrives, show the partial connectivity notification
5101             // immediately. Re-notify partial connectivity silently if no internet
5102             // notification already there.
5103             if (!wasPartial && nai.partialConnectivity()) {
5104                 // Remove delayed message if there is a pending message.
5105                 mHandler.removeMessages(EVENT_INITIAL_EVALUATION_TIMEOUT, nai.network);
5106                 handleInitialEvaluationTimeout(nai.network);
5107             }
5108 
5109             if (wasValidated && !nai.isValidated()) {
5110                 handleNetworkUnvalidated(nai);
5111             }
5112         }
5113 
5114         private int getCaptivePortalMode(@NonNull NetworkAgentInfo nai) {
5115             if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) &&
5116                     mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH)) {
5117                 // Do not avoid captive portal when network is wear proxy.
5118                 return ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT;
5119             }
5120 
5121             return Settings.Global.getInt(mContext.getContentResolver(),
5122                     ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE,
5123                     ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT);
5124         }
5125 
5126         private boolean maybeHandleNetworkAgentInfoMessage(Message msg) {
5127             switch (msg.what) {
5128                 default:
5129                     return false;
5130                 case NetworkAgentInfo.EVENT_NETWORK_LINGER_COMPLETE: {
5131                     NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
5132                     if (nai != null && isLiveNetworkAgent(nai, msg.what)) {
5133                         handleLingerComplete(nai);
5134                     }
5135                     break;
5136                 }
5137                 case NetworkAgentInfo.EVENT_AGENT_REGISTERED: {
5138                     handleNetworkAgentRegistered(msg);
5139                     break;
5140                 }
5141                 case NetworkAgentInfo.EVENT_AGENT_DISCONNECTED: {
5142                     handleNetworkAgentDisconnected(msg);
5143                     break;
5144                 }
5145             }
5146             return true;
5147         }
5148 
5149         @Override
5150         public void handleMessage(@NonNull Message msg) {
5151             if (!maybeHandleNetworkMonitorMessage(msg)
5152                     && !maybeHandleNetworkAgentInfoMessage(msg)) {
5153                 maybeHandleNetworkAgentMessage(msg);
5154             }
5155         }
5156     }
5157 
5158     private class NetworkMonitorCallbacks extends INetworkMonitorCallbacks.Stub {
5159         private final int mNetId;
5160         private final AutodestructReference<NetworkAgentInfo> mNai;
5161 
5162         private NetworkMonitorCallbacks(NetworkAgentInfo nai) {
5163             mNetId = nai.network.getNetId();
5164             mNai = new AutodestructReference<>(nai);
5165         }
5166 
5167         @Override
5168         public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) {
5169             mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT,
5170                     new Pair<>(mNai.getAndDestroy(), networkMonitor)));
5171         }
5172 
5173         @Override
5174         public void notifyNetworkTested(int testResult, @Nullable String redirectUrl) {
5175             // Legacy version of notifyNetworkTestedWithExtras.
5176             // Would only be called if the system has a NetworkStack module older than the
5177             // framework, which does not happen in practice.
5178             Log.wtf(TAG, "Deprecated notifyNetworkTested called: no action taken");
5179         }
5180 
5181         @Override
5182         public void notifyNetworkTestedWithExtras(NetworkTestResultParcelable p) {
5183             // Notify mTrackerHandler and mConnectivityDiagnosticsHandler of the event. Both use
5184             // the same looper so messages will be processed in sequence.
5185             final Message msg = mTrackerHandler.obtainMessage(
5186                     EVENT_NETWORK_TESTED,
5187                     0, mNetId,
5188                     new NetworkTestedResults(
5189                             mNetId, p.result, p.timestampMillis, p.redirectUrl));
5190             mTrackerHandler.sendMessage(msg);
5191 
5192             // Invoke ConnectivityReport generation for this Network test event.
5193             final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(mNetId);
5194             if (nai == null) return;
5195 
5196             // NetworkMonitor reports the network validation result as a bitmask while
5197             // ConnectivityDiagnostics treats this value as an int. Convert the result to a single
5198             // logical value for ConnectivityDiagnostics.
5199             final int validationResult = networkMonitorValidationResultToConnDiagsValidationResult(
5200                     p.result);
5201 
5202             final PersistableBundle extras = new PersistableBundle();
5203             extras.putInt(KEY_NETWORK_VALIDATION_RESULT, validationResult);
5204             extras.putInt(KEY_NETWORK_PROBES_SUCCEEDED_BITMASK, p.probesSucceeded);
5205             extras.putInt(KEY_NETWORK_PROBES_ATTEMPTED_BITMASK, p.probesAttempted);
5206 
5207             ConnectivityReportEvent reportEvent =
5208                     new ConnectivityReportEvent(p.timestampMillis, nai, extras);
5209             final Message m = mConnectivityDiagnosticsHandler.obtainMessage(
5210                     ConnectivityDiagnosticsHandler.CMD_SEND_CONNECTIVITY_REPORT, reportEvent);
5211             mConnectivityDiagnosticsHandler.sendMessage(m);
5212         }
5213 
5214         @Override
5215         public void notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config) {
5216             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
5217                     EVENT_PRIVATE_DNS_CONFIG_RESOLVED,
5218                     0, mNetId, PrivateDnsConfig.fromParcel(config)));
5219         }
5220 
5221         @Override
5222         public void notifyProbeStatusChanged(int probesCompleted, int probesSucceeded) {
5223             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
5224                     EVENT_PROBE_STATUS_CHANGED,
5225                     0, mNetId, new Pair<>(probesCompleted, probesSucceeded)));
5226         }
5227 
5228         @Override
5229         public void notifyCaptivePortalDataChanged(CaptivePortalData data) {
5230             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
5231                     EVENT_CAPPORT_DATA_CHANGED,
5232                     0, mNetId, data));
5233         }
5234 
5235         @Override
5236         public void showProvisioningNotification(String action, String packageName) {
5237             final Intent intent = new Intent(action);
5238             intent.setPackage(packageName);
5239 
5240             final PendingIntent pendingIntent;
5241             // Only the system server can register notifications with package "android"
5242             final long token = Binder.clearCallingIdentity();
5243             try {
5244                 pendingIntent = PendingIntent.getBroadcast(
5245                         mContext,
5246                         0 /* requestCode */,
5247                         intent,
5248                         PendingIntent.FLAG_IMMUTABLE);
5249             } finally {
5250                 Binder.restoreCallingIdentity(token);
5251             }
5252             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
5253                     EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_SHOW,
5254                     mNetId, pendingIntent));
5255         }
5256 
5257         @Override
5258         public void hideProvisioningNotification() {
5259             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
5260                     EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId));
5261         }
5262 
5263         @Override
5264         public void notifyDataStallSuspected(DataStallReportParcelable p) {
5265             ConnectivityService.this.notifyDataStallSuspected(p, mNetId);
5266         }
5267 
5268         @Override
5269         public int getInterfaceVersion() {
5270             return this.VERSION;
5271         }
5272 
5273         @Override
5274         public String getInterfaceHash() {
5275             return this.HASH;
5276         }
5277     }
5278 
5279     /**
5280      * Converts the given NetworkMonitor-specific validation result bitmask to a
5281      * ConnectivityDiagnostics-specific validation result int.
5282      */
5283     private int networkMonitorValidationResultToConnDiagsValidationResult(int validationResult) {
5284         if ((validationResult & NETWORK_VALIDATION_RESULT_SKIPPED) != 0) {
5285             return ConnectivityReport.NETWORK_VALIDATION_RESULT_SKIPPED;
5286         }
5287         if ((validationResult & NETWORK_VALIDATION_RESULT_VALID) == 0) {
5288             return ConnectivityReport.NETWORK_VALIDATION_RESULT_INVALID;
5289         }
5290         return (validationResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0
5291                 ? ConnectivityReport.NETWORK_VALIDATION_RESULT_PARTIALLY_VALID
5292                 : ConnectivityReport.NETWORK_VALIDATION_RESULT_VALID;
5293     }
5294 
5295     private void notifyDataStallSuspected(DataStallReportParcelable p, int netId) {
5296         log("Data stall detected with methods: " + p.detectionMethod);
5297 
5298         final PersistableBundle extras = new PersistableBundle();
5299         int detectionMethod = 0;
5300         if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) {
5301             extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts);
5302             detectionMethod |= DETECTION_METHOD_DNS_EVENTS;
5303         }
5304         if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) {
5305             extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate);
5306             extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS,
5307                     p.tcpMetricsCollectionPeriodMillis);
5308             detectionMethod |= DETECTION_METHOD_TCP_METRICS;
5309         }
5310 
5311         final Message msg = mConnectivityDiagnosticsHandler.obtainMessage(
5312                 ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, detectionMethod, netId,
5313                 new Pair<>(p.timestampMillis, extras));
5314 
5315         // NetworkStateTrackerHandler currently doesn't take any actions based on data
5316         // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid
5317         // the cost of going through two handlers.
5318         mConnectivityDiagnosticsHandler.sendMessage(msg);
5319     }
5320 
5321     private boolean hasDataStallDetectionMethod(DataStallReportParcelable p, int detectionMethod) {
5322         return (p.detectionMethod & detectionMethod) != 0;
5323     }
5324 
5325     private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) {
5326         return isPrivateDnsValidationRequired(nai.networkCapabilities);
5327     }
5328 
5329     private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) {
5330         if (nai == null) return;
5331         // If the Private DNS mode is opportunistic, reprogram the DNS servers
5332         // in order to restart a validation pass from within netd.
5333         final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
5334         if (cfg.inOpportunisticMode()) {
5335             updateDnses(nai.linkProperties, null, nai.network.getNetId());
5336         }
5337     }
5338 
5339     private void handlePrivateDnsSettingsChanged() {
5340         final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
5341 
5342         forEachNetworkAgentInfo(nai -> {
5343             handlePerNetworkPrivateDnsConfig(nai, cfg);
5344             if (networkRequiresPrivateDnsValidation(nai)) {
5345                 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
5346             }
5347         });
5348     }
5349 
5350     private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) {
5351         // Private DNS only ever applies to networks that might provide
5352         // Internet access and therefore also require validation.
5353         if (!networkRequiresPrivateDnsValidation(nai)) return;
5354 
5355         // Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or
5356         // schedule DNS resolutions. If a DNS resolution is required the
5357         // result will be sent back to us.
5358         nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel());
5359 
5360         // With Private DNS bypass support, we can proceed to update the
5361         // Private DNS config immediately, even if we're in strict mode
5362         // and have not yet resolved the provider name into a set of IPs.
5363         updatePrivateDns(nai, cfg);
5364     }
5365 
5366     private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) {
5367         mDnsManager.updatePrivateDns(nai.network, newCfg);
5368         updateDnses(nai.linkProperties, null, nai.network.getNetId());
5369     }
5370 
5371     private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) {
5372         NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId);
5373         if (nai == null) {
5374             return;
5375         }
5376         mDnsManager.updatePrivateDnsValidation(update);
5377         handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
5378     }
5379 
5380     private void handleNat64PrefixEvent(int netId, int operation, String prefixAddress,
5381             int prefixLength) {
5382         NetworkAgentInfo nai = mNetworkForNetId.get(netId);
5383         if (nai == null) return;
5384 
5385         log(String.format("NAT64 prefix changed on netId %d: operation=%d, %s/%d",
5386                 netId, operation, prefixAddress, prefixLength));
5387 
5388         IpPrefix prefix = null;
5389         if (operation == IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED) {
5390             try {
5391                 prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixAddress),
5392                         prefixLength);
5393             } catch (IllegalArgumentException e) {
5394                 loge("Invalid NAT64 prefix " + prefixAddress + "/" + prefixLength);
5395                 return;
5396             }
5397         }
5398 
5399         nai.clatd.setNat64PrefixFromDns(prefix);
5400         handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
5401     }
5402 
5403     private void handleCapportApiDataUpdate(@NonNull final NetworkAgentInfo nai,
5404             @Nullable final CaptivePortalData data) {
5405         nai.capportApiData = data;
5406         // CaptivePortalData will be merged into LinkProperties from NetworkAgentInfo
5407         handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
5408     }
5409 
5410     /**
5411      * Updates the inactivity state from the network requests inside the NAI.
5412      * @param nai the agent info to update
5413      * @param now the timestamp of the event causing this update
5414      * @return whether the network was inactive as a result of this update
5415      */
5416     private boolean updateInactivityState(@NonNull final NetworkAgentInfo nai, final long now) {
5417         // 1. Update the inactivity timer. If it's changed, reschedule or cancel the alarm.
5418         // 2. If the network was inactive and there are now requests, unset inactive.
5419         // 3. If this network is unneeded (which implies it is not lingering), and there is at least
5420         //    one lingered request, set inactive.
5421         nai.updateInactivityTimer();
5422         if (nai.isInactive() && nai.numForegroundNetworkRequests() > 0) {
5423             if (DBG) log("Unsetting inactive " + nai.toShortString());
5424             nai.unsetInactive();
5425             logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER);
5426         } else if (unneeded(nai, UnneededFor.LINGER) && nai.getInactivityExpiry() > 0) {
5427             if (DBG) {
5428                 final int lingerTime = (int) (nai.getInactivityExpiry() - now);
5429                 log("Setting inactive " + nai.toShortString() + " for " + lingerTime + "ms");
5430             }
5431             nai.setInactive();
5432             logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER);
5433             return true;
5434         }
5435         return false;
5436     }
5437 
5438     private void handleNetworkAgentRegistered(Message msg) {
5439         final NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
5440         if (!mNetworkAgentInfos.contains(nai)) {
5441             return;
5442         }
5443 
5444         if (msg.arg1 == NetworkAgentInfo.ARG_AGENT_SUCCESS) {
5445             if (VDBG) log("NetworkAgent registered");
5446         } else {
5447             loge("Error connecting NetworkAgent");
5448             mNetworkAgentInfos.remove(nai);
5449             if (nai != null) {
5450                 final boolean wasDefault = isDefaultNetwork(nai);
5451                 synchronized (mNetworkForNetId) {
5452                     mNetworkForNetId.remove(nai.network.getNetId());
5453                 }
5454                 mNetIdManager.releaseNetId(nai.network.getNetId());
5455                 // Just in case.
5456                 mLegacyTypeTracker.remove(nai, wasDefault);
5457             }
5458         }
5459     }
5460 
5461     @VisibleForTesting
5462     protected boolean shouldCreateNetworksImmediately(@NonNull NetworkCapabilities caps) {
5463         // The feature of creating the networks immediately was slated for U, but race conditions
5464         // detected late required this was flagged off.
5465         // TODO : remove when it's determined that the code is stable
5466         return mQueueNetworkAgentEventsInSystemServer
5467                 // Local network agents for Thread used to not create networks immediately,
5468                 // but other local agents (tethering, P2P) require this to function.
5469                 || (caps.hasCapability(NET_CAPABILITY_LOCAL_NETWORK)
5470                 && !caps.hasTransport(TRANSPORT_THREAD));
5471     }
5472 
5473     private boolean shouldCreateNativeNetwork(@NonNull NetworkAgentInfo nai,
5474             @NonNull NetworkInfo.State state) {
5475         if (nai.isCreated()) return false;
5476         if (state == NetworkInfo.State.CONNECTED) return true;
5477         if (state != NetworkInfo.State.CONNECTING) {
5478             // TODO: throw if no WTFs are observed in the field.
5479             if (shouldCreateNetworksImmediately(nai.getCapsNoCopy())) {
5480                 Log.wtf(TAG, "Uncreated network in invalid state: " + state);
5481             }
5482             return false;
5483         }
5484         return nai.isVPN() || shouldCreateNetworksImmediately(nai.getCapsNoCopy());
5485     }
5486 
5487     private static boolean shouldDestroyNativeNetwork(@NonNull NetworkAgentInfo nai) {
5488         return nai.isCreated() && !nai.isDestroyed();
5489     }
5490 
5491     @VisibleForTesting
5492     boolean shouldIgnoreValidationFailureAfterRoam(NetworkAgentInfo nai) {
5493         // T+ devices should use unregisterAfterReplacement.
5494         if (mDeps.isAtLeastT()) return false;
5495 
5496         // If the network never roamed, return false. The check below is not sufficient if time
5497         // since boot is less than blockTimeOut, though that's extremely unlikely to happen.
5498         if (nai.lastRoamTime == 0) return false;
5499 
5500         final long blockTimeOut = Long.valueOf(mResources.get().getInteger(
5501                 R.integer.config_validationFailureAfterRoamIgnoreTimeMillis));
5502         if (blockTimeOut <= MAX_VALIDATION_IGNORE_AFTER_ROAM_TIME_MS
5503                 && blockTimeOut >= 0) {
5504             final long currentTimeMs = SystemClock.elapsedRealtime();
5505             long timeSinceLastRoam = currentTimeMs - nai.lastRoamTime;
5506             if (timeSinceLastRoam <= blockTimeOut) {
5507                 log ("blocked because only " + timeSinceLastRoam + "ms after roam");
5508                 return true;
5509             }
5510         }
5511         return false;
5512     }
5513 
5514     private void handleNetworkAgentDisconnected(Message msg) {
5515         NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
5516         disconnectAndDestroyNetwork(nai);
5517     }
5518 
5519     // Destroys a network, remove references to it from the internal state managed by
5520     // ConnectivityService, free its interfaces and clean up.
5521     // Must be called on the Handler thread.
5522     private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) {
5523         ensureRunningOnConnectivityServiceThread();
5524 
5525         if (!mNetworkAgentInfos.contains(nai)) return;
5526 
5527         if (DBG) {
5528             log(nai.toShortString() + " disconnected, was satisfying " + nai.numNetworkRequests());
5529         }
5530 
5531         if (mQueueNetworkAgentEventsInSystemServer) {
5532             nai.disconnect();
5533         }
5534 
5535         // Clear all notifications of this network.
5536         mNotifier.clearNotification(nai.network.getNetId());
5537         // A network agent has disconnected.
5538         // TODO - if we move the logic to the network agent (have them disconnect
5539         // because they lost all their requests or because their score isn't good)
5540         // then they would disconnect organically, report their new state and then
5541         // disconnect the channel.
5542         if (nai.networkInfo.isConnected() || nai.networkInfo.isSuspended()) {
5543             nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
5544                     null, null);
5545         }
5546         final boolean wasDefault = isDefaultNetwork(nai);
5547         if (wasDefault) {
5548             mDefaultInetConditionPublished = 0;
5549         }
5550         if (mTrackMultiNetworkActivities) {
5551             // If trackMultiNetworkActivities is disabled, ActivityTracker removes idleTimer when
5552             // the network becomes no longer the default network.
5553             mNetworkActivityTracker.removeDataActivityTracking(nai);
5554         }
5555         notifyIfacesChangedForNetworkStats();
5556         // If this was a local network forwarded to some upstream, or if some local network was
5557         // forwarded to this nai, then disable forwarding rules now.
5558         maybeDisableForwardRulesForDisconnectingNai(nai, true /* sendCallbacks */);
5559         // If this is a local network with an upstream selector, remove the associated network
5560         // request.
5561         if (nai.isLocalNetwork()) {
5562             final NetworkRequest selector = nai.localNetworkConfig.getUpstreamSelector();
5563             if (null != selector) {
5564                 handleRemoveNetworkRequest(mNetworkRequests.get(selector));
5565             }
5566         }
5567         // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
5568         // by other networks that are already connected. Perhaps that can be done by
5569         // sending all CALLBACK_LOST messages (for requests, not listens) at the end
5570         // of rematchAllNetworksAndRequests
5571         notifyNetworkCallbacks(nai, CALLBACK_LOST);
5572         mKeepaliveTracker.handleStopAllKeepalives(nai, SocketKeepalive.ERROR_INVALID_NETWORK);
5573 
5574         mQosCallbackTracker.handleNetworkReleased(nai.network);
5575         for (String iface : nai.linkProperties.getAllInterfaceNames()) {
5576             // Disable wakeup packet monitoring for each interface.
5577             wakeupModifyInterface(iface, nai, false);
5578         }
5579         nai.networkMonitor().notifyNetworkDisconnected();
5580         mNetworkAgentInfos.remove(nai);
5581         nai.clatd.update();
5582         synchronized (mNetworkForNetId) {
5583             // Remove the NetworkAgent, but don't mark the netId as
5584             // available until we've told netd to delete it below.
5585             mNetworkForNetId.remove(nai.network.getNetId());
5586         }
5587         propagateUnderlyingNetworkCapabilities(nai.network);
5588         // Update allowed network lists in netd. This should be called after removing nai
5589         // from mNetworkAgentInfos.
5590         updateProfileAllowedNetworks();
5591         // Remove all previously satisfied requests.
5592         for (int i = 0; i < nai.numNetworkRequests(); i++) {
5593             final NetworkRequest request = nai.requestAt(i);
5594             final NetworkRequestInfo nri = mNetworkRequests.get(request);
5595             final NetworkAgentInfo currentNetwork = nri.getSatisfier();
5596             if (currentNetwork != null
5597                     && currentNetwork.network.getNetId() == nai.network.getNetId()) {
5598                 // uid rules for this network will be removed in destroyNativeNetwork(nai).
5599                 // TODO : setting the satisfier is in fact the job of the rematch. Teach the
5600                 // rematch not to keep disconnected agents instead of setting it here ; this
5601                 // will also allow removing updating the offers below.
5602                 nri.setSatisfier(null, null);
5603                 for (final NetworkOfferInfo noi : mNetworkOffers) {
5604                     informOffer(nri, noi.offer, mNetworkRanker);
5605                 }
5606 
5607                 if (mDefaultRequest == nri) {
5608                     mNetworkActivityTracker.updateDefaultNetwork(null /* newNetwork */, nai);
5609                     maybeDestroyPendingSockets(null /* newNetwork */, nai);
5610                     ensureNetworkTransitionWakelock(nai.toShortString());
5611                 }
5612             }
5613         }
5614         nai.clearInactivityState();
5615         // TODO: mLegacyTypeTracker.remove seems redundant given there's a full rematch right after.
5616         //  Currently, deleting it breaks tests that check for the default network disconnecting.
5617         //  Find out why, fix the rematch code, and delete this.
5618         mLegacyTypeTracker.remove(nai, wasDefault);
5619         rematchAllNetworksAndRequests();
5620         mLingerMonitor.noteDisconnect(nai);
5621 
5622         if (null == getDefaultNetwork() && nai.linkProperties.getHttpProxy() != null) {
5623             // The obvious place to do this would be in makeDefault(), however makeDefault() is
5624             // not called by the rematch in this case. This is because the code above unset
5625             // this network from the default request's satisfier, and that is what the rematch
5626             // is using as its source data to know what the old satisfier was. So as far as the
5627             // rematch above is concerned, the old default network was null.
5628             // Therefore if there is no new default, the default network was null and is still
5629             // null, thus there was no change so makeDefault() is not called. So if the old
5630             // network had a proxy and there is no new default, the proxy tracker should be told
5631             // that there is no longer a default proxy.
5632             // Strictly speaking this is not essential because having a proxy setting when
5633             // there is no network is harmless, but it's still counter-intuitive so reset to null.
5634             mProxyTracker.setDefaultProxy(null);
5635         }
5636 
5637         // Immediate teardown.
5638         if (nai.teardownDelayMs == 0) {
5639             destroyNetwork(nai);
5640             return;
5641         }
5642 
5643         // Delayed teardown.
5644         if (nai.isCreated() && !nai.isDestroyed()) {
5645             try {
5646                 mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM);
5647             } catch (RemoteException e) {
5648                 Log.d(TAG, "Error marking network restricted during teardown: ", e);
5649             }
5650         }
5651         mHandler.postDelayed(() -> destroyNetwork(nai), nai.teardownDelayMs);
5652     }
5653 
5654     private void destroyNetwork(NetworkAgentInfo nai) {
5655         if (shouldDestroyNativeNetwork(nai)) {
5656             // Tell netd to clean up the configuration for this network
5657             // (routing rules, DNS, etc).
5658             // This may be slow as it requires a lot of netd shelling out to ip and
5659             // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it
5660             // after we've rematched networks with requests (which might change the default
5661             // network or service a new request from an app), so network traffic isn't interrupted
5662             // for an unnecessarily long time.
5663             destroyNativeNetwork(nai);
5664         }
5665         if (!nai.isCreated() && !mDeps.isAtLeastT()) {
5666             // Backwards compatibility: send onNetworkDestroyed even if network was never created.
5667             // This can never run if the code above runs because shouldDestroyNativeNetwork is
5668             // false if the network was never created.
5669             // TODO: delete when S is no longer supported.
5670             nai.onNetworkDestroyed();
5671         }
5672         mNetIdManager.releaseNetId(nai.network.getNetId());
5673     }
5674 
5675     private void maybeDisableForwardRulesForDisconnectingNai(
5676             @NonNull final NetworkAgentInfo disconnecting, final boolean sendCallbacks) {
5677         // Step 1 : maybe this network was the upstream for one or more local networks.
5678         forEachNetworkAgentInfo(local -> {
5679             if (!local.isLocalNetwork()) return; // return@forEach
5680             final NetworkRequest selector = local.localNetworkConfig.getUpstreamSelector();
5681             if (null == selector) return; // return@forEach
5682             final NetworkRequestInfo nri = mNetworkRequests.get(selector);
5683             // null == nri can happen while disconnecting a network, because destroyNetwork() is
5684             // called after removing all associated NRIs from mNetworkRequests.
5685             if (null == nri) return; // return@forEach
5686             final NetworkAgentInfo satisfier = nri.getSatisfier();
5687             if (disconnecting != satisfier) return; // return@forEach
5688             removeLocalNetworkUpstream(local, disconnecting);
5689             // Set the satisfier to null immediately so that the LOCAL_NETWORK_CHANGED callback
5690             // correctly contains null as an upstream.
5691             if (sendCallbacks) {
5692                 nri.setSatisfier(null, null);
5693                 notifyNetworkCallbacks(local, CALLBACK_LOCAL_NETWORK_INFO_CHANGED);
5694             }
5695         });
5696 
5697         // Step 2 : maybe this is a local network that had an upstream.
5698         if (!disconnecting.isLocalNetwork()) return;
5699         final NetworkRequest selector = disconnecting.localNetworkConfig.getUpstreamSelector();
5700         if (null == selector) return;
5701         final NetworkRequestInfo nri = mNetworkRequests.get(selector);
5702         // As above null == nri can happen while disconnecting a network, because destroyNetwork()
5703         // is called after removing all associated NRIs from mNetworkRequests.
5704         if (null == nri) return;
5705         final NetworkAgentInfo satisfier = nri.getSatisfier();
5706         if (null == satisfier) return;
5707         removeLocalNetworkUpstream(disconnecting, satisfier);
5708     }
5709 
5710     private void removeLocalNetworkUpstream(@NonNull final NetworkAgentInfo localAgent,
5711             @NonNull final NetworkAgentInfo upstream) {
5712         try {
5713             final String localNetworkInterfaceName = localAgent.linkProperties.getInterfaceName();
5714             final String upstreamNetworkInterfaceName = upstream.linkProperties.getInterfaceName();
5715             mRoutingCoordinatorService.removeInterfaceForward(
5716                     localNetworkInterfaceName,
5717                     upstreamNetworkInterfaceName);
5718             disableMulticastRouting(localNetworkInterfaceName, upstreamNetworkInterfaceName);
5719         } catch (RemoteException e) {
5720             loge("Couldn't remove interface forward for "
5721                     + localAgent.linkProperties.getInterfaceName() + " to "
5722                     + upstream.linkProperties.getInterfaceName() + " while disconnecting");
5723         }
5724     }
5725 
5726     private boolean createNativeNetwork(@NonNull NetworkAgentInfo nai) {
5727         try {
5728             // This should never fail.  Specifying an already in use NetID will cause failure.
5729             final NativeNetworkConfig config;
5730             if (nai.isVPN()) {
5731                 if (getVpnType(nai) == VpnManager.TYPE_VPN_NONE) {
5732                     Log.wtf(TAG, "Unable to get VPN type from network " + nai.toShortString());
5733                     return false;
5734                 }
5735                 config = new NativeNetworkConfig(nai.network.getNetId(), NativeNetworkType.VIRTUAL,
5736                         INetd.PERMISSION_NONE,
5737                         !nai.networkAgentConfig.allowBypass /* secure */,
5738                         getVpnType(nai), nai.networkAgentConfig.excludeLocalRouteVpn);
5739             } else {
5740                 config = new NativeNetworkConfig(nai.network.getNetId(),
5741                         nai.isLocalNetwork() ? NativeNetworkType.PHYSICAL_LOCAL
5742                                 : NativeNetworkType.PHYSICAL,
5743                         getNetworkPermission(nai.networkCapabilities),
5744                         false /* secure */,
5745                         VpnManager.TYPE_VPN_NONE,
5746                         false /* excludeLocalRoutes */);
5747             }
5748             mNetd.networkCreate(config);
5749             mDnsResolver.createNetworkCache(nai.network.getNetId());
5750             mDnsManager.updateCapabilitiesForNetwork(nai.network.getNetId(),
5751                     nai.networkCapabilities);
5752             return true;
5753         } catch (RemoteException | ServiceSpecificException e) {
5754             loge("Error creating network " + nai.toShortString() + ": " + e.getMessage());
5755             return false;
5756         }
5757     }
5758 
5759     private void destroyNativeNetwork(@NonNull NetworkAgentInfo nai) {
5760         if (mDscpPolicyTracker != null) {
5761             mDscpPolicyTracker.removeAllDscpPolicies(nai, false);
5762         }
5763         // Remove any forwarding rules to and from the interface for this network, since
5764         // the interface is going to go away. Don't send the callbacks however ; if the network
5765         // was is being disconnected the callbacks have already been sent, and if it is being
5766         // destroyed pending replacement they will be sent when it is disconnected.
5767         maybeDisableForwardRulesForDisconnectingNai(nai, false /* sendCallbacks */);
5768         updateIngressToVpnAddressFiltering(null, nai.linkProperties, nai);
5769         updateLocalNetworkAddresses(null, nai.linkProperties);
5770         try {
5771             mNetd.networkDestroy(nai.network.getNetId());
5772         } catch (RemoteException | ServiceSpecificException e) {
5773             loge("Exception destroying network(networkDestroy): " + e);
5774         }
5775         try {
5776             mDnsResolver.destroyNetworkCache(nai.network.getNetId());
5777         } catch (RemoteException | ServiceSpecificException e) {
5778             loge("Exception destroying network: " + e);
5779         }
5780         // TODO: defer calling this until the network is removed from mNetworkAgentInfos.
5781         // Otherwise, a private DNS configuration update for a destroyed network, or one that never
5782         // gets created, could add data to DnsManager data structures that will never get deleted.
5783         mDnsManager.removeNetwork(nai.network);
5784 
5785         // clean up tc police filters on interface.
5786         if (nai.everConnected() && canNetworkBeRateLimited(nai) && mIngressRateLimit >= 0) {
5787             mDeps.disableIngressRateLimit(nai.linkProperties.getInterfaceName());
5788         }
5789 
5790         nai.setDestroyed();
5791         nai.onNetworkDestroyed();
5792     }
5793 
5794     // If this method proves to be too slow then we can maintain a separate
5795     // pendingIntent => NetworkRequestInfo map.
5796     // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo.
5797     private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) {
5798         for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) {
5799             PendingIntent existingPendingIntent = entry.getValue().mPendingIntent;
5800             if (existingPendingIntent != null &&
5801                     mDeps.intentFilterEquals(existingPendingIntent, pendingIntent)) {
5802                 return entry.getValue();
5803             }
5804         }
5805         return null;
5806     }
5807 
5808     private void checkNrisConsistency(final NetworkRequestInfo nri) {
5809         if (mDeps.isAtLeastT()) {
5810             for (final NetworkRequestInfo n : mNetworkRequests.values()) {
5811                 if (n.mBinder != null && n.mBinder == nri.mBinder) {
5812                     // Temporary help to debug b/194394697 ; TODO : remove this function when the
5813                     // bug is fixed.
5814                     dumpAllRequestInfoLogsToLogcat();
5815                     throw new IllegalStateException("This NRI is already registered. New : " + nri
5816                             + ", existing : " + n);
5817                 }
5818             }
5819         }
5820     }
5821 
5822     private boolean hasCarrierPrivilegeForNetworkCaps(final int callingUid,
5823             @NonNull final NetworkCapabilities caps) {
5824         if (mCarrierPrivilegeAuthenticator != null) {
5825             return mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
5826                     callingUid, caps);
5827         }
5828         return false;
5829     }
5830 
5831     private int getSubscriptionIdFromNetworkCaps(@NonNull final NetworkCapabilities caps) {
5832         if (mCarrierPrivilegeAuthenticator != null) {
5833             return mCarrierPrivilegeAuthenticator.getSubIdFromNetworkCapabilities(caps);
5834         }
5835         return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
5836     }
5837 
5838     private void handleRegisterNetworkRequestWithIntent(@NonNull final Message msg) {
5839         final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
5840         // handleRegisterNetworkRequestWithIntent() doesn't apply to multilayer requests.
5841         ensureNotMultilayerRequest(nri, "handleRegisterNetworkRequestWithIntent");
5842         final NetworkRequestInfo existingRequest =
5843                 findExistingNetworkRequestInfo(nri.mPendingIntent);
5844         if (existingRequest != null) { // remove the existing request.
5845             if (DBG) {
5846                 log("Replacing " + existingRequest.mRequests.get(0) + " with "
5847                         + nri.mRequests.get(0) + " because their intents matched.");
5848             }
5849             handleReleaseNetworkRequest(existingRequest.mRequests.get(0), mDeps.getCallingUid(),
5850                     /* callOnUnavailable */ false);
5851         }
5852         handleRegisterNetworkRequest(nri);
5853     }
5854 
5855     private void handleRegisterNetworkRequest(@NonNull final NetworkRequestInfo nri) {
5856         handleRegisterNetworkRequests(Collections.singleton(nri));
5857     }
5858 
5859     private void handleRegisterNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
5860         ensureRunningOnConnectivityServiceThread();
5861         for (final NetworkRequestInfo nri : nris) {
5862             mNetworkRequestInfoLogs.log("REGISTER " + nri);
5863             checkNrisConsistency(nri);
5864             for (final NetworkRequest req : nri.mRequests) {
5865                 mNetworkRequests.put(req, nri);
5866                 // TODO: Consider update signal strength for other types.
5867                 if (req.isListen()) {
5868                     forEachNetworkAgentInfo(network -> {
5869                         if (req.networkCapabilities.hasSignalStrength()
5870                                 && network.satisfiesImmutableCapabilitiesOf(req)) {
5871                             updateSignalStrengthThresholds(network, "REGISTER", req);
5872                         }
5873                     });
5874                 } else if (req.isRequest() && mNetworkRequestStateStatsMetrics != null) {
5875                     mNetworkRequestStateStatsMetrics.onNetworkRequestReceived(req);
5876                 }
5877             }
5878 
5879             // If this NRI has a satisfier already, it is replacing an older request that
5880             // has been removed. Track it.
5881             final NetworkRequest activeRequest = nri.getActiveRequest();
5882             if (null != activeRequest) {
5883                 // If there is an active request, then for sure there is a satisfier.
5884                 nri.getSatisfier().addRequest(activeRequest);
5885             }
5886 
5887             if (shouldTrackUidsForBlockedStatusCallbacks()
5888                     && nri.mMessenger != null
5889                     && !nri.mUidTrackedForBlockedStatus) {
5890                 Log.wtf(TAG, "Registered nri is not tracked for sending blocked status: " + nri);
5891             }
5892         }
5893 
5894         if (mFlags.noRematchAllRequestsOnRegister()) {
5895             rematchNetworksAndRequests(nris);
5896         } else {
5897             rematchAllNetworksAndRequests();
5898         }
5899 
5900         // Requests that have not been matched to a network will not have been sent to the
5901         // providers, because the old satisfier and the new satisfier are the same (null in this
5902         // case). Send these requests to the providers.
5903         for (final NetworkRequestInfo nri : nris) {
5904             for (final NetworkOfferInfo noi : mNetworkOffers) {
5905                 informOffer(nri, noi.offer, mNetworkRanker);
5906             }
5907         }
5908     }
5909 
5910     private void handleReleaseNetworkRequestWithIntent(@NonNull final PendingIntent pendingIntent,
5911             final int callingUid) {
5912         final NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent);
5913         if (nri != null) {
5914             // handleReleaseNetworkRequestWithIntent() paths don't apply to multilayer requests.
5915             ensureNotMultilayerRequest(nri, "handleReleaseNetworkRequestWithIntent");
5916             handleReleaseNetworkRequest(
5917                     nri.mRequests.get(0),
5918                     callingUid,
5919                     /* callOnUnavailable */ false);
5920         }
5921     }
5922 
5923     // Determines whether the network is the best (or could become the best, if it validated), for
5924     // none of a particular type of NetworkRequests. The type of NetworkRequests considered depends
5925     // on the value of reason:
5926     //
5927     // - UnneededFor.TEARDOWN: non-listen NetworkRequests. If a network is unneeded for this reason,
5928     //   then it should be torn down.
5929     // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason,
5930     //   then it should be lingered.
5931     private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
5932         ensureRunningOnConnectivityServiceThread();
5933 
5934         if (!nai.everConnected() || nai.isVPN() || nai.isInactive()
5935                 || nai.getScore().getKeepConnectedReason() != NetworkScore.KEEP_CONNECTED_NONE) {
5936             return false;
5937         }
5938 
5939         final int numRequests;
5940         switch (reason) {
5941             case TEARDOWN:
5942                 numRequests = nai.numRequestNetworkRequests();
5943                 break;
5944             case LINGER:
5945                 numRequests = nai.numForegroundNetworkRequests();
5946                 break;
5947             default:
5948                 Log.wtf(TAG, "Invalid reason. Cannot happen.");
5949                 return true;
5950         }
5951 
5952         if (numRequests > 0) return false;
5953 
5954         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
5955             if (reason == UnneededFor.LINGER
5956                     && !nri.isMultilayerRequest()
5957                     && nri.mRequests.get(0).isBackgroundRequest()) {
5958                 // Background requests don't affect lingering.
5959                 continue;
5960             }
5961 
5962             if (isNetworkPotentialSatisfier(nai, nri)) {
5963                 return false;
5964             }
5965         }
5966         return true;
5967     }
5968 
5969     private boolean isNetworkPotentialSatisfier(
5970             @NonNull final NetworkAgentInfo candidate, @NonNull final NetworkRequestInfo nri) {
5971         // While destroyed network sometimes satisfy requests (including occasionally newly
5972         // satisfying requests), *potential* satisfiers are networks that might beat a current
5973         // champion if they validate. As such, a destroyed network is never a potential satisfier,
5974         // because it's never a good idea to keep a destroyed network in case it validates.
5975         // For example, declaring it a potential satisfier would keep an unvalidated destroyed
5976         // candidate after it's been replaced by another unvalidated network.
5977         if (candidate.isDestroyed()) return false;
5978         // Listen requests won't keep up a network satisfying it. If this is not a multilayer
5979         // request, return immediately. For multilayer requests, check to see if any of the
5980         // multilayer requests may have a potential satisfier.
5981         if (!nri.isMultilayerRequest() && (nri.mRequests.get(0).isListen()
5982                 || nri.mRequests.get(0).isListenForBest())) {
5983             return false;
5984         }
5985         for (final NetworkRequest req : nri.mRequests) {
5986             // This multilayer listen request is satisfied therefore no further requests need to be
5987             // evaluated deeming this network not a potential satisfier.
5988             if ((req.isListen() || req.isListenForBest()) && nri.getActiveRequest() == req) {
5989                 return false;
5990             }
5991             // As non-multilayer listen requests have already returned, the below would only happen
5992             // for a multilayer request therefore continue to the next request if available.
5993             if (req.isListen() || req.isListenForBest()) {
5994                 continue;
5995             }
5996             // If there is hope for this network might validate and subsequently become the best
5997             // network for that request, then it is needed. Note that this network can't already
5998             // be the best for this request, or it would be the current satisfier, and therefore
5999             // there would be no need to call this method to find out if it is a *potential*
6000             // satisfier ("unneeded", the only caller, only calls this if this network currently
6001             // satisfies no request).
6002             if (candidate.satisfies(req)) {
6003                 // As soon as a network is found that satisfies a request, return. Specifically for
6004                 // multilayer requests, returning as soon as a NetworkAgentInfo satisfies a request
6005                 // is important so as to not evaluate lower priority requests further in
6006                 // nri.mRequests.
6007                 final NetworkAgentInfo champion = req.equals(nri.getActiveRequest())
6008                         ? nri.getSatisfier() : null;
6009                 // Note that this catches two important cases:
6010                 // 1. Unvalidated cellular will not be reaped when unvalidated WiFi
6011                 //    is currently satisfying the request.  This is desirable when
6012                 //    cellular ends up validating but WiFi does not.
6013                 // 2. Unvalidated WiFi will not be reaped when validated cellular
6014                 //    is currently satisfying the request.  This is desirable when
6015                 //    WiFi ends up validating and out scoring cellular.
6016                 return mNetworkRanker.mightBeat(req, champion, candidate.getValidatedScoreable());
6017             }
6018         }
6019 
6020         return false;
6021     }
6022 
6023     private NetworkRequestInfo getNriForAppRequest(
6024             NetworkRequest request, int callingUid, String requestedOperation) {
6025         // Looking up the app passed param request in mRequests isn't possible since it may return
6026         // null for a request managed by a per-app default. Therefore use getNriForAppRequest() to
6027         // do the lookup since that will also find per-app default managed requests.
6028         // Additionally, this lookup needs to be relatively fast (hence the lookup optimization)
6029         // to avoid potential race conditions when validating a package->uid mapping when sending
6030         // the callback on the very low-chance that an application shuts down prior to the callback
6031         // being sent.
6032         final NetworkRequestInfo nri = mNetworkRequests.get(request) != null
6033                 ? mNetworkRequests.get(request) : getNriForAppRequest(request);
6034 
6035         if (nri != null) {
6036             if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) {
6037                 log(String.format("UID %d attempted to %s for unowned request %s",
6038                         callingUid, requestedOperation, nri));
6039                 return null;
6040             }
6041         }
6042 
6043         return nri;
6044     }
6045 
6046     private void ensureNotMultilayerRequest(@NonNull final NetworkRequestInfo nri,
6047             final String callingMethod) {
6048         if (nri.isMultilayerRequest()) {
6049             throw new IllegalStateException(
6050                     callingMethod + " does not support multilayer requests.");
6051         }
6052     }
6053 
6054     private void handleTimedOutNetworkRequest(@NonNull final NetworkRequestInfo nri) {
6055         ensureRunningOnConnectivityServiceThread();
6056         // handleTimedOutNetworkRequest() is part of the requestNetwork() flow which works off of a
6057         // single NetworkRequest and thus does not apply to multilayer requests.
6058         ensureNotMultilayerRequest(nri, "handleTimedOutNetworkRequest");
6059         if (mNetworkRequests.get(nri.mRequests.get(0)) == null) {
6060             return;
6061         }
6062         if (nri.isBeingSatisfied()) {
6063             return;
6064         }
6065         if (VDBG || (DBG && nri.mRequests.get(0).isRequest())) {
6066             log("releasing " + nri.mRequests.get(0) + " (timeout)");
6067         }
6068         handleRemoveNetworkRequest(nri);
6069         callCallbackForRequest(nri, null, CALLBACK_UNAVAIL, 0);
6070     }
6071 
6072     private void handleReleaseNetworkRequest(@NonNull final NetworkRequest request,
6073             final int callingUid,
6074             final boolean callOnUnavailable) {
6075         final NetworkRequestInfo nri =
6076                 getNriForAppRequest(request, callingUid, "release NetworkRequest");
6077         if (nri == null) {
6078             return;
6079         }
6080         if (VDBG || (DBG && request.isRequest())) {
6081             log("releasing " + request + " (release request)");
6082         }
6083         handleRemoveNetworkRequest(nri);
6084         if (callOnUnavailable) {
6085             callCallbackForRequest(nri, null, CALLBACK_UNAVAIL, 0);
6086         }
6087     }
6088 
6089     private void handleRemoveNetworkRequest(@NonNull final NetworkRequestInfo nri) {
6090         handleRemoveNetworkRequest(nri, true /* untrackUids */);
6091     }
6092 
6093     private void handleRemoveNetworkRequest(@NonNull final NetworkRequestInfo nri,
6094             final boolean untrackUids) {
6095         ensureRunningOnConnectivityServiceThread();
6096         for (final NetworkRequest req : nri.mRequests) {
6097             if (null == mNetworkRequests.remove(req)) {
6098                 logw("Attempted removal of untracked request " + req + " for nri " + nri);
6099                 continue;
6100             }
6101             if (req.isListen()) {
6102                 removeListenRequestFromNetworks(req);
6103             } else if (req.isRequest() && mNetworkRequestStateStatsMetrics != null) {
6104                 mNetworkRequestStateStatsMetrics.onNetworkRequestRemoved(req);
6105             }
6106         }
6107         nri.unlinkDeathRecipient();
6108         if (mDefaultNetworkRequests.remove(nri)) {
6109             // If this request was one of the defaults, then the UID rules need to be updated
6110             // WARNING : if the app(s) for which this network request is the default are doing
6111             // traffic, this will kill their connected sockets, even if an equivalent request
6112             // is going to be reinstated right away ; unconnected traffic will go on the default
6113             // until the new default is set, which will happen very soon.
6114             // TODO : The only way out of this is to diff old defaults and new defaults, and only
6115             // remove ranges for those requests that won't have a replacement
6116             final NetworkAgentInfo satisfier = nri.getSatisfier();
6117             if (null != satisfier) {
6118                 try {
6119                     modifyNetworkUidRanges(false /* add */, satisfier, nri.getUids(),
6120                             nri.getPreferenceOrderForNetd());
6121                 } catch (RemoteException e) {
6122                     loge("Exception setting network preference default network", e);
6123                 }
6124             }
6125         }
6126 
6127         if (untrackUids) {
6128             maybeUntrackUidAndClearBlockedReasons(nri);
6129         }
6130         mNetworkRequestInfoLogs.log("RELEASE " + nri);
6131         checkNrisConsistency(nri);
6132 
6133         if (null != nri.getActiveRequest()) {
6134             if (!nri.getActiveRequest().isListen()) {
6135                 removeSatisfiedNetworkRequestFromNetwork(nri);
6136             }
6137         }
6138 
6139         // For all outstanding offers, cancel any of the layers of this NRI that used to be
6140         // needed for this offer.
6141         for (final NetworkOfferInfo noi : mNetworkOffers) {
6142             for (final NetworkRequest req : nri.mRequests) {
6143                 if (req.isRequest() && noi.offer.neededFor(req)) {
6144                     noi.offer.onNetworkUnneeded(req);
6145                 }
6146             }
6147         }
6148     }
6149 
6150     private void handleRemoveNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
6151         handleRemoveNetworkRequests(nris, true /* untrackUids */);
6152     }
6153 
6154     private void handleRemoveNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris,
6155             final boolean untrackUids) {
6156         for (final NetworkRequestInfo nri : nris) {
6157             if (mDefaultRequest == nri) {
6158                 // Make sure we never remove the default request.
6159                 continue;
6160             }
6161             handleRemoveNetworkRequest(nri, untrackUids);
6162         }
6163     }
6164 
6165     private void removeListenRequestFromNetworks(@NonNull final NetworkRequest req) {
6166         // listens don't have a singular affected Network. Check all networks to see
6167         // if this listen request applies and remove it.
6168         forEachNetworkAgentInfo(nai -> {
6169             nai.removeRequest(req.requestId);
6170             if (req.networkCapabilities.hasSignalStrength()
6171                     && nai.satisfiesImmutableCapabilitiesOf(req)) {
6172                 updateSignalStrengthThresholds(nai, "RELEASE", req);
6173             }
6174         });
6175     }
6176 
6177     /**
6178      * Remove a NetworkRequestInfo's satisfied request from its 'satisfier' (NetworkAgentInfo) and
6179      * manage the necessary upkeep (linger, teardown networks, etc.) when doing so.
6180      * @param nri the NetworkRequestInfo to disassociate from its current NetworkAgentInfo
6181      */
6182     private void removeSatisfiedNetworkRequestFromNetwork(@NonNull final NetworkRequestInfo nri) {
6183         boolean wasKept = false;
6184         final NetworkAgentInfo nai = nri.getSatisfier();
6185         if (nai != null) {
6186             final int requestLegacyType = nri.getActiveRequest().legacyType;
6187             final boolean wasBackgroundNetwork = nai.isBackgroundNetwork();
6188             nai.removeRequest(nri.getActiveRequest().requestId);
6189             if (VDBG || DDBG) {
6190                 log(" Removing from current network " + nai.toShortString()
6191                         + ", leaving " + nai.numNetworkRequests() + " requests.");
6192             }
6193             // If there are still lingered requests on this network, don't tear it down,
6194             // but resume lingering instead.
6195             final long now = SystemClock.elapsedRealtime();
6196             if (updateInactivityState(nai, now)) {
6197                 notifyNetworkLosing(nai, now);
6198             }
6199             if (unneeded(nai, UnneededFor.TEARDOWN)) {
6200                 if (DBG) log("no live requests for " + nai.toShortString() + "; disconnecting");
6201                 teardownUnneededNetwork(nai);
6202             } else {
6203                 wasKept = true;
6204             }
6205             if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) {
6206                 // Went from foreground to background.
6207                 updateCapabilitiesForNetwork(nai);
6208             }
6209 
6210             // Maintain the illusion.  When this request arrived, we might have pretended
6211             // that a network connected to serve it, even though the network was already
6212             // connected.  Now that this request has gone away, we might have to pretend
6213             // that the network disconnected.  LegacyTypeTracker will generate that
6214             // phantom disconnect for this type.
6215             if (requestLegacyType != TYPE_NONE) {
6216                 boolean doRemove = true;
6217                 if (wasKept) {
6218                     // check if any of the remaining requests for this network are for the
6219                     // same legacy type - if so, don't remove the nai
6220                     for (int i = 0; i < nai.numNetworkRequests(); i++) {
6221                         NetworkRequest otherRequest = nai.requestAt(i);
6222                         if (otherRequest.legacyType == requestLegacyType
6223                                 && otherRequest.isRequest()) {
6224                             if (DBG) log(" still have other legacy request - leaving");
6225                             doRemove = false;
6226                         }
6227                     }
6228                 }
6229 
6230                 if (doRemove) {
6231                     mLegacyTypeTracker.remove(requestLegacyType, nai, false);
6232                 }
6233             }
6234         }
6235     }
6236 
6237     /**
6238      * Perform the specified operation on all networks.
6239      *
6240      * This method will run |op| exactly once for each network currently registered at the
6241      * time it is called, even if |op| adds or removes networks.
6242      *
6243      * @param op the operation to perform. The operation is allowed to disconnect any number of
6244      *           networks.
6245      */
6246     private void forEachNetworkAgentInfo(final Consumer<NetworkAgentInfo> op) {
6247         // Create a copy instead of iterating over the set so |op| is allowed to disconnect any
6248         // number of networks (which removes it from mNetworkAgentInfos). The copy is cheap
6249         // because there are at most a handful of NetworkAgents connected at any given time.
6250         final NetworkAgentInfo[] nais = new NetworkAgentInfo[mNetworkAgentInfos.size()];
6251         mNetworkAgentInfos.toArray(nais);
6252         for (NetworkAgentInfo nai : nais) {
6253             op.accept(nai);
6254         }
6255     }
6256 
6257     /**
6258      * Check whether the specified condition is true for any network.
6259      *
6260      * This method will stop evaluating as soon as the condition returns true for any network.
6261      * The order of iteration is not contractual.
6262      *
6263      * @param condition the condition to verify. This method must not modify the set of networks in
6264      *                  any way.
6265      * @return whether {@code condition} returned true for any network
6266      */
6267     private boolean anyNetworkAgentInfo(final Predicate<NetworkAgentInfo> condition) {
6268         for (int i = mNetworkAgentInfos.size() - 1; i >= 0; i--) {
6269             if (condition.test(mNetworkAgentInfos.valueAt(i))) return true;
6270         }
6271         return false;
6272     }
6273 
6274     private RequestInfoPerUidCounter getRequestCounter(NetworkRequestInfo nri) {
6275         return hasAnyPermissionOf(mContext,
6276                 nri.mPid, nri.mUid, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
6277                 ? mSystemNetworkRequestCounter : mNetworkRequestCounter;
6278     }
6279 
6280     @Override
6281     public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
6282         enforceNetworkStackSettingsOrSetup();
6283         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED,
6284                 encodeBool(accept), encodeBool(always), network));
6285     }
6286 
6287     @Override
6288     public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) {
6289         enforceNetworkStackSettingsOrSetup();
6290         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY,
6291                 encodeBool(accept), encodeBool(always), network));
6292     }
6293 
6294     @Override
6295     public void setAvoidUnvalidated(Network network) {
6296         enforceNetworkStackSettingsOrSetup();
6297         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network));
6298     }
6299 
6300     @Override
6301     public void setTestAllowBadWifiUntil(long timeMs) {
6302         enforceSettingsPermission();
6303         if (!Build.isDebuggable()) {
6304             throw new IllegalStateException("Does not support in non-debuggable build");
6305         }
6306 
6307         if (timeMs > System.currentTimeMillis() + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS) {
6308             throw new IllegalArgumentException("It should not exceed "
6309                     + MAX_TEST_ALLOW_BAD_WIFI_UNTIL_MS + "ms from now");
6310         }
6311 
6312         mHandler.sendMessage(
6313                 mHandler.obtainMessage(EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL, timeMs));
6314     }
6315 
6316     @Override
6317     public void setTestLowTcpPollingTimerForKeepalive(long timeMs) {
6318         enforceSettingsPermission();
6319 
6320         if (timeMs > System.currentTimeMillis() + MAX_TEST_LOW_TCP_POLLING_UNTIL_MS) {
6321             throw new IllegalArgumentException("Argument should not exceed "
6322                     + MAX_TEST_LOW_TCP_POLLING_UNTIL_MS + "ms from now");
6323         }
6324 
6325         mHandler.sendMessage(
6326                 mHandler.obtainMessage(EVENT_SET_LOW_TCP_POLLING_UNTIL, timeMs));
6327     }
6328 
6329     private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) {
6330         if (DBG) log("handleSetAcceptUnvalidated network=" + network +
6331                 " accept=" + accept + " always=" + always);
6332 
6333         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
6334         if (nai == null) {
6335             // Nothing to do.
6336             return;
6337         }
6338 
6339         if (nai.everValidated()) {
6340             // The network validated while the dialog box was up. Take no action.
6341             return;
6342         }
6343 
6344         if (!nai.networkAgentConfig.explicitlySelected) {
6345             Log.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network");
6346         }
6347 
6348         if (accept != nai.networkAgentConfig.acceptUnvalidated) {
6349             nai.networkAgentConfig.acceptUnvalidated = accept;
6350             // If network becomes partial connectivity and user already accepted to use this
6351             // network, we should respect the user's option and don't need to popup the
6352             // PARTIAL_CONNECTIVITY notification to user again.
6353             nai.networkAgentConfig.acceptPartialConnectivity = accept;
6354             nai.updateScoreForNetworkAgentUpdate();
6355             rematchAllNetworksAndRequests();
6356         }
6357 
6358         if (always) {
6359             nai.onSaveAcceptUnvalidated(accept);
6360         }
6361 
6362         if (!accept) {
6363             // Tell the NetworkAgent to not automatically reconnect to the network.
6364             nai.onPreventAutomaticReconnect();
6365             // Teardown the network.
6366             teardownUnneededNetwork(nai);
6367         }
6368 
6369     }
6370 
6371     private void handleSetAcceptPartialConnectivity(Network network, boolean accept,
6372             boolean always) {
6373         if (DBG) {
6374             log("handleSetAcceptPartialConnectivity network=" + network + " accept=" + accept
6375                     + " always=" + always);
6376         }
6377 
6378         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
6379         if (nai == null) {
6380             // Nothing to do.
6381             return;
6382         }
6383 
6384         if (nai.isValidated()) {
6385             // The network validated while the dialog box was up. Take no action.
6386             return;
6387         }
6388 
6389         if (accept != nai.networkAgentConfig.acceptPartialConnectivity) {
6390             nai.networkAgentConfig.acceptPartialConnectivity = accept;
6391         }
6392 
6393         // TODO: Use the current design or save the user choice into IpMemoryStore.
6394         if (always) {
6395             nai.onSaveAcceptUnvalidated(accept);
6396         }
6397 
6398         if (!accept) {
6399             // Tell the NetworkAgent to not automatically reconnect to the network.
6400             nai.onPreventAutomaticReconnect();
6401             // Tear down the network.
6402             teardownUnneededNetwork(nai);
6403         } else {
6404             // Inform NetworkMonitor that partial connectivity is acceptable. This will likely
6405             // result in a partial connectivity result which will be processed by
6406             // maybeHandleNetworkMonitorMessage.
6407             //
6408             // TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored
6409             // per network. Therefore, NetworkMonitor may still do https probe.
6410             nai.networkMonitor().setAcceptPartialConnectivity();
6411         }
6412     }
6413 
6414     private void handleSetAvoidUnvalidated(Network network) {
6415         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
6416         if (nai == null || nai.isValidated()) {
6417             // Nothing to do. The network either disconnected or revalidated.
6418             return;
6419         }
6420         if (0L == nai.getAvoidUnvalidated()) {
6421             nai.setAvoidUnvalidated();
6422             nai.updateScoreForNetworkAgentUpdate();
6423             rematchAllNetworksAndRequests();
6424         }
6425     }
6426 
6427     /** Schedule evaluation timeout */
6428     @VisibleForTesting
6429     public void scheduleEvaluationTimeout(@NonNull final Network network, final long delayMs) {
6430         mDeps.scheduleEvaluationTimeout(mHandler, network, delayMs);
6431     }
6432 
6433     @Override
6434     public void startCaptivePortalApp(Network network) {
6435         enforceNetworkStackOrSettingsPermission();
6436         mHandler.post(() -> {
6437             NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
6438             if (nai == null) return;
6439             if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return;
6440             nai.networkMonitor().launchCaptivePortalApp();
6441         });
6442     }
6443 
6444     /**
6445      * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this
6446      * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself.
6447      * @param network Network on which the captive portal was detected.
6448      * @param appExtras Bundle to use as intent extras for the captive portal application.
6449      *                  Must be treated as opaque to avoid preventing the captive portal app to
6450      *                  update its arguments.
6451      */
6452     @Override
6453     public void startCaptivePortalAppInternal(Network network, Bundle appExtras) {
6454         mContext.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
6455                 "ConnectivityService");
6456 
6457         final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
6458         appIntent.putExtras(appExtras);
6459         appIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL,
6460                 new CaptivePortal(new CaptivePortalImpl(network).asBinder()));
6461         appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
6462 
6463         final long token = Binder.clearCallingIdentity();
6464         try {
6465             mContext.startActivityAsUser(appIntent, UserHandle.CURRENT);
6466         } finally {
6467             Binder.restoreCallingIdentity(token);
6468         }
6469     }
6470 
6471     public class CaptivePortalImpl extends ICaptivePortal.Stub implements IBinder.DeathRecipient {
6472         private final Network mNetwork;
6473         // Binder object to track the lifetime of the setDelegateUid caller for cleanup purposes.
6474         //
6475         // Note that in theory it can happen that there are multiple callers for a given
6476         // object. For example, the app that receives the CaptivePortal object from the Intent
6477         // fired by startCaptivePortalAppInternal could send the object to another process, or
6478         // clone it. Only the first of these objects that calls setDelegateUid will properly
6479         // register a death recipient. Calls from the other objects will work, but only the
6480         // first object's death will cause the death recipient to fire.
6481         // TODO: track all callers by callerBinder instead of CaptivePortalImpl, store callerBinder
6482         // in a Set. When the death recipient fires, we can remove the callingBinder from the set,
6483         // and when the set is empty, we can clear the delegated UID.
6484         private IBinder mDelegateUidCaller;
6485 
6486         private CaptivePortalImpl(Network network) {
6487             mNetwork = network;
6488         }
6489 
6490         @Override
6491         public void appResponse(final int response) {
6492             if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) {
6493                 enforceSettingsPermission();
6494             } else if (response == CaptivePortal.APP_RETURN_UNWANTED) {
6495                 mHandler.sendMessage(mHandler.obtainMessage(EVENT_USER_DOES_NOT_WANT, mNetwork));
6496                 // Since the network will be disconnected, skip notifying NetworkMonitor
6497                 return;
6498             }
6499 
6500             final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork);
6501             if (nm == null) return;
6502             nm.notifyCaptivePortalAppFinished(response);
6503         }
6504 
6505         @Override
6506         public void appRequest(final int request) {
6507             final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork);
6508             if (nm == null) return;
6509 
6510             if (request == CaptivePortal.APP_REQUEST_REEVALUATION_REQUIRED) {
6511                 // This enforceNetworkStackPermission() should be adopted to check
6512                 // the required permission but this may be break OEM captive portal
6513                 // apps. Simply ignore the request if the caller does not have
6514                 // permission.
6515                 if (!hasNetworkStackPermission()) {
6516                     Log.e(TAG, "Calling appRequest() without proper permission. Skip");
6517                     return;
6518                 }
6519 
6520                 nm.forceReevaluation(mDeps.getCallingUid());
6521             }
6522         }
6523 
6524         private int handleSetDelegateUid(int uid, @NonNull final IBinder callerBinder) {
6525             if (mDelegateUidCaller == null) {
6526                 mDelegateUidCaller = callerBinder;
6527                 try {
6528                     // While technically unnecessary, it is safe to register a DeathRecipient for
6529                     // a cleanup operation (where uid = INVALID_UID).
6530                     mDelegateUidCaller.linkToDeath(this, 0);
6531                 } catch (RemoteException e) {
6532                     // remote has died, return early.
6533                     return ENOTCONN;
6534                 }
6535             }
6536 
6537             final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(mNetwork);
6538             if (nai == null) return ENOENT; // network does not exist anymore.
6539             if (nai.isDestroyed()) return ENOENT; // network has already been destroyed.
6540 
6541             // TODO: consider allowing the uid to bypass VPN on all networks before V.
6542             if (!mDeps.isAtLeastV()) return EOPNOTSUPP;
6543 
6544             // Check whether there has already been a delegate UID configured, if so, perform
6545             // cleanup and disallow bypassing VPN for that UID if no other caller is delegating
6546             // this UID.
6547             // TODO: consider using exceptions instead of errnos.
6548             final int errno = nai.removeCaptivePortalDelegateUid(this);
6549             if (errno != 0) return errno;
6550 
6551             // If uid == INVALID_UID, we are done.
6552             if (uid == INVALID_UID) return 0;
6553             return nai.setCaptivePortalDelegateUid(this, uid);
6554         }
6555 
6556         @Override
6557         public void setDelegateUid(int uid, @NonNull final IBinder callerBinder,
6558                 @NonNull final IIntResultListener listener) {
6559             Objects.requireNonNull(callerBinder);
6560             Objects.requireNonNull(listener);
6561             enforceAnyPermissionOf(mContext, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
6562 
6563             mHandler.post(() -> {
6564                 final int errno = handleSetDelegateUid(uid, callerBinder);
6565                 try {
6566                     listener.onResult(errno);
6567                 } catch (RemoteException e) {
6568                     // remote has died, nothing to do.
6569                 }
6570             });
6571         }
6572 
6573         @Nullable
6574         private NetworkMonitorManager getNetworkMonitorManager(final Network network) {
6575             // getNetworkAgentInfoForNetwork is thread-safe
6576             final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
6577             if (nai == null) return null;
6578 
6579             // nai.networkMonitor() is thread-safe
6580             return nai.networkMonitor();
6581         }
6582 
6583         @Override
6584         public void binderDied() {
6585             // Cleanup invalid UID and restore the VPN bypass rule. Because mDelegateUidCaller is
6586             // never reset, it cannot be null in this context.
6587             mHandler.post(() -> handleSetDelegateUid(INVALID_UID, mDelegateUidCaller));
6588         }
6589     }
6590 
6591     public boolean avoidBadWifi() {
6592         return mMultinetworkPolicyTracker.getAvoidBadWifi();
6593     }
6594 
6595     private boolean activelyPreferBadWifi() {
6596         return mMultinetworkPolicyTracker.getActivelyPreferBadWifi();
6597     }
6598 
6599     /**
6600      * Return whether the device should maintain continuous, working connectivity by switching away
6601      * from WiFi networks having no connectivity.
6602      * @see MultinetworkPolicyTracker#getAvoidBadWifi()
6603      */
6604     public boolean shouldAvoidBadWifi() {
6605         if (!hasNetworkStackPermission()) {
6606             throw new SecurityException("avoidBadWifi requires NETWORK_STACK permission");
6607         }
6608         return avoidBadWifi();
6609     }
6610 
6611     private void updateAvoidBadWifi() {
6612         ensureRunningOnConnectivityServiceThread();
6613         // Agent info scores and offer scores depend on whether cells yields to bad wifi.
6614         final boolean avoidBadWifi = avoidBadWifi();
6615         forEachNetworkAgentInfo(nai -> {
6616             nai.updateScoreForNetworkAgentUpdate();
6617             if (avoidBadWifi) {
6618                 // If the device is now avoiding bad wifi, remove notifications that might have
6619                 // been put up when the device didn't.
6620                 mNotifier.clearNotification(nai.network.getNetId(), NotificationType.LOST_INTERNET);
6621             }
6622         });
6623         // UpdateOfferScore will update mNetworkOffers inline, so make a copy first.
6624         final ArrayList<NetworkOfferInfo> offersToUpdate = new ArrayList<>(mNetworkOffers);
6625         for (final NetworkOfferInfo noi : offersToUpdate) {
6626             updateOfferScore(noi.offer);
6627         }
6628         mNetworkRanker.setConfiguration(new NetworkRanker.Configuration(activelyPreferBadWifi()));
6629         rematchAllNetworksAndRequests();
6630     }
6631 
6632     // TODO: Evaluate whether this is of interest to other consumers of
6633     // MultinetworkPolicyTracker and worth moving out of here.
6634     private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) {
6635         final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi();
6636         if (!configRestrict) {
6637             pw.println("Bad Wi-Fi avoidance: unrestricted");
6638             return;
6639         }
6640 
6641         pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi());
6642         pw.increaseIndent();
6643         pw.println("Config restrict:               " + configRestrict);
6644         pw.println("Actively prefer bad wifi:      " + activelyPreferBadWifi());
6645 
6646         final String settingValue = mMultinetworkPolicyTracker.getAvoidBadWifiSetting();
6647         String description;
6648         // Can't use a switch statement because strings are legal case labels, but null is not.
6649         if ("0".equals(settingValue)) {
6650             description = "get stuck";
6651         } else if (settingValue == null) {
6652             description = "prompt";
6653         } else if ("1".equals(settingValue)) {
6654             description = "avoid";
6655         } else {
6656             description = settingValue + " (?)";
6657         }
6658         pw.println("Avoid bad wifi setting:        " + description);
6659 
6660         final Boolean configValue = BinderUtils.withCleanCallingIdentity(
6661                 () -> mMultinetworkPolicyTracker.deviceConfigActivelyPreferBadWifi());
6662         if (null == configValue) {
6663             description = "unset";
6664         } else if (configValue) {
6665             description = "force true";
6666         } else {
6667             description = "force false";
6668         }
6669         pw.println("Actively prefer bad wifi conf: " + description);
6670         pw.println();
6671         pw.println("Network overrides:");
6672         pw.increaseIndent();
6673         for (NetworkAgentInfo nai : networksSortedById()) {
6674             if (0L != nai.getAvoidUnvalidated()) {
6675                 pw.println(nai.toShortString());
6676             }
6677         }
6678         pw.decreaseIndent();
6679         pw.decreaseIndent();
6680     }
6681 
6682     // TODO: This method is copied from TetheringNotificationUpdater. Should have a utility class to
6683     // unify the method.
6684     private static @NonNull String getSettingsPackageName(@NonNull final PackageManager pm) {
6685         final Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
6686         final ComponentName settingsComponent = settingsIntent.resolveActivity(pm);
6687         return settingsComponent != null
6688                 ? settingsComponent.getPackageName() : "com.android.settings";
6689     }
6690 
6691     private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) {
6692         final String action;
6693         final boolean highPriority;
6694         switch (type) {
6695             case NO_INTERNET:
6696                 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED;
6697                 // High priority because it is only displayed for explicitly selected networks.
6698                 highPriority = true;
6699                 break;
6700             case PRIVATE_DNS_BROKEN:
6701                 action = Settings.ACTION_WIRELESS_SETTINGS;
6702                 // High priority because we should let user know why there is no internet.
6703                 highPriority = true;
6704                 break;
6705             case LOST_INTERNET:
6706                 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION;
6707                 // High priority because it could help the user avoid unexpected data usage.
6708                 highPriority = true;
6709                 break;
6710             case PARTIAL_CONNECTIVITY:
6711                 action = ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY;
6712                 // Don't bother the user with a high-priority notification if the network was not
6713                 // explicitly selected by the user.
6714                 highPriority = nai.networkAgentConfig.explicitlySelected;
6715                 break;
6716             default:
6717                 Log.wtf(TAG, "Unknown notification type " + type);
6718                 return;
6719         }
6720 
6721         Intent intent = new Intent(action);
6722         if (type != NotificationType.PRIVATE_DNS_BROKEN) {
6723             intent.putExtra(ConnectivityManager.EXTRA_NETWORK, nai.network);
6724             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
6725             // Some OEMs have their own Settings package. Thus, need to get the current using
6726             // Settings package name instead of just use default name "com.android.settings".
6727             final String settingsPkgName = getSettingsPackageName(mContext.getPackageManager());
6728             intent.setClassName(settingsPkgName,
6729                     settingsPkgName + ".wifi.WifiNoInternetDialog");
6730         }
6731 
6732         PendingIntent pendingIntent = PendingIntent.getActivity(
6733                 mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */),
6734                 0 /* requestCode */,
6735                 intent,
6736                 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
6737 
6738         mNotifier.showNotification(
6739                 nai.network.getNetId(), type, nai, null, pendingIntent, highPriority);
6740     }
6741 
6742     private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) {
6743         // Don't prompt if the network is validated, and don't prompt on captive portals
6744         // because we're already prompting the user to sign in.
6745         if (nai.everValidated() || nai.everCaptivePortalDetected()) {
6746             return false;
6747         }
6748 
6749         // If a network has partial connectivity, always prompt unless the user has already accepted
6750         // partial connectivity and selected don't ask again. This ensures that if the device
6751         // automatically connects to a network that has partial Internet access, the user will
6752         // always be able to use it, either because they've already chosen "don't ask again" or
6753         // because we have prompted them.
6754         if (nai.partialConnectivity() && !nai.networkAgentConfig.acceptPartialConnectivity) {
6755             return true;
6756         }
6757 
6758         // If a network has no Internet access, only prompt if the network was explicitly selected
6759         // and if the user has not already told us to use the network regardless of whether it
6760         // validated or not.
6761         if (nai.networkAgentConfig.explicitlySelected
6762                 && !nai.networkAgentConfig.acceptUnvalidated) {
6763             return true;
6764         }
6765 
6766         return false;
6767     }
6768 
6769     private void handleInitialEvaluationTimeout(@NonNull final Network network) {
6770         if (VDBG || DDBG) log("handleInitialEvaluationTimeout " + network);
6771 
6772         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
6773         if (null == nai) return;
6774 
6775         if (nai.setEvaluated()) {
6776             // If setEvaluated() returned true, the network never had any form of connectivity.
6777             // This may have an impact on request matching if bad WiFi avoidance is off and the
6778             // network was found not to have Internet access.
6779             nai.updateScoreForNetworkAgentUpdate();
6780             rematchAllNetworksAndRequests();
6781 
6782             // Also, if this is WiFi and it should be preferred actively, now is the time to
6783             // prompt the user that they walked past and connected to a bad WiFi.
6784             if (nai.networkCapabilities.hasTransport(TRANSPORT_WIFI)
6785                     && !avoidBadWifi()
6786                     && activelyPreferBadWifi()) {
6787                 // The notification will be removed if the network validates or disconnects.
6788                 showNetworkNotification(nai, NotificationType.LOST_INTERNET);
6789                 return;
6790             }
6791         }
6792 
6793         if (!shouldPromptUnvalidated(nai)) return;
6794 
6795         // Stop automatically reconnecting to this network in the future. Automatically connecting
6796         // to a network that provides no or limited connectivity is not useful, because the user
6797         // cannot use that network except through the notification shown by this method, and the
6798         // notification is only shown if the network is explicitly selected by the user.
6799         nai.onPreventAutomaticReconnect();
6800 
6801         if (nai.partialConnectivity()) {
6802             showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY);
6803         } else {
6804             showNetworkNotification(nai, NotificationType.NO_INTERNET);
6805         }
6806     }
6807 
6808     private void handleNetworkUnvalidated(NetworkAgentInfo nai) {
6809         NetworkCapabilities nc = nai.networkCapabilities;
6810         if (DBG) log("handleNetworkUnvalidated " + nai.toShortString() + " cap=" + nc);
6811 
6812         if (!nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
6813             return;
6814         }
6815 
6816         if (mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) {
6817             showNetworkNotification(nai, NotificationType.LOST_INTERNET);
6818         }
6819     }
6820 
6821     @Override
6822     public int getMultipathPreference(Network network) {
6823         enforceAccessPermission();
6824 
6825         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
6826         if (nai != null && nai.networkCapabilities
6827                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
6828             return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
6829         }
6830 
6831         final NetworkPolicyManager netPolicyManager =
6832                  mContext.getSystemService(NetworkPolicyManager.class);
6833 
6834         final long token = Binder.clearCallingIdentity();
6835         final int networkPreference;
6836         try {
6837             networkPreference = netPolicyManager.getMultipathPreference(network);
6838         } finally {
6839             Binder.restoreCallingIdentity(token);
6840         }
6841         if (networkPreference != 0) {
6842             return networkPreference;
6843         }
6844         return mMultinetworkPolicyTracker.getMeteredMultipathPreference();
6845     }
6846 
6847     @Override
6848     public NetworkRequest getDefaultRequest() {
6849         return mDefaultRequest.mRequests.get(0);
6850     }
6851 
6852     private class InternalHandler extends Handler {
6853         public InternalHandler(Looper looper) {
6854             super(looper);
6855         }
6856 
6857         @Override
6858         public void handleMessage(Message msg) {
6859             switch (msg.what) {
6860                 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK:
6861                 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: {
6862                     handleReleaseNetworkTransitionWakelock(msg.what);
6863                     break;
6864                 }
6865                 case EVENT_APPLY_GLOBAL_HTTP_PROXY: {
6866                     mProxyTracker.loadDeprecatedGlobalHttpProxy();
6867                     break;
6868                 }
6869                 case EVENT_PAC_PROXY_HAS_CHANGED: {
6870                     final Pair<Network, ProxyInfo> arg = (Pair<Network, ProxyInfo>) msg.obj;
6871                     handlePacProxyServiceStarted(arg.first, arg.second);
6872                     break;
6873                 }
6874                 case EVENT_REGISTER_NETWORK_PROVIDER: {
6875                     handleRegisterNetworkProvider((NetworkProviderInfo) msg.obj);
6876                     break;
6877                 }
6878                 case EVENT_UNREGISTER_NETWORK_PROVIDER: {
6879                     handleUnregisterNetworkProvider((Messenger) msg.obj);
6880                     break;
6881                 }
6882                 case EVENT_REGISTER_NETWORK_OFFER: {
6883                     handleRegisterNetworkOffer((NetworkOffer) msg.obj);
6884                     break;
6885                 }
6886                 case EVENT_UNREGISTER_NETWORK_OFFER: {
6887                     final NetworkOfferInfo offer =
6888                             findNetworkOfferInfoByCallback((INetworkOfferCallback) msg.obj);
6889                     if (null != offer) {
6890                         handleUnregisterNetworkOffer(offer, true /* releaseReservations */);
6891                     }
6892                     break;
6893                 }
6894                 case EVENT_REGISTER_NETWORK_AGENT: {
6895                     final Pair<NetworkAgentInfo, INetworkMonitor> arg =
6896                             (Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj;
6897                     handleRegisterNetworkAgent(arg.first, arg.second);
6898                     break;
6899                 }
6900                 case EVENT_REGISTER_NETWORK_REQUEST:
6901                 case EVENT_REGISTER_NETWORK_LISTENER: {
6902                     handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj);
6903                     break;
6904                 }
6905                 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT:
6906                 case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: {
6907                     handleRegisterNetworkRequestWithIntent(msg);
6908                     break;
6909                 }
6910                 case EVENT_TIMEOUT_NETWORK_REQUEST: {
6911                     NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj;
6912                     handleTimedOutNetworkRequest(nri);
6913                     break;
6914                 }
6915                 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: {
6916                     handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1);
6917                     break;
6918                 }
6919                 case EVENT_RELEASE_NETWORK_REQUEST: {
6920                     handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1,
6921                             /* callOnUnavailable */ false);
6922                     break;
6923                 }
6924                 case EVENT_SET_ACCEPT_UNVALIDATED: {
6925                     Network network = (Network) msg.obj;
6926                     handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2));
6927                     break;
6928                 }
6929                 case EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY: {
6930                     Network network = (Network) msg.obj;
6931                     handleSetAcceptPartialConnectivity(network, toBool(msg.arg1),
6932                             toBool(msg.arg2));
6933                     break;
6934                 }
6935                 case EVENT_SET_AVOID_UNVALIDATED: {
6936                     handleSetAvoidUnvalidated((Network) msg.obj);
6937                     break;
6938                 }
6939                 case EVENT_INITIAL_EVALUATION_TIMEOUT: {
6940                     handleInitialEvaluationTimeout((Network) msg.obj);
6941                     break;
6942                 }
6943                 case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: {
6944                     handleConfigureAlwaysOnNetworks();
6945                     break;
6946                 }
6947                 // Sent by AutomaticOnOffKeepaliveTracker to process an app request on the
6948                 // handler thread.
6949                 case AutomaticOnOffKeepaliveTracker.CMD_REQUEST_START_KEEPALIVE: {
6950                     mKeepaliveTracker.handleStartKeepalive(msg);
6951                     break;
6952                 }
6953                 case AutomaticOnOffKeepaliveTracker.CMD_MONITOR_AUTOMATIC_KEEPALIVE: {
6954                     final AutomaticOnOffKeepalive ki =
6955                             mKeepaliveTracker.getKeepaliveForBinder((IBinder) msg.obj);
6956                     if (null == ki) return; // The callback was unregistered before the alarm fired
6957 
6958                     final Network underpinnedNetwork = ki.getUnderpinnedNetwork();
6959                     final Network network = ki.getNetwork();
6960                     final boolean networkFound =
6961                             anyNetworkAgentInfo(n -> n.network.equals(network));
6962 
6963                     // If the network no longer exists, then the keepalive should have been
6964                     // cleaned up already. There is no point trying to resume keepalives.
6965                     if (!networkFound) return;
6966 
6967                     final boolean underpinnedNetworkFound = anyNetworkAgentInfo(
6968                             n -> n.everConnected() && n.network.equals(underpinnedNetwork));
6969                     if (underpinnedNetworkFound) {
6970                         mKeepaliveTracker.handleMonitorAutomaticKeepalive(ki,
6971                                 underpinnedNetwork.netId);
6972                     } else {
6973                         // If no underpinned network, then make sure the keepalive is running.
6974                         mKeepaliveTracker.handleMaybeResumeKeepalive(ki);
6975                     }
6976                     break;
6977                 }
6978                 // Sent by KeepaliveTracker to process an app request on the state machine thread.
6979                 case NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE: {
6980                     final AutomaticOnOffKeepalive ki = mKeepaliveTracker.getKeepaliveForBinder(
6981                             (IBinder) msg.obj);
6982                     if (ki == null) {
6983                         Log.e(TAG, "Attempt to stop an already stopped keepalive");
6984                         return;
6985                     }
6986                     final int reason = msg.arg2;
6987                     mKeepaliveTracker.handleStopKeepalive(ki, reason);
6988                     break;
6989                 }
6990                 case EVENT_REPORT_NETWORK_CONNECTIVITY: {
6991                     handleReportNetworkConnectivity((NetworkAgentInfo) msg.obj, msg.arg1,
6992                             toBool(msg.arg2));
6993                     break;
6994                 }
6995                 case EVENT_PRIVATE_DNS_SETTINGS_CHANGED:
6996                     handlePrivateDnsSettingsChanged();
6997                     break;
6998                 case EVENT_PRIVATE_DNS_VALIDATION_UPDATE:
6999                     handlePrivateDnsValidationUpdate(
7000                             (PrivateDnsValidationUpdate) msg.obj);
7001                     break;
7002                 case EVENT_BLOCKED_REASONS_CHANGED:
7003                     handleBlockedReasonsChanged((List) msg.obj);
7004                     break;
7005                 case EVENT_SET_REQUIRE_VPN_FOR_UIDS:
7006                     handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj);
7007                     break;
7008                 case EVENT_SET_OEM_NETWORK_PREFERENCE: {
7009                     final Pair<OemNetworkPreferences, IOnCompleteListener> arg =
7010                             (Pair<OemNetworkPreferences, IOnCompleteListener>) msg.obj;
7011                     handleSetOemNetworkPreference(arg.first, arg.second);
7012                     break;
7013                 }
7014                 case EVENT_SET_PROFILE_NETWORK_PREFERENCE: {
7015                     final Pair<List<ProfileNetworkPreferenceInfo>, IOnCompleteListener> arg =
7016                             (Pair<List<ProfileNetworkPreferenceInfo>, IOnCompleteListener>) msg.obj;
7017                     handleSetProfileNetworkPreference(arg.first, arg.second);
7018                     break;
7019                 }
7020                 case EVENT_REPORT_NETWORK_ACTIVITY:
7021                     final NetworkActivityParams arg = (NetworkActivityParams) msg.obj;
7022                     handleReportNetworkActivity(arg);
7023                     break;
7024                 case EVENT_MOBILE_DATA_PREFERRED_UIDS_CHANGED:
7025                     handleMobileDataPreferredUidsChanged();
7026                     break;
7027                 case EVENT_SET_TEST_ALLOW_BAD_WIFI_UNTIL:
7028                     final long timeMs = ((Long) msg.obj).longValue();
7029                     mMultinetworkPolicyTracker.setTestAllowBadWifiUntil(timeMs);
7030                     break;
7031                 case EVENT_INGRESS_RATE_LIMIT_CHANGED:
7032                     handleIngressRateLimitChanged();
7033                     break;
7034                 case EVENT_USER_DOES_NOT_WANT:
7035                     final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj);
7036                     if (nai == null) break;
7037                     nai.onPreventAutomaticReconnect();
7038                     if (mQueueNetworkAgentEventsInSystemServer) {
7039                         disconnectAndDestroyNetwork(nai);
7040                     } else {
7041                         nai.disconnect();
7042                     }
7043                     break;
7044                 case EVENT_SET_VPN_NETWORK_PREFERENCE:
7045                     handleSetVpnNetworkPreference((VpnNetworkPreferenceInfo) msg.obj);
7046                     break;
7047                 case EVENT_SET_LOW_TCP_POLLING_UNTIL: {
7048                     final long time = ((Long) msg.obj).longValue();
7049                     mKeepaliveTracker.handleSetTestLowTcpPollingTimer(time);
7050                     break;
7051                 }
7052                 case EVENT_UID_FROZEN_STATE_CHANGED:
7053                     UidFrozenStateChangedArgs args = (UidFrozenStateChangedArgs) msg.obj;
7054                     handleFrozenUids(args.mUids, args.mFrozenStates);
7055                     break;
7056                 case EVENT_UPDATE_FIREWALL_DESTROY_SOCKET_REASONS:
7057                     handleUpdateFirewallDestroySocketReasons((List) msg.obj);
7058                     break;
7059                 case EVENT_CLEAR_FIREWALL_DESTROY_SOCKET_REASONS:
7060                     handleClearFirewallDestroySocketReasons(msg.arg1);
7061                     break;
7062             }
7063         }
7064     }
7065 
7066     @Override
7067     @Deprecated
7068     public int getLastTetherError(String iface) {
7069         enforceAccessPermission();
7070         final TetheringManager tm = (TetheringManager) mContext.getSystemService(
7071                 Context.TETHERING_SERVICE);
7072         return tm.getLastTetherError(iface);
7073     }
7074 
7075     @Override
7076     @Deprecated
7077     public String[] getTetherableIfaces() {
7078         enforceAccessPermission();
7079         final TetheringManager tm = (TetheringManager) mContext.getSystemService(
7080                 Context.TETHERING_SERVICE);
7081         return tm.getTetherableIfaces();
7082     }
7083 
7084     @Override
7085     @Deprecated
7086     public String[] getTetheredIfaces() {
7087         enforceAccessPermission();
7088         final TetheringManager tm = (TetheringManager) mContext.getSystemService(
7089                 Context.TETHERING_SERVICE);
7090         return tm.getTetheredIfaces();
7091     }
7092 
7093 
7094     @Override
7095     @Deprecated
7096     public String[] getTetheringErroredIfaces() {
7097         enforceAccessPermission();
7098         final TetheringManager tm = (TetheringManager) mContext.getSystemService(
7099                 Context.TETHERING_SERVICE);
7100 
7101         return tm.getTetheringErroredIfaces();
7102     }
7103 
7104     @Override
7105     @Deprecated
7106     public String[] getTetherableUsbRegexs() {
7107         enforceAccessPermission();
7108         final TetheringManager tm = (TetheringManager) mContext.getSystemService(
7109                 Context.TETHERING_SERVICE);
7110 
7111         return tm.getTetherableUsbRegexs();
7112     }
7113 
7114     @Override
7115     @Deprecated
7116     public String[] getTetherableWifiRegexs() {
7117         enforceAccessPermission();
7118         final TetheringManager tm = (TetheringManager) mContext.getSystemService(
7119                 Context.TETHERING_SERVICE);
7120         return tm.getTetherableWifiRegexs();
7121     }
7122 
7123     // Called when we lose the default network and have no replacement yet.
7124     // This will automatically be cleared after X seconds or a new default network
7125     // becomes CONNECTED, whichever happens first.  The timer is started by the
7126     // first caller and not restarted by subsequent callers.
7127     private void ensureNetworkTransitionWakelock(String forWhom) {
7128         synchronized (this) {
7129             if (mNetTransitionWakeLock.isHeld()) {
7130                 return;
7131             }
7132             mNetTransitionWakeLock.acquire();
7133             mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime();
7134             mTotalWakelockAcquisitions++;
7135         }
7136         mWakelockLogs.log("ACQUIRE for " + forWhom);
7137         Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
7138         final int lockTimeout = mResources.get().getInteger(
7139                 R.integer.config_networkTransitionTimeout);
7140         mHandler.sendMessageDelayed(msg, lockTimeout);
7141     }
7142 
7143     // Called when we gain a new default network to release the network transition wakelock in a
7144     // second, to allow a grace period for apps to reconnect over the new network. Pending expiry
7145     // message is cancelled.
7146     private void scheduleReleaseNetworkTransitionWakelock() {
7147         synchronized (this) {
7148             if (!mNetTransitionWakeLock.isHeld()) {
7149                 return; // expiry message released the lock first.
7150             }
7151         }
7152         // Cancel self timeout on wakelock hold.
7153         mHandler.removeMessages(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
7154         Message msg = mHandler.obtainMessage(EVENT_CLEAR_NET_TRANSITION_WAKELOCK);
7155         mHandler.sendMessageDelayed(msg, 1000);
7156     }
7157 
7158     // Called when either message of ensureNetworkTransitionWakelock or
7159     // scheduleReleaseNetworkTransitionWakelock is processed.
7160     private void handleReleaseNetworkTransitionWakelock(int eventId) {
7161         String event = eventName(eventId);
7162         synchronized (this) {
7163             if (!mNetTransitionWakeLock.isHeld()) {
7164                 mWakelockLogs.log(String.format("RELEASE: already released (%s)", event));
7165                 Log.w(TAG, "expected Net Transition WakeLock to be held");
7166                 return;
7167             }
7168             mNetTransitionWakeLock.release();
7169             long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
7170             mTotalWakelockDurationMs += lockDuration;
7171             mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration);
7172             mTotalWakelockReleases++;
7173         }
7174         mWakelockLogs.log(String.format("RELEASE (%s)", event));
7175     }
7176 
7177     // 100 percent is full good, 0 is full bad.
7178     @Override
7179     public void reportInetCondition(int networkType, int percentage) {
7180         NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
7181         if (nai == null) return;
7182         reportNetworkConnectivity(nai.network, percentage > 50);
7183     }
7184 
7185     @Override
7186     public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
7187         enforceAccessPermission();
7188         enforceInternetPermission();
7189         final int uid = mDeps.getCallingUid();
7190         final int connectivityInfo = encodeBool(hasConnectivity);
7191 
7192         final NetworkAgentInfo nai;
7193         if (network == null) {
7194             nai = getDefaultNetwork();
7195         } else {
7196             nai = getNetworkAgentInfoForNetwork(network);
7197         }
7198 
7199         mHandler.sendMessage(
7200                 mHandler.obtainMessage(
7201                         EVENT_REPORT_NETWORK_CONNECTIVITY, uid, connectivityInfo, nai));
7202     }
7203 
7204     private void handleReportNetworkConnectivity(
7205             @Nullable NetworkAgentInfo nai, int uid, boolean hasConnectivity) {
7206         if (nai == null
7207                 || nai != getNetworkAgentInfoForNetwork(nai.network)
7208                 || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
7209             return;
7210         }
7211         // Revalidate if the app report does not match our current validated state.
7212         if (hasConnectivity == nai.isValidated()) {
7213             mConnectivityDiagnosticsHandler.sendMessage(
7214                     mConnectivityDiagnosticsHandler.obtainMessage(
7215                             ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED,
7216                             new ReportedNetworkConnectivityInfo(
7217                                     hasConnectivity, false /* isNetworkRevalidating */, uid, nai)));
7218             return;
7219         }
7220         if (DBG) {
7221             int netid = nai.network.getNetId();
7222             log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid);
7223         }
7224         // Validating a network that has not yet connected could result in a call to
7225         // rematchNetworkAndRequests() which is not meant to work on such networks.
7226         if (!nai.everConnected()) {
7227             return;
7228         }
7229         final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
7230         if (isNetworkWithCapabilitiesBlocked(nc, uid, false)) {
7231             return;
7232         }
7233 
7234         // Send CONNECTIVITY_REPORTED event before re-validating the Network to force an ordering of
7235         // ConnDiags events. This ensures that #onNetworkConnectivityReported() will be called
7236         // before #onConnectivityReportAvailable(), which is called once Network evaluation is
7237         // completed.
7238         mConnectivityDiagnosticsHandler.sendMessage(
7239                 mConnectivityDiagnosticsHandler.obtainMessage(
7240                         ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED,
7241                         new ReportedNetworkConnectivityInfo(
7242                                 hasConnectivity, true /* isNetworkRevalidating */, uid, nai)));
7243         nai.networkMonitor().forceReevaluation(uid);
7244     }
7245 
7246     // TODO: call into netd.
7247     private boolean queryUserAccess(int uid, Network network) {
7248         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
7249         if (nai == null) return false;
7250 
7251         // Any UID can use its default network.
7252         if (nai == getDefaultNetworkForUid(uid)) return true;
7253 
7254         // Privileged apps can use any network.
7255         if (mPermissionMonitor.hasRestrictedNetworksPermission(uid)) {
7256             return true;
7257         }
7258 
7259         // An unprivileged UID can use a VPN iff the VPN applies to it.
7260         if (nai.isVPN()) {
7261             return nai.networkCapabilities.appliesToUid(uid);
7262         }
7263 
7264         // An unprivileged UID can bypass the VPN that applies to it only if it can protect its
7265         // sockets, i.e., if it is the owner.
7266         final NetworkAgentInfo vpn = getVpnForUid(uid);
7267         if (vpn != null && !vpn.networkAgentConfig.allowBypass
7268                 && uid != vpn.networkCapabilities.getOwnerUid()) {
7269             return false;
7270         }
7271 
7272         // The UID's permission must be at least sufficient for the network. Since the restricted
7273         // permission was already checked above, that just leaves background networks.
7274         if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_FOREGROUND)) {
7275             return mPermissionMonitor.hasUseBackgroundNetworksPermission(uid);
7276         }
7277 
7278         // Unrestricted network. Anyone gets to use it.
7279         return true;
7280     }
7281 
7282     /**
7283      * Returns information about the proxy a certain network is using. If given a null network, it
7284      * it will return the proxy for the bound network for the caller app or the default proxy if
7285      * none.
7286      *
7287      * @param network the network we want to get the proxy information for.
7288      * @return Proxy information if a network has a proxy configured, or otherwise null.
7289      */
7290     @Override
7291     public ProxyInfo getProxyForNetwork(Network network) {
7292         final ProxyInfo globalProxy = mProxyTracker.getGlobalProxy();
7293         if (globalProxy != null) return globalProxy;
7294         if (network == null) {
7295             // Get the network associated with the calling UID.
7296             final Network activeNetwork = getActiveNetworkForUidInternal(mDeps.getCallingUid(),
7297                     true);
7298             if (activeNetwork == null) {
7299                 return null;
7300             }
7301             return getLinkPropertiesProxyInfo(activeNetwork);
7302         } else if (mDeps.queryUserAccess(mDeps.getCallingUid(), network, this)) {
7303             // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which
7304             // caller may not have.
7305             return getLinkPropertiesProxyInfo(network);
7306         }
7307         // No proxy info available if the calling UID does not have network access.
7308         return null;
7309     }
7310 
7311 
7312     private ProxyInfo getLinkPropertiesProxyInfo(Network network) {
7313         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
7314         if (nai == null) return null;
7315         synchronized (nai) {
7316             final ProxyInfo linkHttpProxy = nai.linkProperties.getHttpProxy();
7317             return linkHttpProxy == null ? null : new ProxyInfo(linkHttpProxy);
7318         }
7319     }
7320 
7321     @Override
7322     public void setGlobalProxy(@Nullable final ProxyInfo proxyProperties) {
7323         enforceNetworkStackPermission(mContext);
7324         mProxyTracker.setGlobalProxy(proxyProperties);
7325     }
7326 
7327     @Override
7328     @Nullable
7329     public ProxyInfo getGlobalProxy() {
7330         return mProxyTracker.getGlobalProxy();
7331     }
7332 
7333     private void handlePacProxyServiceStarted(@Nullable Network net, @Nullable ProxyInfo proxy) {
7334         mProxyTracker.setDefaultProxy(proxy);
7335         final NetworkAgentInfo nai = getDefaultNetwork();
7336         // TODO : this method should check that net == nai.network, unfortunately at this point
7337         // 'net' is always null in practice (see PacProxyService#sendPacBroadcast). PAC proxy
7338         // is only ever installed on the default network so in practice this is okay.
7339         if (null == nai) return;
7340         // PAC proxies only work on the default network. Therefore, only the default network
7341         // should have its link properties fixed up for PAC proxies.
7342         mProxyTracker.updateDefaultNetworkProxyPortForPAC(nai.linkProperties, nai.network);
7343         if (nai.everConnected()) {
7344             notifyNetworkCallbacks(nai, CALLBACK_IP_CHANGED);
7345         }
7346     }
7347 
7348     // If the proxy has changed from oldLp to newLp, resend proxy broadcast. This method gets called
7349     // when any network changes proxy.
7350     // TODO: Remove usage of broadcast extras as they are deprecated and not applicable in a
7351     // multi-network world where an app might be bound to a non-default network.
7352     private void updateProxy(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp) {
7353         ProxyInfo newProxyInfo = newLp.getHttpProxy();
7354         ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
7355 
7356         if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
7357             mProxyTracker.sendProxyBroadcast();
7358         }
7359     }
7360 
7361     private static class SettingsObserver extends ContentObserver {
7362         final private HashMap<Uri, Integer> mUriEventMap;
7363         final private Context mContext;
7364         final private Handler mHandler;
7365 
7366         SettingsObserver(Context context, Handler handler) {
7367             super(null);
7368             mUriEventMap = new HashMap<>();
7369             mContext = context;
7370             mHandler = handler;
7371         }
7372 
7373         void observe(Uri uri, int what) {
7374             mUriEventMap.put(uri, what);
7375             final ContentResolver resolver = mContext.getContentResolver();
7376             resolver.registerContentObserver(uri, false, this);
7377         }
7378 
7379         @Override
7380         public void onChange(boolean selfChange) {
7381             Log.wtf(TAG, "Should never be reached.");
7382         }
7383 
7384         @Override
7385         public void onChange(boolean selfChange, Uri uri) {
7386             final Integer what = mUriEventMap.get(uri);
7387             if (what != null) {
7388                 mHandler.obtainMessage(what).sendToTarget();
7389             } else {
7390                 loge("No matching event to send for URI=" + uri);
7391             }
7392         }
7393     }
7394 
7395     private static void log(String s) {
7396         Log.d(TAG, s);
7397     }
7398 
7399     private static void logw(String s) {
7400         Log.w(TAG, s);
7401     }
7402 
7403     private static void logwtf(String s) {
7404         Log.wtf(TAG, s);
7405     }
7406 
7407     private static void logwtf(String s, Throwable t) {
7408         Log.wtf(TAG, s, t);
7409     }
7410 
7411     private static void loge(String s) {
7412         Log.e(TAG, s);
7413     }
7414 
7415     private static void loge(String s, Throwable t) {
7416         Log.e(TAG, s, t);
7417     }
7418 
7419     /**
7420      * Return the information of all ongoing VPNs.
7421      *
7422      * <p>This method is used to update NetworkStatsService.
7423      *
7424      * <p>Must be called on the handler thread.
7425      */
7426     private UnderlyingNetworkInfo[] getAllVpnInfo() {
7427         ensureRunningOnConnectivityServiceThread();
7428         if (mLockdownEnabled) {
7429             return new UnderlyingNetworkInfo[0];
7430         }
7431         List<UnderlyingNetworkInfo> infoList = new ArrayList<>();
7432         forEachNetworkAgentInfo(nai -> {
7433             UnderlyingNetworkInfo info = createVpnInfo(nai);
7434             if (info != null) {
7435                 infoList.add(info);
7436             }
7437         });
7438         return infoList.toArray(new UnderlyingNetworkInfo[infoList.size()]);
7439     }
7440 
7441     /**
7442      * @return VPN information for accounting, or null if we can't retrieve all required
7443      *         information, e.g underlying ifaces.
7444      */
7445     private UnderlyingNetworkInfo createVpnInfo(NetworkAgentInfo nai) {
7446         Network[] underlyingNetworks = nai.declaredUnderlyingNetworks;
7447         // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret
7448         // the underlyingNetworks list.
7449         // TODO: stop using propagateUnderlyingCapabilities here, for example, by always
7450         // initializing NetworkAgentInfo#declaredUnderlyingNetworks to an empty array.
7451         if (underlyingNetworks == null && nai.propagateUnderlyingCapabilities()) {
7452             final NetworkAgentInfo defaultNai = getDefaultNetworkForUid(
7453                     nai.networkCapabilities.getOwnerUid());
7454             if (defaultNai != null) {
7455                 underlyingNetworks = new Network[] { defaultNai.network };
7456             }
7457         }
7458 
7459         if (CollectionUtils.isEmpty(underlyingNetworks)) return null;
7460 
7461         List<String> interfaces = new ArrayList<>();
7462         for (Network network : underlyingNetworks) {
7463             NetworkAgentInfo underlyingNai = getNetworkAgentInfoForNetwork(network);
7464             if (underlyingNai == null) continue;
7465             LinkProperties lp = underlyingNai.linkProperties;
7466             for (String iface : lp.getAllInterfaceNames()) {
7467                 if (!TextUtils.isEmpty(iface)) {
7468                     interfaces.add(iface);
7469                 }
7470             }
7471         }
7472 
7473         if (interfaces.isEmpty()) return null;
7474 
7475         // Must be non-null or NetworkStatsService will crash.
7476         // Cannot happen in production code because Vpn only registers the NetworkAgent after the
7477         // tun or ipsec interface is created.
7478         // TODO: Remove this check.
7479         if (nai.linkProperties.getInterfaceName() == null) return null;
7480 
7481         return new UnderlyingNetworkInfo(nai.networkCapabilities.getOwnerUid(),
7482                 nai.linkProperties.getInterfaceName(), interfaces);
7483     }
7484 
7485     // TODO This needs to be the default network that applies to the NAI.
7486     private Network[] underlyingNetworksOrDefault(final int ownerUid,
7487             Network[] underlyingNetworks) {
7488         final Network defaultNetwork = getNetwork(getDefaultNetworkForUid(ownerUid));
7489         if (underlyingNetworks == null && defaultNetwork != null) {
7490             // null underlying networks means to track the default.
7491             underlyingNetworks = new Network[] { defaultNetwork };
7492         }
7493         return underlyingNetworks;
7494     }
7495 
7496     // Returns true iff |network| is an underlying network of |nai|.
7497     private boolean hasUnderlyingNetwork(NetworkAgentInfo nai, Network network) {
7498         // TODO: support more than one level of underlying networks, either via a fixed-depth search
7499         // (e.g., 2 levels of underlying networks), or via loop detection, or....
7500         if (!nai.propagateUnderlyingCapabilities()) return false;
7501         final Network[] underlying = underlyingNetworksOrDefault(
7502                 nai.networkCapabilities.getOwnerUid(), nai.declaredUnderlyingNetworks);
7503         return CollectionUtils.contains(underlying, network);
7504     }
7505 
7506     /**
7507      * Recompute the capabilities for any networks that had a specific network as underlying.
7508      *
7509      * When underlying networks change, such networks may have to update capabilities to reflect
7510      * things like the metered bit, their transports, and so on. The capabilities are calculated
7511      * immediately. This method runs on the ConnectivityService thread.
7512      */
7513     private void propagateUnderlyingNetworkCapabilities(Network updatedNetwork) {
7514         ensureRunningOnConnectivityServiceThread();
7515         forEachNetworkAgentInfo(nai -> {
7516             if (updatedNetwork == null || hasUnderlyingNetwork(nai, updatedNetwork)) {
7517                 updateCapabilitiesForNetwork(nai);
7518             }
7519         });
7520     }
7521 
7522     private boolean isUidBlockedByVpn(int uid, List<UidRange> blockedUidRanges) {
7523         // Determine whether this UID is blocked because of always-on VPN lockdown. If a VPN applies
7524         // to the UID, then the UID is not blocked because always-on VPN lockdown applies only when
7525         // a VPN is not up.
7526         final NetworkAgentInfo vpnNai = getVpnForUid(uid);
7527         if (vpnNai != null && !vpnNai.networkAgentConfig.allowBypass) return false;
7528         for (UidRange range : blockedUidRanges) {
7529             if (range.contains(uid)) return true;
7530         }
7531         return false;
7532     }
7533 
7534     @Override
7535     public void setRequireVpnForUids(boolean requireVpn, UidRange[] ranges) {
7536         enforceNetworkStackOrSettingsPermission();
7537         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_REQUIRE_VPN_FOR_UIDS,
7538                 encodeBool(requireVpn), 0 /* arg2 */, ranges));
7539     }
7540 
7541     private void handleSetRequireVpnForUids(boolean requireVpn, UidRange[] ranges) {
7542         if (DBG) {
7543             Log.d(TAG, "Setting VPN " + (requireVpn ? "" : "not ") + "required for UIDs: "
7544                     + Arrays.toString(ranges));
7545         }
7546         // Cannot use a Set since the list of UID ranges might contain duplicates.
7547         final List<UidRange> newVpnBlockedUidRanges = new ArrayList(mVpnBlockedUidRanges);
7548         for (int i = 0; i < ranges.length; i++) {
7549             if (requireVpn) {
7550                 newVpnBlockedUidRanges.add(ranges[i]);
7551             } else {
7552                 newVpnBlockedUidRanges.remove(ranges[i]);
7553             }
7554         }
7555 
7556         try {
7557             mNetd.networkRejectNonSecureVpn(requireVpn, toUidRangeStableParcels(ranges));
7558         } catch (RemoteException | ServiceSpecificException e) {
7559             Log.e(TAG, "setRequireVpnForUids(" + requireVpn + ", "
7560                     + Arrays.toString(ranges) + "): netd command failed: " + e);
7561         }
7562 
7563         if (mDeps.isAtLeastT()) {
7564             mPermissionMonitor.updateVpnLockdownUidRanges(requireVpn, ranges);
7565         }
7566 
7567         forEachNetworkAgentInfo(nai -> {
7568             final boolean curMetered = nai.networkCapabilities.isMetered();
7569             maybeNotifyNetworkBlocked(nai, curMetered, curMetered,
7570                     mVpnBlockedUidRanges, newVpnBlockedUidRanges);
7571         });
7572 
7573         mVpnBlockedUidRanges = newVpnBlockedUidRanges;
7574     }
7575 
7576     @Override
7577     public void setLegacyLockdownVpnEnabled(boolean enabled) {
7578         enforceNetworkStackOrSettingsPermission();
7579         mHandler.post(() -> mLockdownEnabled = enabled);
7580     }
7581 
7582     private boolean isLegacyLockdownNai(NetworkAgentInfo nai) {
7583         return mLockdownEnabled
7584                 && isLegacyVpn(nai)
7585                 && nai.networkCapabilities.appliesToUid(Process.FIRST_APPLICATION_UID);
7586     }
7587 
7588     private NetworkAgentInfo getLegacyLockdownNai() {
7589         if (!mLockdownEnabled) {
7590             return null;
7591         }
7592         // The legacy lockdown VPN always only applies to userId 0.
7593         final NetworkAgentInfo nai = getVpnForUid(Process.FIRST_APPLICATION_UID);
7594         if (nai == null || !isLegacyLockdownNai(nai)) return null;
7595 
7596         // The legacy lockdown VPN must always have exactly one underlying network.
7597         // This code may run on any thread and declaredUnderlyingNetworks may change, so store it in
7598         // a local variable. There is no need to make a copy because its contents cannot change.
7599         final Network[] underlying = nai.declaredUnderlyingNetworks;
7600         if (underlying == null ||  underlying.length != 1) {
7601             return null;
7602         }
7603 
7604         // The legacy lockdown VPN always uses the default network.
7605         // If the VPN's underlying network is no longer the current default network, it means that
7606         // the default network has just switched, and the VPN is about to disconnect.
7607         // Report that the VPN is not connected, so the state of NetworkInfo objects overwritten
7608         // by filterForLegacyLockdown will be set to CONNECTING and not CONNECTED.
7609         final NetworkAgentInfo defaultNetwork = getDefaultNetwork();
7610         if (defaultNetwork == null || !defaultNetwork.network.equals(underlying[0])) {
7611             return null;
7612         }
7613 
7614         return nai;
7615     };
7616 
7617     // TODO: move all callers to filterForLegacyLockdown and delete this method.
7618     // This likely requires making sendLegacyNetworkBroadcast take a NetworkInfo object instead of
7619     // just a DetailedState object.
7620     private DetailedState getLegacyLockdownState(DetailedState origState) {
7621         if (origState != DetailedState.CONNECTED) {
7622             return origState;
7623         }
7624         return (mLockdownEnabled && getLegacyLockdownNai() == null)
7625                 ? DetailedState.CONNECTING
7626                 : DetailedState.CONNECTED;
7627     }
7628 
7629     private void filterForLegacyLockdown(NetworkInfo ni) {
7630         if (!mLockdownEnabled || !ni.isConnected()) return;
7631         // The legacy lockdown VPN replaces the state of every network in CONNECTED state with the
7632         // state of its VPN. This is to ensure that when an underlying network connects, apps will
7633         // not see a CONNECTIVITY_ACTION broadcast for a network in state CONNECTED until the VPN
7634         // comes up, at which point there is a new CONNECTIVITY_ACTION broadcast for the underlying
7635         // network, this time with a state of CONNECTED.
7636         //
7637         // Now that the legacy lockdown code lives in ConnectivityService, and no longer has access
7638         // to the internal state of the Vpn object, always replace the state with CONNECTING. This
7639         // is not too far off the truth, since an always-on VPN, when not connected, is always
7640         // trying to reconnect.
7641         if (getLegacyLockdownNai() == null) {
7642             ni.setDetailedState(DetailedState.CONNECTING, "", null);
7643         }
7644     }
7645 
7646     @Override
7647     public void setProvisioningNotificationVisible(boolean visible, int networkType,
7648             String action) {
7649         enforceSettingsPermission();
7650         if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
7651             return;
7652         }
7653         final long ident = Binder.clearCallingIdentity();
7654         try {
7655             // Concatenate the range of types onto the range of NetIDs.
7656             int id = NetIdManager.MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE);
7657             mNotifier.setProvNotificationVisible(visible, id, action);
7658         } finally {
7659             Binder.restoreCallingIdentity(ident);
7660         }
7661     }
7662 
7663     @Override
7664     public void setAirplaneMode(boolean enable) {
7665         enforceAirplaneModePermission();
7666         final long ident = Binder.clearCallingIdentity();
7667         try {
7668             final ContentResolver cr = mContext.getContentResolver();
7669             Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, encodeBool(enable));
7670             Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
7671             intent.putExtra("state", enable);
7672             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
7673         } finally {
7674             Binder.restoreCallingIdentity(ident);
7675         }
7676     }
7677 
7678     private void onUserAdded(@NonNull final UserHandle user) {
7679         if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) {
7680             handleSetOemNetworkPreference(mOemNetworkPreferences, null);
7681         }
7682         updateProfileAllowedNetworks();
7683     }
7684 
7685     private void onUserRemoved(@NonNull final UserHandle user) {
7686         // If there was a network preference for this user, remove it.
7687         handleSetProfileNetworkPreference(
7688                 List.of(new ProfileNetworkPreferenceInfo(user, null, true,
7689                         false /* blockingNonEnterprise */)),
7690                 null /* listener */);
7691         if (mOemNetworkPreferences.getNetworkPreferences().size() > 0) {
7692             handleSetOemNetworkPreference(mOemNetworkPreferences, null);
7693         }
7694     }
7695 
7696     private void onPackageChanged(@NonNull final String packageName) {
7697         // This is necessary in case a package is added or removed, but also when it's replaced to
7698         // run as a new UID by its manifest rules. Also, if a separate package shares the same UID
7699         // as one in the preferences, then it should follow the same routing as that other package,
7700         // which means updating the rules is never to be needed in this case (whether it joins or
7701         // leaves a UID with a preference).
7702         if (isMappedInOemNetworkPreference(packageName)) {
7703             handleSetOemNetworkPreference(mOemNetworkPreferences, null);
7704         }
7705 
7706         // Invalidates cache entry when the package is updated.
7707         synchronized (mSelfCertifiedCapabilityCache) {
7708             mSelfCertifiedCapabilityCache.remove(packageName);
7709         }
7710     }
7711 
7712     private final BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
7713         @Override
7714         public void onReceive(Context context, Intent intent) {
7715             ensureRunningOnConnectivityServiceThread();
7716             final String action = intent.getAction();
7717             final UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
7718 
7719             // User should be filled for below intents, check the existence.
7720             if (user == null) {
7721                 Log.wtf(TAG, intent.getAction() + " broadcast without EXTRA_USER");
7722                 return;
7723             }
7724 
7725             if (Intent.ACTION_USER_ADDED.equals(action)) {
7726                 onUserAdded(user);
7727             } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
7728                 onUserRemoved(user);
7729             }  else {
7730                 Log.wtf(TAG, "received unexpected intent: " + action);
7731             }
7732         }
7733     };
7734 
7735     private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() {
7736         @Override
7737         public void onReceive(Context context, Intent intent) {
7738             ensureRunningOnConnectivityServiceThread();
7739             switch (intent.getAction()) {
7740                 case Intent.ACTION_PACKAGE_ADDED:
7741                 case Intent.ACTION_PACKAGE_REMOVED:
7742                 case Intent.ACTION_PACKAGE_REPLACED:
7743                     onPackageChanged(intent.getData().getSchemeSpecificPart());
7744                     break;
7745                 default:
7746                     Log.wtf(TAG, "received unexpected intent: " + intent.getAction());
7747             }
7748         }
7749     };
7750 
7751     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
7752     private final BroadcastReceiver mDataSaverReceiver = new BroadcastReceiver() {
7753         @Override
7754         public void onReceive(Context context, Intent intent) {
7755             if (mDeps.isAtLeastV()) {
7756                 throw new IllegalStateException(
7757                         "data saver status should be updated from platform");
7758             }
7759             ensureRunningOnConnectivityServiceThread();
7760             switch (intent.getAction()) {
7761                 case ACTION_RESTRICT_BACKGROUND_CHANGED:
7762                     // If the uid is present in the deny list, the API will consistently
7763                     // return ENABLED. To retrieve the global switch status, the system
7764                     // uid is chosen because it will never be included in the deny list.
7765                     final int dataSaverForSystemUid =
7766                             mPolicyManager.getRestrictBackgroundStatus(Process.SYSTEM_UID);
7767                     final boolean isDataSaverEnabled = (dataSaverForSystemUid
7768                             != ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED);
7769                     mBpfNetMaps.setDataSaverEnabled(isDataSaverEnabled);
7770                     break;
7771                 default:
7772                     Log.wtf(TAG, "received unexpected intent: " + intent.getAction());
7773             }
7774         }
7775     };
7776 
7777     private final HashMap<Messenger, NetworkProviderInfo> mNetworkProviderInfos = new HashMap<>();
7778     private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>();
7779 
7780     private static class NetworkProviderInfo {
7781         public final String name;
7782         public final Messenger messenger;
7783         private final IBinder.DeathRecipient mDeathRecipient;
7784         public final int providerId;
7785 
7786         NetworkProviderInfo(String name, Messenger messenger, int providerId,
7787                 @NonNull IBinder.DeathRecipient deathRecipient) {
7788             this.name = name;
7789             this.messenger = messenger;
7790             this.providerId = providerId;
7791             mDeathRecipient = deathRecipient;
7792 
7793             if (mDeathRecipient == null) {
7794                 throw new AssertionError("Must pass a deathRecipient");
7795             }
7796         }
7797 
7798         void connect(Context context, Handler handler) {
7799             try {
7800                 messenger.getBinder().linkToDeath(mDeathRecipient, 0);
7801             } catch (RemoteException e) {
7802                 mDeathRecipient.binderDied();
7803             }
7804         }
7805     }
7806 
7807     private void ensureAllNetworkRequestsHaveSupportedType(List<NetworkRequest> requests) {
7808         final boolean isMultilayerRequest = requests.size() > 1;
7809         for (int i = 0; i < requests.size(); i++) {
7810             ensureNetworkRequestHasSupportedType(requests.get(i), isMultilayerRequest);
7811         }
7812     }
7813 
7814     private void ensureNetworkRequestHasSupportedType(NetworkRequest request,
7815             boolean isMultilayerRequest) {
7816         if (request.type == NetworkRequest.Type.NONE) {
7817             throw new IllegalArgumentException(
7818                     "All NetworkRequests in ConnectivityService must have a type");
7819         }
7820         if (isMultilayerRequest && request.type == NetworkRequest.Type.RESERVATION) {
7821             throw new IllegalArgumentException(
7822                     "Reservation requests are not supported in multilayer request");
7823         }
7824     }
7825 
7826     /**
7827      * Tracks info about the requester.
7828      * Also used to notice when the calling process dies so as to self-expire
7829      */
7830     @VisibleForTesting
7831     protected class NetworkRequestInfo implements IBinder.DeathRecipient {
7832         // The requests to be satisfied in priority order. Non-multilayer requests will only have a
7833         // single NetworkRequest in mRequests.
7834         final List<NetworkRequest> mRequests;
7835 
7836         /**
7837          * List of callbacks that are queued for sending later when the requesting app is unfrozen.
7838          *
7839          * <p>There may typically be hundreds of NetworkRequestInfo, so a memory-efficient structure
7840          * (just an int[]) is used to keep queued callbacks. This reduces the number of object
7841          * references.
7842          *
7843          * <p>This is intended to be used with {@link CallbackQueue} which defines the internal
7844          * format.
7845          */
7846         @NonNull
7847         private int[] mQueuedCallbacks = new int[0];
7848 
7849         private static final int MATCHED_NETID_NOT_FROZEN = -1;
7850 
7851         /**
7852          * If this request was already satisfied by a network when the requesting UID was frozen,
7853          * the netId that was matched at that time. Otherwise, NETID_UNSET if no network was
7854          * satisfying this request when frozen (including if this is a listen and not a request),
7855          * and MATCHED_NETID_NOT_FROZEN if not frozen.
7856          */
7857         private int mMatchedNetIdWhenFrozen = MATCHED_NETID_NOT_FROZEN;
7858 
7859         // mSatisfier and mActiveRequest rely on one another therefore set them together.
7860         void setSatisfier(
7861                 @Nullable final NetworkAgentInfo satisfier,
7862                 @Nullable final NetworkRequest activeRequest) {
7863             mSatisfier = satisfier;
7864             mActiveRequest = activeRequest;
7865         }
7866 
7867         // The network currently satisfying this NRI. Only one request in an NRI can have a
7868         // satisfier. For non-multilayer requests, only non-listen requests can have a satisfier.
7869         @Nullable
7870         private NetworkAgentInfo mSatisfier;
7871         NetworkAgentInfo getSatisfier() {
7872             return mSatisfier;
7873         }
7874 
7875         // The request in mRequests assigned to a network agent. This is null if none of the
7876         // requests in mRequests can be satisfied. This member has the constraint of only being
7877         // accessible on the handler thread.
7878         @Nullable
7879         private NetworkRequest mActiveRequest;
7880         NetworkRequest getActiveRequest() {
7881             return mActiveRequest;
7882         }
7883 
7884         final PendingIntent mPendingIntent;
7885         boolean mPendingIntentSent;
7886         @Nullable
7887         final Messenger mMessenger;
7888 
7889         // Information about the caller that caused this object to be created.
7890         @Nullable
7891         private final IBinder mBinder;
7892         final int mPid;
7893         final int mUid;
7894         final @NetworkCallback.Flag int mCallbackFlags;
7895         @Nullable
7896         final String mCallingAttributionTag;
7897 
7898         // Counter keeping track of this NRI.
7899         final RequestInfoPerUidCounter mPerUidCounter;
7900 
7901         // Effective UID of this request. This is different from mUid when a privileged process
7902         // files a request on behalf of another UID. This UID is used to determine blocked status,
7903         // UID matching, and so on. mUid above is used for permission checks and to enforce the
7904         // maximum limit of registered callbacks per UID.
7905         final int mAsUid;
7906 
7907         // Flag to indicate that uid of this nri is tracked for sending blocked status callbacks.
7908         // It is always true on V+ if mMessenger != null. As such, it's not strictly necessary.
7909         // it's used only as a safeguard to avoid double counting or leaking.
7910         boolean mUidTrackedForBlockedStatus;
7911 
7912         // Preference order of this request.
7913         final int mPreferenceOrder;
7914 
7915         final int mDeclaredMethodsFlags;
7916 
7917         // In order to preserve the mapping of NetworkRequest-to-callback when apps register
7918         // callbacks using a returned NetworkRequest, the original NetworkRequest needs to be
7919         // maintained for keying off of. This is only a concern when the original nri
7920         // mNetworkRequests changes which happens currently for apps that register callbacks to
7921         // track the default network. In those cases, the nri is updated to have mNetworkRequests
7922         // that match the per-app default nri that currently tracks the calling app's uid so that
7923         // callbacks are fired at the appropriate time. When the callbacks fire,
7924         // mNetworkRequestForCallback will be used so as to preserve the caller's mapping. When
7925         // callbacks are updated to key off of an nri vs NetworkRequest, this stops being an issue.
7926         // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects.
7927         @NonNull
7928         private final NetworkRequest mNetworkRequestForCallback;
7929         NetworkRequest getNetworkRequestForCallback() {
7930             return mNetworkRequestForCallback;
7931         }
7932 
7933         /**
7934          * NetworkCapabilities that were created as part of a NetworkOffer in response to a
7935          * RESERVATION request. mReservedCapabilities is null if no current offer matches the
7936          * RESERVATION request or if the request is not a RESERVATION. Matching is based on
7937          * reservationId.
7938          */
7939         @Nullable
7940         private NetworkCapabilities mReservedCapabilities;
7941         @Nullable
7942         NetworkCapabilities getReservedCapabilities() {
7943             return mReservedCapabilities;
7944         }
7945 
7946         void setReservedCapabilities(@NonNull NetworkCapabilities caps) {
7947             // This function can only be called once. NetworkCapabilities are never reset as the
7948             // reservation is released when the offer disappears.
7949             if (mReservedCapabilities != null) {
7950                 logwtf("ReservedCapabilities can only be set once");
7951             }
7952             mReservedCapabilities = caps;
7953         }
7954 
7955         /**
7956          * Get the list of UIDs this nri applies to.
7957          */
7958         @NonNull
7959         Set<UidRange> getUids() {
7960             // networkCapabilities.getUids() returns a defensive copy.
7961             // multilayer requests will all have the same uids so return the first one.
7962             final Set<UidRange> uids = mRequests.get(0).networkCapabilities.getUidRanges();
7963             return (null == uids) ? new ArraySet<>() : uids;
7964         }
7965 
7966         NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r,
7967                 @Nullable final PendingIntent pi, @Nullable String callingAttributionTag) {
7968             this(asUid, Collections.singletonList(r), r, pi, callingAttributionTag,
7969                     PREFERENCE_ORDER_INVALID);
7970         }
7971 
7972         NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
7973                 @NonNull final NetworkRequest requestForCallback, @Nullable final PendingIntent pi,
7974                 @Nullable String callingAttributionTag, final int preferenceOrder) {
7975             ensureAllNetworkRequestsHaveSupportedType(r);
7976             mRequests = initializeRequests(r);
7977             mNetworkRequestForCallback = requestForCallback;
7978             mPendingIntent = pi;
7979             mMessenger = null;
7980             mBinder = null;
7981             mPid = getCallingPid();
7982             mUid = mDeps.getCallingUid();
7983             mAsUid = asUid;
7984             mPerUidCounter = getRequestCounter(this);
7985             /**
7986              * Location sensitive data not included in pending intent. Only included in
7987              * {@link NetworkCallback}.
7988              */
7989             mCallbackFlags = NetworkCallback.FLAG_NONE;
7990             mCallingAttributionTag = callingAttributionTag;
7991             mPreferenceOrder = preferenceOrder;
7992             mDeclaredMethodsFlags = DECLARED_METHODS_NONE;
7993         }
7994 
7995         NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r, @Nullable final Messenger m,
7996                 @Nullable final IBinder binder,
7997                 @NetworkCallback.Flag int callbackFlags,
7998                 @Nullable String callingAttributionTag, int declaredMethodsFlags) {
7999             this(asUid, Collections.singletonList(r), r, m, binder, callbackFlags,
8000                     callingAttributionTag, declaredMethodsFlags);
8001         }
8002 
8003         NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
8004                 @NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m,
8005                 @Nullable final IBinder binder,
8006                 @NetworkCallback.Flag int callbackFlags,
8007                 @Nullable String callingAttributionTag, int declaredMethodsFlags) {
8008             super();
8009             ensureAllNetworkRequestsHaveSupportedType(r);
8010             mRequests = initializeRequests(r);
8011             mNetworkRequestForCallback = requestForCallback;
8012             mMessenger = m;
8013             mBinder = binder;
8014             mPid = getCallingPid();
8015             mUid = mDeps.getCallingUid();
8016             mAsUid = asUid;
8017             mPendingIntent = null;
8018             mPerUidCounter = getRequestCounter(this);
8019             mCallbackFlags = callbackFlags;
8020             mCallingAttributionTag = callingAttributionTag;
8021             mPreferenceOrder = PREFERENCE_ORDER_INVALID;
8022             mDeclaredMethodsFlags = declaredMethodsFlags;
8023             linkDeathRecipient();
8024         }
8025 
8026         NetworkRequestInfo(@NonNull final NetworkRequestInfo nri,
8027                 @NonNull final List<NetworkRequest> r) {
8028             super();
8029             ensureAllNetworkRequestsHaveSupportedType(r);
8030             mRequests = initializeRequests(r);
8031             mNetworkRequestForCallback = nri.getNetworkRequestForCallback();
8032             final NetworkAgentInfo satisfier = nri.getSatisfier();
8033             if (null != satisfier) {
8034                 // If the old NRI was satisfied by an NAI, then it may have had an active request.
8035                 // The active request is necessary to figure out what callbacks to send, in
8036                 // particular when a network updates its capabilities.
8037                 // As this code creates a new NRI with a new set of requests, figure out which of
8038                 // the list of requests should be the active request. It is always the first
8039                 // request of the list that can be satisfied by the satisfier since the order of
8040                 // requests is a priority order.
8041                 // Note even in the presence of a satisfier there may not be an active request,
8042                 // when the satisfier is the no-service network.
8043                 NetworkRequest activeRequest = null;
8044                 for (final NetworkRequest candidate : r) {
8045                     if (candidate.canBeSatisfiedBy(satisfier.networkCapabilities)) {
8046                         activeRequest = candidate;
8047                         break;
8048                     }
8049                 }
8050                 setSatisfier(satisfier, activeRequest);
8051             }
8052             mMatchedNetIdWhenFrozen = nri.mMatchedNetIdWhenFrozen;
8053             mQueuedCallbacks = nri.mQueuedCallbacks;
8054             mMessenger = nri.mMessenger;
8055             mBinder = nri.mBinder;
8056             mPid = nri.mPid;
8057             mUid = nri.mUid;
8058             mAsUid = nri.mAsUid;
8059             mPendingIntent = nri.mPendingIntent;
8060             mPerUidCounter = nri.mPerUidCounter;
8061             mCallbackFlags = nri.mCallbackFlags;
8062             mCallingAttributionTag = nri.mCallingAttributionTag;
8063             mUidTrackedForBlockedStatus = nri.mUidTrackedForBlockedStatus;
8064             mPreferenceOrder = PREFERENCE_ORDER_INVALID;
8065             mDeclaredMethodsFlags = nri.mDeclaredMethodsFlags;
8066             linkDeathRecipient();
8067         }
8068 
8069         NetworkRequestInfo(int asUid, @NonNull final NetworkRequest r) {
8070             this(asUid, Collections.singletonList(r), PREFERENCE_ORDER_INVALID);
8071         }
8072 
8073         NetworkRequestInfo(int asUid, @NonNull final List<NetworkRequest> r,
8074                 final int preferenceOrder) {
8075             this(asUid, r, r.get(0), null /* pi */, null /* callingAttributionTag */,
8076                     preferenceOrder);
8077         }
8078 
8079         // True if this NRI is being satisfied. It also accounts for if the nri has its satisifer
8080         // set to the mNoServiceNetwork in which case mActiveRequest will be null thus returning
8081         // false.
8082         boolean isBeingSatisfied() {
8083             return (null != mSatisfier && null != mActiveRequest);
8084         }
8085 
8086         boolean isMultilayerRequest() {
8087             return mRequests.size() > 1;
8088         }
8089 
8090         private List<NetworkRequest> initializeRequests(List<NetworkRequest> r) {
8091             // Creating a defensive copy to prevent the sender from modifying the list being
8092             // reflected in the return value of this method.
8093             final List<NetworkRequest> tempRequests = new ArrayList<>(r);
8094             return Collections.unmodifiableList(tempRequests);
8095         }
8096 
8097         void linkDeathRecipient() {
8098             if (null != mBinder) {
8099                 try {
8100                     mBinder.linkToDeath(this, 0);
8101                 } catch (RemoteException e) {
8102                     binderDied();
8103                 }
8104             }
8105         }
8106 
8107         void unlinkDeathRecipient() {
8108             if (null != mBinder) {
8109                 try {
8110                     mBinder.unlinkToDeath(this, 0);
8111                 } catch (NoSuchElementException e) {
8112                     // Temporary workaround for b/194394697 pending analysis of additional logs
8113                     Log.wtf(TAG, "unlinkToDeath for already unlinked NRI " + this);
8114                 }
8115             }
8116         }
8117 
8118         /**
8119          * Called when this NRI is being frozen.
8120          *
8121          * <p>Calling this method multiple times when the NRI is frozen is fine. This may happen
8122          * if iterating through the NetworkRequest -> NRI map since there are duplicates in the
8123          * NRI values for multilayer requests. It may also happen if an app is frozen, killed,
8124          * restarted and refrozen since there is no callback sent when processes are killed, but in
8125          * that case the callbacks to the killed app do not matter.
8126          */
8127         void onFrozen() {
8128             if (mMatchedNetIdWhenFrozen != MATCHED_NETID_NOT_FROZEN) {
8129                 // Already frozen
8130                 return;
8131             }
8132             if (mSatisfier != null) {
8133                 mMatchedNetIdWhenFrozen = mSatisfier.network.netId;
8134             } else {
8135                 mMatchedNetIdWhenFrozen = NETID_UNSET;
8136             }
8137         }
8138 
8139         boolean maybeQueueCallback(@NonNull NetworkAgentInfo nai, int callbackId) {
8140             if (mMatchedNetIdWhenFrozen == MATCHED_NETID_NOT_FROZEN) {
8141                 return false;
8142             }
8143 
8144             boolean ignoreThisCallback = false;
8145             final int netId = nai.network.netId;
8146             final CallbackQueue queue = new CallbackQueue(mQueuedCallbacks);
8147             // Based on the new callback, clear previous callbacks that are no longer necessary.
8148             // For example, if the network is lost, there is no need to send intermediate callbacks.
8149             switch (callbackId) {
8150                 // PRECHECK is not an API and not very meaningful, do not deliver it for frozen apps
8151                 // Networks are likely to already be lost when the app is unfrozen, also skip LOSING
8152                 case CALLBACK_PRECHECK:
8153                 case CALLBACK_LOSING:
8154                     ignoreThisCallback = true;
8155                     break;
8156                 case CALLBACK_LOST:
8157                     // All callbacks for this netId before onLost are unnecessary. And onLost itself
8158                     // is also unnecessary if onAvailable was previously queued for this netId: the
8159                     // Network just appeared and disappeared while the app was frozen.
8160                     ignoreThisCallback = queue.hasCallback(netId, CALLBACK_AVAILABLE);
8161                     queue.removeCallbacksForNetId(netId);
8162                     break;
8163                 case CALLBACK_AVAILABLE:
8164                     if (mSatisfier != null) {
8165                         // For requests that are satisfied by individual networks (not LISTEN), when
8166                         // AVAILABLE is received, the request is matching a new Network, so previous
8167                         // callbacks (for other Networks) are unnecessary.
8168                         queue.clear();
8169                     }
8170                     break;
8171                 case CALLBACK_SUSPENDED:
8172                 case CALLBACK_RESUMED:
8173                     if (queue.hasCallback(netId, CALLBACK_AVAILABLE)) {
8174                         // AVAILABLE will already send the latest suspended status
8175                         ignoreThisCallback = true;
8176                         break;
8177                     }
8178                     // If SUSPENDED was queued, just remove it from the queue instead of sending
8179                     // RESUMED; and vice-versa.
8180                     final int otherCb = callbackId == CALLBACK_SUSPENDED
8181                             ? CALLBACK_RESUMED
8182                             : CALLBACK_SUSPENDED;
8183                     ignoreThisCallback = queue.removeCallbacks(netId, otherCb);
8184                     break;
8185                 case CALLBACK_CAP_CHANGED:
8186                 case CALLBACK_IP_CHANGED:
8187                 case CALLBACK_LOCAL_NETWORK_INFO_CHANGED:
8188                 case CALLBACK_BLK_CHANGED:
8189                     ignoreThisCallback = queue.hasCallback(netId, CALLBACK_AVAILABLE);
8190                     break;
8191                 default:
8192                     Log.wtf(TAG, "Unexpected callback type: "
8193                             + ConnectivityManager.getCallbackName(callbackId));
8194                     return false;
8195             }
8196 
8197             if (!ignoreThisCallback) {
8198                 // For non-listen (matching) callbacks, AVAILABLE can appear in the queue twice in a
8199                 // row for the same network if the new AVAILABLE suppressed intermediate AVAILABLEs
8200                 // for other networks. Example:
8201                 // A is matched, app is frozen, B is matched, A is matched again (removes callbacks
8202                 // for B), app is unfrozen.
8203                 // In that case call AVAILABLE sub-callbacks to update state, but not AVAILABLE
8204                 // itself.
8205                 if (callbackId == CALLBACK_AVAILABLE && netId == mMatchedNetIdWhenFrozen) {
8206                     // The queue should have been cleared here, since this is AVAILABLE on a
8207                     // non-listen callback (mMatchedNetIdWhenFrozen is set).
8208                     addAvailableSubCallbacks(nai, queue);
8209                 } else {
8210                     // When unfreezing, no need to send a callback multiple times for the same netId
8211                     queue.removeCallbacks(netId, callbackId);
8212                     // TODO: this code always adds the callback for simplicity. It would save
8213                     // some CPU/memory if the code instead only added to the queue callbacks where
8214                     // isCallbackOverridden=true, or which need to be in the queue because they
8215                     // affect other callbacks that are overridden.
8216                     queue.addCallback(netId, callbackId);
8217                 }
8218             }
8219             // Instead of shrinking the queue, possibly reallocating, the NRI could keep the array
8220             // and length in memory for future adds, but this saves memory by avoiding the cost
8221             // of an extra member and of unused array length (there are often hundreds of NRIs).
8222             mQueuedCallbacks = queue.getMinimizedBackingArray();
8223             return true;
8224         }
8225 
8226         /**
8227          * Called when this NRI is being unfrozen to stop queueing, and send queued callbacks.
8228          *
8229          * <p>Calling this method multiple times when the NRI is unfrozen (for example iterating
8230          * through the NetworkRequest -> NRI map where there are duplicate values for multilayer
8231          * requests) is fine.
8232          */
8233         void sendQueuedCallbacks() {
8234             mMatchedNetIdWhenFrozen = MATCHED_NETID_NOT_FROZEN;
8235             if (mQueuedCallbacks.length == 0) {
8236                 return;
8237             }
8238             new CallbackQueue(mQueuedCallbacks).forEach((netId, callbackId) -> {
8239                 // For CALLBACK_LOST only, there will not be a NAI for the netId. Build and send the
8240                 // callback directly.
8241                 if (callbackId == CALLBACK_LOST) {
8242                     if (isCallbackOverridden(CALLBACK_LOST)) {
8243                         final Bundle cbBundle = makeCommonBundleForCallback(this,
8244                                 new Network(netId));
8245                         callCallbackForRequest(this, CALLBACK_LOST, cbBundle, 0 /* arg1 */);
8246                     }
8247                     return; // Next item in forEach
8248                 }
8249 
8250                 // Other callbacks should always have a NAI, because if a Network disconnects
8251                 // LOST will be called, unless the request is no longer satisfied by that Network in
8252                 // which case AVAILABLE will have been called for another Network. In both cases
8253                 // previous callbacks are cleared.
8254                 final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
8255                 if (nai == null) {
8256                     Log.wtf(TAG, "Missing NetworkAgentInfo for net " + netId
8257                             + " for callback " + callbackId);
8258                     return; // Next item in forEach
8259                 }
8260 
8261                 final int arg1 =
8262                         callbackId == CALLBACK_AVAILABLE || callbackId == CALLBACK_BLK_CHANGED
8263                                 ? getBlockedState(nai, mAsUid)
8264                                 : 0;
8265                 callCallbackForRequest(this, nai, callbackId, arg1);
8266             });
8267             mQueuedCallbacks = new int[0];
8268         }
8269 
8270         boolean isCallbackOverridden(int callbackId) {
8271             return !mUseDeclaredMethodsForCallbacksEnabled
8272                     || (mDeclaredMethodsFlags & (1 << callbackId)) != 0;
8273         }
8274 
8275         /**
8276          * Queue all callbacks that are called by AVAILABLE, except onAvailable.
8277          *
8278          * <p>AVAILABLE may call SUSPENDED, CAP_CHANGED, IP_CHANGED, LOCAL_NETWORK_INFO_CHANGED,
8279          * and BLK_CHANGED, in this order.
8280          */
8281         private void addAvailableSubCallbacks(
8282                 @NonNull NetworkAgentInfo nai, @NonNull CallbackQueue queue) {
8283             final boolean callSuspended =
8284                     !nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
8285             final boolean callLocalInfoChanged = nai.isLocalNetwork();
8286 
8287             final int cbCount = 3 + (callSuspended ? 1 : 0) + (callLocalInfoChanged ? 1 : 0);
8288             // Avoid unnecessary re-allocations by reserving enough space for all callbacks to add.
8289             queue.ensureHasCapacity(cbCount);
8290             final int netId = nai.network.netId;
8291             if (callSuspended) {
8292                 queue.addCallback(netId, CALLBACK_SUSPENDED);
8293             }
8294             queue.addCallback(netId, CALLBACK_CAP_CHANGED);
8295             queue.addCallback(netId, CALLBACK_IP_CHANGED);
8296             if (callLocalInfoChanged) {
8297                 queue.addCallback(netId, CALLBACK_LOCAL_NETWORK_INFO_CHANGED);
8298             }
8299             queue.addCallback(netId, CALLBACK_BLK_CHANGED);
8300         }
8301 
8302         boolean hasHigherOrderThan(@NonNull final NetworkRequestInfo target) {
8303             // Compare two preference orders.
8304             return mPreferenceOrder < target.mPreferenceOrder;
8305         }
8306 
8307         int getPreferenceOrderForNetd() {
8308             if (mPreferenceOrder >= PREFERENCE_ORDER_NONE
8309                     && mPreferenceOrder <= PREFERENCE_ORDER_LOWEST) {
8310                 return mPreferenceOrder;
8311             }
8312             return PREFERENCE_ORDER_NONE;
8313         }
8314 
8315         public int getReservationId() {
8316             // RESERVATIONs cannot be used in multilayer requests.
8317             if (isMultilayerRequest()) return RES_ID_UNSET;
8318             final NetworkRequest req = mRequests.get(0);
8319             // Non-reservation types return RES_ID_UNSET.
8320             return req.networkCapabilities.getReservationId();
8321         }
8322 
8323         @Override
8324         public void binderDied() {
8325             // As an immutable collection, mRequests cannot change by the time the
8326             // lambda is evaluated on the handler thread so calling .get() from a binder thread
8327             // is acceptable. Use handleReleaseNetworkRequest and not directly
8328             // handleRemoveNetworkRequest so as to force a lookup in the requests map, in case
8329             // the app already unregistered the request.
8330             mHandler.post(() -> handleReleaseNetworkRequest(mRequests.get(0),
8331                     mUid, false /* callOnUnavailable */));
8332         }
8333 
8334         @Override
8335         public String toString() {
8336             final String asUidString = (mAsUid == mUid) ? "" : " asUid: " + mAsUid;
8337             return "uid/pid:" + mUid + "/" + mPid + asUidString + " activeRequest: "
8338                     + (mActiveRequest == null ? null : mActiveRequest.requestId)
8339                     + " callbackRequest: "
8340                     + mNetworkRequestForCallback.requestId
8341                     + " " + mRequests
8342                     + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent)
8343                     + " callback flags: " + mCallbackFlags
8344                     + " order: " + mPreferenceOrder
8345                     + " isUidTracked: " + mUidTrackedForBlockedStatus
8346                     + " declaredMethods: " + declaredMethodsFlagsToString(mDeclaredMethodsFlags);
8347         }
8348     }
8349 
8350     /**
8351      * Get a readable String for a bitmask of declared methods.
8352      */
8353     @VisibleForTesting
8354     public static String declaredMethodsFlagsToString(int flags) {
8355         if (flags == DECLARED_METHODS_NONE) {
8356             return "NONE";
8357         }
8358         if (flags == DECLARED_METHODS_ALL) {
8359             return "ALL";
8360         }
8361         final StringBuilder sb = new StringBuilder();
8362         flags = maybeAppendDeclaredMethod(flags, CALLBACK_PRECHECK, "PRECHK", sb);
8363         flags = maybeAppendDeclaredMethod(flags, CALLBACK_AVAILABLE, "AVAIL", sb);
8364         flags = maybeAppendDeclaredMethod(flags, CALLBACK_LOSING, "LOSING", sb);
8365         flags = maybeAppendDeclaredMethod(flags, CALLBACK_LOST, "LOST", sb);
8366         flags = maybeAppendDeclaredMethod(flags, CALLBACK_UNAVAIL, "UNAVAIL", sb);
8367         flags = maybeAppendDeclaredMethod(flags, CALLBACK_CAP_CHANGED, "NC", sb);
8368         flags = maybeAppendDeclaredMethod(flags, CALLBACK_IP_CHANGED, "LP", sb);
8369         flags = maybeAppendDeclaredMethod(flags, CALLBACK_SUSPENDED, "SUSP", sb);
8370         flags = maybeAppendDeclaredMethod(flags, CALLBACK_RESUMED, "RESUME", sb);
8371         flags = maybeAppendDeclaredMethod(flags, CALLBACK_BLK_CHANGED, "BLK", sb);
8372         flags = maybeAppendDeclaredMethod(flags, CALLBACK_LOCAL_NETWORK_INFO_CHANGED,
8373                 "LOCALINF", sb);
8374         flags = maybeAppendDeclaredMethod(flags, CALLBACK_RESERVED, "RES", sb);
8375         if (flags != 0) {
8376             sb.append("|0x").append(Integer.toHexString(flags));
8377         }
8378         return sb.toString();
8379     }
8380 
8381     private static int maybeAppendDeclaredMethod(int declaredMethodsFlags,
8382             int callbackId, String callbackName, @NonNull StringBuilder builder) {
8383         final int callbackFlag = 1 << callbackId;
8384         if ((declaredMethodsFlags & callbackFlag) != 0) {
8385             if (builder.length() > 0) {
8386                 builder.append('|');
8387             }
8388             builder.append(callbackName);
8389         }
8390         return declaredMethodsFlags & ~callbackFlag;
8391     }
8392 
8393     // Keep backward compatibility since the ServiceSpecificException is used by
8394     // the API surface, see {@link ConnectivityManager#convertServiceException}.
8395     public static class RequestInfoPerUidCounter extends PerUidCounter {
8396         RequestInfoPerUidCounter(int maxCountPerUid) {
8397             super(maxCountPerUid);
8398         }
8399 
8400         @Override
8401         public synchronized void incrementCountOrThrow(int uid) {
8402             try {
8403                 super.incrementCountOrThrow(uid);
8404             } catch (IllegalStateException e) {
8405                 throw new ServiceSpecificException(
8406                         ConnectivityManager.Errors.TOO_MANY_REQUESTS,
8407                         "Uid " + uid + " exceeded its allotted requests limit");
8408             }
8409         }
8410 
8411         @Override
8412         public synchronized void decrementCountOrThrow(int uid) {
8413             throw new UnsupportedOperationException("Use decrementCount instead.");
8414         }
8415 
8416         public synchronized void decrementCount(int uid) {
8417             try {
8418                 super.decrementCountOrThrow(uid);
8419             } catch (IllegalStateException e) {
8420                 logwtf("Exception when decrement per uid request count: ", e);
8421             }
8422         }
8423     }
8424 
8425     // This checks that the passed capabilities either do not request a
8426     // specific SSID/SignalStrength, or the calling app has permission to do so.
8427     private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
8428             int callerPid, int callerUid, String callerPackageName) {
8429         if (null != nc.getSsid() && !hasSettingsPermission(callerPid, callerUid)) {
8430             throw new SecurityException("Insufficient permissions to request a specific SSID");
8431         }
8432 
8433         if (nc.hasSignalStrength()
8434                 && !hasNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) {
8435             throw new SecurityException(
8436                     "Insufficient permissions to request a specific signal strength");
8437         }
8438         mAppOpsManager.checkPackage(callerUid, callerPackageName);
8439     }
8440 
8441     private int[] getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) {
8442         final SortedSet<Integer> thresholds = new TreeSet<>();
8443         synchronized (nai) {
8444             // mNetworkRequests may contain the same value multiple times in case of
8445             // multilayer requests. It won't matter in this case because the thresholds
8446             // will then be the same and be deduplicated as they enter the `thresholds` set.
8447             // TODO : have mNetworkRequests be a Set<NetworkRequestInfo> or the like.
8448             for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
8449                 for (final NetworkRequest req : nri.mRequests) {
8450                     if (req.networkCapabilities.hasSignalStrength()
8451                             && nai.satisfiesImmutableCapabilitiesOf(req)) {
8452                         thresholds.add(req.networkCapabilities.getSignalStrength());
8453                     }
8454                 }
8455             }
8456         }
8457         return CollectionUtils.toIntArray(new ArrayList<>(thresholds));
8458     }
8459 
8460     private void updateSignalStrengthThresholds(
8461             NetworkAgentInfo nai, String reason, NetworkRequest request) {
8462         final int[] thresholdsArray = getSignalStrengthThresholds(nai);
8463 
8464         if (VDBG || (DBG && !"CONNECT".equals(reason))) {
8465             String detail;
8466             if (request != null && request.networkCapabilities.hasSignalStrength()) {
8467                 detail = reason + " " + request.networkCapabilities.getSignalStrength();
8468             } else {
8469                 detail = reason;
8470             }
8471             log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s",
8472                     detail, Arrays.toString(thresholdsArray), nai.toShortString()));
8473         }
8474 
8475         nai.onSignalStrengthThresholdsUpdated(thresholdsArray);
8476     }
8477 
8478     private static void ensureValidNetworkSpecifier(NetworkCapabilities nc) {
8479         if (nc == null) {
8480             return;
8481         }
8482         NetworkSpecifier ns = nc.getNetworkSpecifier();
8483         if (ns == null) {
8484             return;
8485         }
8486         if (ns instanceof MatchAllNetworkSpecifier) {
8487             throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted");
8488         }
8489     }
8490 
8491     private static void ensureListenableCapabilities(@NonNull final NetworkCapabilities nc) {
8492         ensureValidNetworkSpecifier(nc);
8493         if (nc.isPrivateDnsBroken()) {
8494             throw new IllegalArgumentException("Can't request broken private DNS");
8495         }
8496         if (nc.hasAllowedUids()) {
8497             throw new IllegalArgumentException("Can't request access UIDs");
8498         }
8499     }
8500 
8501     private void ensureRequestableCapabilities(@NonNull final NetworkCapabilities nc) {
8502         ensureListenableCapabilities(nc);
8503         final String badCapability = nc.describeFirstNonRequestableCapability();
8504         if (badCapability != null) {
8505             throw new IllegalArgumentException("Cannot request network with " + badCapability);
8506         }
8507     }
8508 
8509     // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed.
8510     @TargetApi(Build.VERSION_CODES.S)
8511     private boolean isTargetSdkAtleast(int version, int callingUid,
8512             @NonNull String callingPackageName) {
8513         final UserHandle user = UserHandle.getUserHandleForUid(callingUid);
8514         final PackageManager pm =
8515                 mContext.createContextAsUser(user, 0 /* flags */).getPackageManager();
8516         try {
8517             final int callingVersion = pm.getTargetSdkVersion(callingPackageName);
8518             if (callingVersion < version) return false;
8519         } catch (PackageManager.NameNotFoundException e) { }
8520         return true;
8521     }
8522 
8523     @Override
8524     public NetworkRequest requestNetwork(int asUid, NetworkCapabilities networkCapabilities,
8525             int reqTypeInt, Messenger messenger, int timeoutMs, final IBinder binder,
8526             int legacyType, int callbackFlags, @NonNull String callingPackageName,
8527             @Nullable String callingAttributionTag, int declaredMethodsFlag) {
8528         if (declaredMethodsFlag == 0) {
8529             // This could happen if raw binder calls are used to call the previous overload of
8530             // requestNetwork, as missing int arguments in a binder call end up as 0
8531             // (Parcel.readInt returns 0 at the end of a parcel). Such raw calls this would be
8532             // really unexpected bad behavior from the caller though.
8533             // TODO: remove after verifying this does not happen. This could allow enabling the
8534             // optimization for callbacks that do not override any method (right now they use
8535             // DECLARED_METHODS_ALL), if it is OK to break NetworkCallbacks created using
8536             // dexmaker-mockito-inline and either spy() or MockSettings.useConstructor (see
8537             // comment in ConnectivityManager which sets the flag to DECLARED_METHODS_ALL).
8538             Log.wtf(TAG, "requestNetwork called without declaredMethodsFlag from "
8539                     + callingPackageName);
8540             declaredMethodsFlag = DECLARED_METHODS_ALL;
8541         }
8542         if (legacyType != TYPE_NONE && !hasNetworkStackPermission()) {
8543             if (isTargetSdkAtleast(Build.VERSION_CODES.M, mDeps.getCallingUid(),
8544                     callingPackageName)) {
8545                 throw new SecurityException("Insufficient permissions to specify legacy type");
8546             }
8547         }
8548         final NetworkCapabilities defaultNc = mDefaultRequest.mRequests.get(0).networkCapabilities;
8549         final int callingUid = mDeps.getCallingUid();
8550         // Privileged callers can track the default network of another UID by passing in a UID.
8551         if (asUid != Process.INVALID_UID) {
8552             enforceSettingsPermission();
8553         } else {
8554             asUid = callingUid;
8555         }
8556         final NetworkRequest.Type reqType;
8557         try {
8558             reqType = NetworkRequest.Type.values()[reqTypeInt];
8559         } catch (ArrayIndexOutOfBoundsException e) {
8560             throw new IllegalArgumentException("Unsupported request type " + reqTypeInt);
8561         }
8562         switch (reqType) {
8563             case TRACK_DEFAULT:
8564                 // If the request type is TRACK_DEFAULT, the passed {@code networkCapabilities}
8565                 // is unused and will be replaced by ones appropriate for the UID (usually, the
8566                 // calling app). This allows callers to keep track of the default network.
8567                 networkCapabilities = copyDefaultNetworkCapabilitiesForUid(
8568                         defaultNc, asUid, callingUid, callingPackageName);
8569                 enforceAccessPermission();
8570                 break;
8571             case TRACK_SYSTEM_DEFAULT:
8572                 enforceSettingsOrSetupWizardOrUseRestrictedNetworksPermission();
8573                 networkCapabilities = new NetworkCapabilities(defaultNc);
8574                 break;
8575             case BACKGROUND_REQUEST:
8576                 enforceNetworkStackOrSettingsPermission();
8577                 // Fall-through since other checks are the same with normal requests.
8578             case REQUEST:
8579             case RESERVATION:
8580                 networkCapabilities = new NetworkCapabilities(networkCapabilities);
8581                 enforceNetworkRequestPermissions(networkCapabilities, callingPackageName,
8582                         callingAttributionTag, callingUid);
8583                 // TODO: this is incorrect. We mark the request as metered or not depending on
8584                 //  the state of the app when the request is filed, but we never change the
8585                 //  request if the app changes network state. http://b/29964605
8586                 enforceMeteredApnPolicy(networkCapabilities);
8587                 maybeDisableLocalNetworkMatching(networkCapabilities, callingUid);
8588                 break;
8589             case LISTEN_FOR_BEST:
8590                 enforceAccessPermission();
8591                 networkCapabilities = new NetworkCapabilities(networkCapabilities);
8592                 maybeDisableLocalNetworkMatching(networkCapabilities, callingUid);
8593                 break;
8594             default:
8595                 throw new IllegalArgumentException("Unsupported request type " + reqType);
8596         }
8597         ensureRequestableCapabilities(networkCapabilities);
8598         ensureSufficientPermissionsForRequest(networkCapabilities,
8599                 Binder.getCallingPid(), callingUid, callingPackageName);
8600 
8601         // Enforce FOREGROUND if the caller does not have permission to use background network.
8602         if (reqType == LISTEN_FOR_BEST) {
8603             restrictBackgroundRequestForCaller(networkCapabilities);
8604         }
8605 
8606         // Set the UID range for this request to the single UID of the requester, unless the
8607         // requester has the permission to specify other UIDs.
8608         // This will overwrite any allowed UIDs in the requested capabilities. Though there
8609         // are no visible methods to set the UIDs, an app could use reflection to try and get
8610         // networks for other apps so it's essential that the UIDs are overwritten.
8611         // Also set the requester UID and package name in the request.
8612         restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities,
8613                 callingUid, callingPackageName);
8614 
8615         if (timeoutMs < 0) {
8616             throw new IllegalArgumentException("Bad timeout specified");
8617         }
8618 
8619         // For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were
8620         // copied from the default request above. (This is necessary to ensure, for example, that
8621         // the callback does not leak sensitive information to unprivileged apps.) Check that the
8622         // changes don't alter request matching.
8623         if (reqType == NetworkRequest.Type.TRACK_SYSTEM_DEFAULT &&
8624                 (!networkCapabilities.equalRequestableCapabilities(defaultNc))) {
8625             throw new IllegalStateException(
8626                     "TRACK_SYSTEM_DEFAULT capabilities don't match default request: "
8627                     + networkCapabilities + " vs. " + defaultNc);
8628         }
8629 
8630         final NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
8631                 nextNetworkRequestId(), reqType);
8632         final NetworkRequestInfo nri = getNriToRegister(
8633                 asUid, networkRequest, messenger, binder, callbackFlags,
8634                 callingAttributionTag, declaredMethodsFlag);
8635         if (DBG) log("requestNetwork for " + nri);
8636         trackUidAndRegisterNetworkRequest(EVENT_REGISTER_NETWORK_REQUEST, nri);
8637         if (timeoutMs > 0) {
8638             mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST,
8639                     nri), timeoutMs);
8640         }
8641         return networkRequest;
8642     }
8643 
8644     /**
8645      * Return the nri to be used when registering a network request. Specifically, this is used with
8646      * requests registered to track the default request. If there is currently a per-app default
8647      * tracking the app requestor, then we need to create a version of this nri that mirrors that of
8648      * the tracking per-app default so that callbacks are sent to the app requestor appropriately.
8649      * @param asUid the uid on behalf of which to file the request. Different from requestorUid
8650      *              when a privileged caller is tracking the default network for another uid.
8651      * @param nr the network request for the nri.
8652      * @param msgr the messenger for the nri.
8653      * @param binder the binder for the nri.
8654      * @param callingAttributionTag the calling attribution tag for the nri.
8655      * @return the nri to register.
8656      */
8657     private NetworkRequestInfo getNriToRegister(final int asUid, @NonNull final NetworkRequest nr,
8658             @Nullable final Messenger msgr, @Nullable final IBinder binder,
8659             @NetworkCallback.Flag int callbackFlags,
8660             @Nullable String callingAttributionTag, int declaredMethodsFlags) {
8661         final List<NetworkRequest> requests;
8662         if (NetworkRequest.Type.TRACK_DEFAULT == nr.type) {
8663             requests = copyDefaultNetworkRequestsForUid(
8664                     asUid, nr.getRequestorUid(), nr.getRequestorPackageName());
8665         } else {
8666             requests = Collections.singletonList(nr);
8667         }
8668         return new NetworkRequestInfo(
8669                 asUid, requests, nr, msgr, binder, callbackFlags, callingAttributionTag,
8670                 declaredMethodsFlags);
8671     }
8672 
8673     private boolean shouldCheckCapabilitiesDeclaration(
8674             @NonNull final NetworkCapabilities networkCapabilities, final int callingUid,
8675             @NonNull final String callingPackageName) {
8676         final UserHandle user = UserHandle.getUserHandleForUid(callingUid);
8677         // Only run the check if the change is enabled.
8678         if (!mDeps.isChangeEnabled(
8679                 ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION,
8680                 callingPackageName, user)) {
8681             return false;
8682         }
8683 
8684         return networkCapabilities.hasCapability(
8685                 NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
8686                 || networkCapabilities.hasCapability(
8687                 NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY);
8688     }
8689 
8690     private void enforceRequestCapabilitiesDeclaration(@NonNull final String callerPackageName,
8691             @NonNull final NetworkCapabilities networkCapabilities, int callingUid) {
8692         // This check is added to fix the linter error for "current min is 30", which is not going
8693         // to happen because Connectivity service always run in S+.
8694         if (!mDeps.isAtLeastS()) {
8695             Log.wtf(TAG, "Connectivity service should always run in at least SDK S");
8696             return;
8697         }
8698         ApplicationSelfCertifiedNetworkCapabilities applicationNetworkCapabilities;
8699         final long ident = Binder.clearCallingIdentity();
8700         try {
8701             synchronized (mSelfCertifiedCapabilityCache) {
8702                 applicationNetworkCapabilities = mSelfCertifiedCapabilityCache.get(
8703                         callerPackageName);
8704                 if (applicationNetworkCapabilities == null) {
8705                     final PackageManager packageManager =
8706                             mContext.createContextAsUser(UserHandle.getUserHandleForUid(
8707                                     callingUid), 0 /* flags */).getPackageManager();
8708                     final PackageManager.Property networkSliceProperty = packageManager.getProperty(
8709                             ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES,
8710                             callerPackageName
8711                     );
8712                     final XmlResourceParser parser = packageManager
8713                             .getResourcesForApplication(callerPackageName)
8714                             .getXml(networkSliceProperty.getResourceId());
8715                     applicationNetworkCapabilities =
8716                             ApplicationSelfCertifiedNetworkCapabilities.createFromXml(parser);
8717                     mSelfCertifiedCapabilityCache.put(callerPackageName,
8718                             applicationNetworkCapabilities);
8719                 }
8720 
8721             }
8722         } catch (PackageManager.NameNotFoundException ne) {
8723             throw new SecurityException(
8724                     "Cannot find " + ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES
8725                             + " property");
8726         } catch (XmlPullParserException | IOException | InvalidTagException e) {
8727             throw new SecurityException(e.getMessage());
8728         } finally {
8729             Binder.restoreCallingIdentity(ident);
8730         }
8731 
8732         applicationNetworkCapabilities.enforceSelfCertifiedNetworkCapabilitiesDeclared(
8733                 networkCapabilities);
8734     }
8735 
8736     private boolean canRequestRestrictedNetworkDueToCarrierPrivileges(
8737             NetworkCapabilities networkCapabilities, int callingUid) {
8738         if (mRequestRestrictedWifiEnabled) {
8739             // For U+ devices, callers with carrier privilege could request restricted networks
8740             // with CBS capabilities, or any restricted WiFi networks.
8741             return ((networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
8742                 || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
8743                 && hasCarrierPrivilegeForNetworkCaps(callingUid, networkCapabilities));
8744         } else {
8745             // For T+ devices, callers with carrier privilege could request with CBS
8746             // capabilities.
8747             return (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
8748                 && hasCarrierPrivilegeForNetworkCaps(callingUid, networkCapabilities));
8749         }
8750     }
8751     private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities,
8752             String callingPackageName, String callingAttributionTag, final int callingUid) {
8753         if (shouldCheckCapabilitiesDeclaration(networkCapabilities, callingUid,
8754                 callingPackageName)) {
8755             enforceRequestCapabilitiesDeclaration(callingPackageName, networkCapabilities,
8756                     callingUid);
8757         }
8758         if (!networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
8759             if (!canRequestRestrictedNetworkDueToCarrierPrivileges(
8760                     networkCapabilities, callingUid)) {
8761                 enforceConnectivityRestrictedNetworksPermission(true /* checkUidsAllowedList */);
8762             }
8763         } else {
8764             enforceChangePermission(callingPackageName, callingAttributionTag);
8765         }
8766     }
8767 
8768     @Override
8769     public boolean requestBandwidthUpdate(Network network) {
8770         enforceAccessPermission();
8771         NetworkAgentInfo nai = null;
8772         if (network == null) {
8773             return false;
8774         }
8775         synchronized (mNetworkForNetId) {
8776             nai = mNetworkForNetId.get(network.getNetId());
8777         }
8778         if (nai != null) {
8779             nai.onBandwidthUpdateRequested();
8780             synchronized (mBandwidthRequests) {
8781                 final int uid = mDeps.getCallingUid();
8782                 Integer uidReqs = mBandwidthRequests.get(uid);
8783                 if (uidReqs == null) {
8784                     uidReqs = 0;
8785                 }
8786                 mBandwidthRequests.put(uid, ++uidReqs);
8787             }
8788             return true;
8789         }
8790         return false;
8791     }
8792 
8793     private boolean isSystem(int uid) {
8794         return uid < Process.FIRST_APPLICATION_UID;
8795     }
8796 
8797     private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) {
8798         final int uid = mDeps.getCallingUid();
8799         if (isSystem(uid)) {
8800             // Exemption for system uid.
8801             return;
8802         }
8803         if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
8804             // Policy already enforced.
8805             return;
8806         }
8807         final boolean isRestrictedOnMeteredNetworks = mDeps.isAtLeastV()
8808                 ? mBpfNetMaps.isUidRestrictedOnMeteredNetworks(uid)
8809                 : BinderUtils.withCleanCallingIdentity(() ->
8810                         mPolicyManager.isUidRestrictedOnMeteredNetworks(uid));
8811         if (isRestrictedOnMeteredNetworks) {
8812             // If UID is restricted, don't allow them to bring up metered APNs.
8813             networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
8814         }
8815     }
8816 
8817     @Override
8818     public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
8819             PendingIntent operation, @NonNull String callingPackageName,
8820             @Nullable String callingAttributionTag) {
8821         Objects.requireNonNull(operation, "PendingIntent cannot be null.");
8822         final int callingUid = mDeps.getCallingUid();
8823         networkCapabilities = new NetworkCapabilities(networkCapabilities);
8824         enforceNetworkRequestPermissions(networkCapabilities, callingPackageName,
8825                 callingAttributionTag, callingUid);
8826         enforceMeteredApnPolicy(networkCapabilities);
8827         ensureRequestableCapabilities(networkCapabilities);
8828         ensureSufficientPermissionsForRequest(networkCapabilities,
8829                 Binder.getCallingPid(), callingUid, callingPackageName);
8830         restrictRequestNetworkCapabilitiesForCaller(
8831                 networkCapabilities, callingUid, callingPackageName);
8832 
8833         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
8834                 nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
8835         NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation,
8836                 callingAttributionTag);
8837         if (DBG) log("pendingRequest for " + nri);
8838         trackUidAndRegisterNetworkRequest(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT, nri);
8839         return networkRequest;
8840     }
8841 
8842     private void releasePendingNetworkRequestWithDelay(PendingIntent operation) {
8843         mHandler.sendMessageDelayed(
8844                 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
8845                 mDeps.getCallingUid(), 0, operation), mReleasePendingIntentDelayMs);
8846     }
8847 
8848     @Override
8849     public void releasePendingNetworkRequest(PendingIntent operation) {
8850         Objects.requireNonNull(operation, "PendingIntent cannot be null.");
8851         mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
8852                 mDeps.getCallingUid(), 0, operation));
8853     }
8854 
8855     // In order to implement the compatibility measure for pre-M apps that call
8856     // WifiManager.enableNetwork(..., true) without also binding to that network explicitly,
8857     // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork.
8858     // This ensures it has permission to do so.
8859     private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) {
8860         if (nc == null) {
8861             return false;
8862         }
8863         int[] transportTypes = nc.getTransportTypes();
8864         if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) {
8865             return false;
8866         }
8867         try {
8868             mContext.enforceCallingOrSelfPermission(
8869                     android.Manifest.permission.ACCESS_WIFI_STATE,
8870                     "ConnectivityService");
8871         } catch (SecurityException e) {
8872             return false;
8873         }
8874         return true;
8875     }
8876 
8877     private boolean isAppRequest(NetworkRequestInfo nri) {
8878         return nri.mMessenger != null || nri.mPendingIntent != null;
8879     }
8880 
8881     private void trackUidAndMaybePostCurrentBlockedReason(final NetworkRequestInfo nri) {
8882         if (!isAppRequest(nri)) {
8883             Log.wtf(TAG, "trackUidAndMaybePostCurrentBlockedReason is called for non app"
8884                     + "request: " + nri);
8885             return;
8886         }
8887         nri.mPerUidCounter.incrementCountOrThrow(nri.mUid);
8888 
8889         // If nri.mMessenger is null, this nri does not have NetworkCallback so ConnectivityService
8890         // does not need to send onBlockedStatusChanged callback for this uid and does not need to
8891         // track the uid in mBlockedStatusTrackingUids
8892         if (!shouldTrackUidsForBlockedStatusCallbacks() || nri.mMessenger == null) {
8893             return;
8894         }
8895         if (nri.mUidTrackedForBlockedStatus) {
8896             Log.wtf(TAG, "Nri is already tracked for sending blocked status: " + nri);
8897             return;
8898         }
8899         nri.mUidTrackedForBlockedStatus = true;
8900         synchronized (mBlockedStatusTrackingUids) {
8901             final int uid = nri.mAsUid;
8902             final int count = mBlockedStatusTrackingUids.get(uid, 0);
8903             if (count == 0) {
8904                 mHandler.sendMessage(mHandler.obtainMessage(EVENT_BLOCKED_REASONS_CHANGED,
8905                         List.of(new Pair<>(uid, mBpfNetMaps.getUidNetworkingBlockedReasons(uid)))));
8906             }
8907             mBlockedStatusTrackingUids.put(uid, count + 1);
8908         }
8909     }
8910 
8911     private void trackUidAndRegisterNetworkRequest(final int event, NetworkRequestInfo nri) {
8912         // Post the update of the UID's blocked reasons before posting the message that registers
8913         // the callback. This is necessary because if the callback immediately matches a request,
8914         // the onBlockedStatusChanged must be called with the correct blocked reasons.
8915         // Also, once trackUidAndMaybePostCurrentBlockedReason is called, the register network
8916         // request event must be posted, because otherwise the counter for uid will never be
8917         // decremented.
8918         trackUidAndMaybePostCurrentBlockedReason(nri);
8919         mHandler.sendMessage(mHandler.obtainMessage(event, nri));
8920     }
8921 
8922     private void maybeUntrackUidAndClearBlockedReasons(final NetworkRequestInfo nri) {
8923         if (!isAppRequest(nri)) {
8924             // Not an app request.
8925             return;
8926         }
8927         nri.mPerUidCounter.decrementCount(nri.mUid);
8928 
8929         if (!shouldTrackUidsForBlockedStatusCallbacks() || nri.mMessenger == null) {
8930             return;
8931         }
8932         if (!nri.mUidTrackedForBlockedStatus) {
8933             Log.wtf(TAG, "Nri is not tracked for sending blocked status: " + nri);
8934             return;
8935         }
8936         nri.mUidTrackedForBlockedStatus = false;
8937         synchronized (mBlockedStatusTrackingUids) {
8938             final int count = mBlockedStatusTrackingUids.get(nri.mAsUid);
8939             if (count > 1) {
8940                 mBlockedStatusTrackingUids.put(nri.mAsUid, count - 1);
8941             } else {
8942                 mBlockedStatusTrackingUids.delete(nri.mAsUid);
8943                 mUidBlockedReasons.delete(nri.mAsUid);
8944             }
8945         }
8946     }
8947 
8948     @Override
8949     public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
8950             Messenger messenger, IBinder binder,
8951             @NetworkCallback.Flag int callbackFlags,
8952             @NonNull String callingPackageName, @NonNull String callingAttributionTag,
8953             int declaredMethodsFlag) {
8954         if (declaredMethodsFlag == 0) {
8955             Log.wtf(TAG, "listenForNetwork called without declaredMethodsFlag from "
8956                     + callingPackageName);
8957             declaredMethodsFlag = DECLARED_METHODS_ALL;
8958         }
8959         final int callingUid = mDeps.getCallingUid();
8960         if (!hasWifiNetworkListenPermission(networkCapabilities)) {
8961             enforceAccessPermission();
8962         }
8963 
8964         NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
8965         ensureSufficientPermissionsForRequest(networkCapabilities,
8966                 Binder.getCallingPid(), callingUid, callingPackageName);
8967         restrictRequestNetworkCapabilitiesForCaller(nc, callingUid, callingPackageName);
8968         // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so
8969         // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get
8970         // onLost and onAvailable callbacks when networks move in and out of the background.
8971         // There is no need to do this for requests because an app without CHANGE_NETWORK_STATE
8972         // can't request networks.
8973         restrictBackgroundRequestForCaller(nc);
8974         ensureListenableCapabilities(nc);
8975 
8976         NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
8977                 NetworkRequest.Type.LISTEN);
8978         NetworkRequestInfo nri =
8979                 new NetworkRequestInfo(callingUid, networkRequest, messenger, binder, callbackFlags,
8980                         callingAttributionTag, declaredMethodsFlag);
8981         if (VDBG) log("listenForNetwork for " + nri);
8982 
8983         trackUidAndRegisterNetworkRequest(EVENT_REGISTER_NETWORK_LISTENER, nri);
8984         return networkRequest;
8985     }
8986 
8987     @Override
8988     public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
8989             PendingIntent operation, @NonNull String callingPackageName,
8990             @Nullable String callingAttributionTag) {
8991         Objects.requireNonNull(operation, "PendingIntent cannot be null.");
8992         final int callingUid = mDeps.getCallingUid();
8993         if (!hasWifiNetworkListenPermission(networkCapabilities)) {
8994             enforceAccessPermission();
8995         }
8996         ensureListenableCapabilities(networkCapabilities);
8997         ensureSufficientPermissionsForRequest(networkCapabilities,
8998                 Binder.getCallingPid(), callingUid, callingPackageName);
8999         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
9000         restrictRequestNetworkCapabilitiesForCaller(nc, callingUid, callingPackageName);
9001 
9002         NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
9003                 NetworkRequest.Type.LISTEN);
9004         NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, networkRequest, operation,
9005                 callingAttributionTag);
9006         if (VDBG) log("pendingListenForNetwork for " + nri);
9007 
9008         trackUidAndRegisterNetworkRequest(EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT, nri);
9009     }
9010 
9011     /** Returns the next Network provider ID. */
9012     public final int nextNetworkProviderId() {
9013         return mNextNetworkProviderId.getAndIncrement();
9014     }
9015 
9016     @Override
9017     public void releaseNetworkRequest(NetworkRequest networkRequest) {
9018         ensureNetworkRequestHasSupportedType(networkRequest, false /* isMultilayerRequest */);
9019         mHandler.sendMessage(mHandler.obtainMessage(
9020                 EVENT_RELEASE_NETWORK_REQUEST, mDeps.getCallingUid(), 0, networkRequest));
9021     }
9022 
9023     private void handleRegisterNetworkProvider(NetworkProviderInfo npi) {
9024         if (mNetworkProviderInfos.containsKey(npi.messenger)) {
9025             // Avoid creating duplicates. even if an app makes a direct AIDL call.
9026             // This will never happen if an app calls ConnectivityManager#registerNetworkProvider,
9027             // as that will throw if a duplicate provider is registered.
9028             loge("Attempt to register existing NetworkProviderInfo "
9029                     + mNetworkProviderInfos.get(npi.messenger).name);
9030             return;
9031         }
9032 
9033         if (DBG) log("Got NetworkProvider Messenger for " + npi.name);
9034         mNetworkProviderInfos.put(npi.messenger, npi);
9035         npi.connect(mContext, mTrackerHandler);
9036     }
9037 
9038     @Override
9039     public int registerNetworkProvider(Messenger messenger, String name) {
9040         enforceNetworkFactoryOrSettingsPermission();
9041         Objects.requireNonNull(messenger, "messenger must be non-null");
9042         NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger,
9043                 nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger));
9044         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi));
9045         return npi.providerId;
9046     }
9047 
9048     @Override
9049     public void unregisterNetworkProvider(Messenger messenger) {
9050         enforceNetworkFactoryOrSettingsPermission();
9051         mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger));
9052     }
9053 
9054     @Override
9055     public void offerNetwork(final int providerId,
9056             @NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps,
9057             @NonNull final INetworkOfferCallback callback) {
9058         Objects.requireNonNull(score);
9059         Objects.requireNonNull(caps);
9060         Objects.requireNonNull(callback);
9061         if (caps.hasTransport(TRANSPORT_TEST)) {
9062             enforceAnyPermissionOf(mContext, Manifest.permission.MANAGE_TEST_NETWORKS);
9063         } else {
9064             enforceNetworkFactoryPermission();
9065         }
9066         final boolean yieldToBadWiFi = caps.hasTransport(TRANSPORT_CELLULAR) && !avoidBadWifi();
9067         final NetworkOffer offer = new NetworkOffer(
9068                 FullScore.makeProspectiveScore(score, caps, yieldToBadWiFi),
9069                 caps, callback, providerId);
9070         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_OFFER, offer));
9071     }
9072 
9073     private void updateOfferScore(final NetworkOffer offer) {
9074         final boolean yieldToBadWiFi =
9075                 offer.caps.hasTransport(TRANSPORT_CELLULAR) && !avoidBadWifi();
9076         final NetworkOffer newOffer = new NetworkOffer(
9077                 offer.score.withYieldToBadWiFi(yieldToBadWiFi),
9078                         offer.caps, offer.callback, offer.providerId);
9079         if (offer.equals(newOffer)) return;
9080         handleRegisterNetworkOffer(newOffer);
9081     }
9082 
9083     @Override
9084     public void unofferNetwork(@NonNull final INetworkOfferCallback callback) {
9085         Objects.requireNonNull(callback);
9086         mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_OFFER, callback));
9087     }
9088 
9089     private void handleUnregisterNetworkProvider(Messenger messenger) {
9090         NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger);
9091         if (npi == null) {
9092             loge("Failed to find Messenger in unregisterNetworkProvider");
9093             return;
9094         }
9095         // Unregister all the offers from this provider
9096         final ArrayList<NetworkOfferInfo> toRemove = new ArrayList<>();
9097         for (final NetworkOfferInfo noi : mNetworkOffers) {
9098             if (noi.offer.providerId == npi.providerId) {
9099                 // Can't call handleUnregisterNetworkOffer here because iteration is in progress
9100                 toRemove.add(noi);
9101             }
9102         }
9103         for (final NetworkOfferInfo noi : toRemove) {
9104             handleUnregisterNetworkOffer(noi, true /* releaseReservations */);
9105         }
9106         if (DBG) log("unregisterNetworkProvider for " + npi.name);
9107     }
9108 
9109     @Override
9110     public void declareNetworkRequestUnfulfillable(@NonNull final NetworkRequest request) {
9111         if (request.hasTransport(TRANSPORT_TEST)) {
9112             enforceNetworkFactoryOrTestNetworksPermission();
9113         } else {
9114             enforceNetworkFactoryPermission();
9115         }
9116         final NetworkRequestInfo nri = mNetworkRequests.get(request);
9117         if (nri != null) {
9118             // declareNetworkRequestUnfulfillable() paths don't apply to multilayer requests.
9119             ensureNotMultilayerRequest(nri, "declareNetworkRequestUnfulfillable");
9120             mHandler.post(() -> handleReleaseNetworkRequest(
9121                     nri.mRequests.get(0), mDeps.getCallingUid(), true));
9122         }
9123     }
9124 
9125     // NOTE: Accessed on multiple threads, must be synchronized on itself.
9126     @GuardedBy("mNetworkForNetId")
9127     private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>();
9128     // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId.
9129     // An entry is first reserved with NetIdManager, prior to being added to mNetworkForNetId, so
9130     // there may not be a strict 1:1 correlation between the two.
9131     private final NetIdManager mNetIdManager;
9132 
9133     // Tracks all NetworkAgents that are currently registered.
9134     // NOTE: Only should be accessed on ConnectivityServiceThread, except dump().
9135     // Code iterating over this set is recommended to use forAllNetworkAgentInfos(), which allows
9136     // code within the loop to disconnect networks during iteration without causing null pointer or
9137     // OOB exceptions.
9138     private final ArraySet<NetworkAgentInfo> mNetworkAgentInfos = new ArraySet<>();
9139 
9140     // UID ranges for users that are currently blocked by VPNs.
9141     // This array is accessed and iterated on multiple threads without holding locks, so its
9142     // contents must never be mutated. When the ranges change, the array is replaced with a new one
9143     // (on the handler thread).
9144     private volatile List<UidRange> mVpnBlockedUidRanges = new ArrayList<>();
9145 
9146     // Must only be accessed on the handler thread
9147     @NonNull
9148     private final ArrayList<NetworkOfferInfo> mNetworkOffers = new ArrayList<>();
9149 
9150     @GuardedBy("mBlockedAppUids")
9151     private final HashSet<Integer> mBlockedAppUids = new HashSet<>();
9152 
9153     // Current OEM network preferences. This object must only be written to on the handler thread.
9154     // Since it is immutable and always non-null, other threads may read it if they only care
9155     // about seeing a consistent object but not that it is current.
9156     @NonNull
9157     private OemNetworkPreferences mOemNetworkPreferences =
9158             new OemNetworkPreferences.Builder().build();
9159     // Current per-profile network preferences. This object follows the same threading rules as
9160     // the OEM network preferences above.
9161     @NonNull
9162     private NetworkPreferenceList<UserHandle, ProfileNetworkPreferenceInfo>
9163             mProfileNetworkPreferences = new NetworkPreferenceList<>();
9164 
9165     // Current VPN network preferences. This object follows the same threading rules as the OEM
9166     // network preferences above.
9167     @NonNull
9168     private NetworkPreferenceList<String, VpnNetworkPreferenceInfo>
9169             mVpnNetworkPreferences = new NetworkPreferenceList<>();
9170 
9171     // A set of UIDs that should use mobile data preferentially if available. This object follows
9172     // the same threading rules as the OEM network preferences above.
9173     @NonNull
9174     private Set<Integer> mMobileDataPreferredUids = new ArraySet<>();
9175 
9176     // OemNetworkPreferences activity String log entries.
9177     private static final int MAX_OEM_NETWORK_PREFERENCE_LOGS = 20;
9178     @NonNull
9179     private final LocalLog mOemNetworkPreferencesLogs =
9180             new LocalLog(MAX_OEM_NETWORK_PREFERENCE_LOGS);
9181 
9182     /**
9183      * Determine whether a given package has a mapping in the current OemNetworkPreferences.
9184      * @param packageName the package name to check existence of a mapping for.
9185      * @return true if a mapping exists, false otherwise
9186      */
9187     private boolean isMappedInOemNetworkPreference(@NonNull final String packageName) {
9188         return mOemNetworkPreferences.getNetworkPreferences().containsKey(packageName);
9189     }
9190 
9191     // The always-on request for an Internet-capable network that apps without a specific default
9192     // fall back to.
9193     @VisibleForTesting
9194     @NonNull
9195     final NetworkRequestInfo mDefaultRequest;
9196     // Collection of NetworkRequestInfo's used for default networks.
9197     // This set is read and iterated on multiple threads.
9198     // Using CopyOnWriteArraySet since number of default network request is small (system default
9199     // network request + per-app default network requests) and updated infrequently but read
9200     // frequently.
9201     @VisibleForTesting
9202     @NonNull
9203     final CopyOnWriteArraySet<NetworkRequestInfo> mDefaultNetworkRequests =
9204             new CopyOnWriteArraySet<>();
9205 
9206 
9207     private boolean isPerAppDefaultRequest(@NonNull final NetworkRequestInfo nri) {
9208         return (mDefaultNetworkRequests.contains(nri) && mDefaultRequest != nri);
9209     }
9210 
9211     /**
9212      * Return the default network request currently tracking the given uid.
9213      * @param uid the uid to check.
9214      * @return the NetworkRequestInfo tracking the given uid.
9215      */
9216     @NonNull
9217     private NetworkRequestInfo getDefaultRequestTrackingUid(final int uid) {
9218         NetworkRequestInfo highestPriorityNri = mDefaultRequest;
9219         for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
9220             // Checking the first request is sufficient as only multilayer requests will have more
9221             // than one request and for multilayer, all requests will track the same uids.
9222             if (nri.mRequests.get(0).networkCapabilities.appliesToUid(uid)) {
9223                 // Find out the highest priority request.
9224                 if (nri.hasHigherOrderThan(highestPriorityNri)) {
9225                     highestPriorityNri = nri;
9226                 }
9227             }
9228         }
9229         return highestPriorityNri;
9230     }
9231 
9232     /**
9233      * Get a copy of the network requests of the default request that is currently tracking the
9234      * given uid.
9235      * @param asUid the uid on behalf of which to file the request. Different from requestorUid
9236      *              when a privileged caller is tracking the default network for another uid.
9237      * @param requestorUid the uid to check the default for.
9238      * @param requestorPackageName the requestor's package name.
9239      * @return a copy of the default's NetworkRequest that is tracking the given uid.
9240      */
9241     @NonNull
9242     private List<NetworkRequest> copyDefaultNetworkRequestsForUid(
9243             final int asUid, final int requestorUid, @NonNull final String requestorPackageName) {
9244         return copyNetworkRequestsForUid(
9245                 getDefaultRequestTrackingUid(asUid).mRequests,
9246                 asUid, requestorUid, requestorPackageName);
9247     }
9248 
9249     /**
9250      * Copy the given nri's NetworkRequest collection.
9251      * @param requestsToCopy the NetworkRequest collection to be copied.
9252      * @param asUid the uid on behalf of which to file the request. Different from requestorUid
9253      *              when a privileged caller is tracking the default network for another uid.
9254      * @param requestorUid the uid to set on the copied collection.
9255      * @param requestorPackageName the package name to set on the copied collection.
9256      * @return the copied NetworkRequest collection.
9257      */
9258     @NonNull
9259     private List<NetworkRequest> copyNetworkRequestsForUid(
9260             @NonNull final List<NetworkRequest> requestsToCopy, final int asUid,
9261             final int requestorUid, @NonNull final String requestorPackageName) {
9262         final List<NetworkRequest> requests = new ArrayList<>();
9263         for (final NetworkRequest nr : requestsToCopy) {
9264             requests.add(new NetworkRequest(copyDefaultNetworkCapabilitiesForUid(
9265                             nr.networkCapabilities, asUid, requestorUid, requestorPackageName),
9266                     nr.legacyType, nextNetworkRequestId(), nr.type));
9267         }
9268         return requests;
9269     }
9270 
9271     @NonNull
9272     private NetworkCapabilities copyDefaultNetworkCapabilitiesForUid(
9273             @NonNull final NetworkCapabilities netCapToCopy, final int asUid,
9274             final int requestorUid, @NonNull final String requestorPackageName) {
9275         // These capabilities are for a TRACK_DEFAULT callback, so:
9276         // 1. Remove NET_CAPABILITY_VPN, because it's (currently!) the only difference between
9277         //    mDefaultRequest and a per-UID default request.
9278         //    TODO: stop depending on the fact that these two unrelated things happen to be the same
9279         // 2. Always set the UIDs to asUid. restrictRequestUidsForCallerAndSetRequestorInfo will
9280         //    not do this in the case of a privileged application.
9281         final NetworkCapabilities netCap = new NetworkCapabilities(netCapToCopy);
9282         netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
9283         netCap.setSingleUid(asUid);
9284         restrictRequestUidsForCallerAndSetRequestorInfo(
9285                 netCap, requestorUid, requestorPackageName);
9286         return netCap;
9287     }
9288 
9289     /**
9290      * Get the nri that is currently being tracked for callbacks by per-app defaults.
9291      * @param nr the network request to check for equality against.
9292      * @return the nri if one exists, null otherwise.
9293      */
9294     @Nullable
9295     private NetworkRequestInfo getNriForAppRequest(@NonNull final NetworkRequest nr) {
9296         for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
9297             if (nri.getNetworkRequestForCallback().equals(nr)) {
9298                 return nri;
9299             }
9300         }
9301         return null;
9302     }
9303 
9304     /**
9305      * Check if an nri is currently being managed by per-app default networking.
9306      * @param nri the nri to check.
9307      * @return true if this nri is currently being managed by per-app default networking.
9308      */
9309     private boolean isPerAppTrackedNri(@NonNull final NetworkRequestInfo nri) {
9310         // nri.mRequests.get(0) is only different from the original request filed in
9311         // nri.getNetworkRequestForCallback() if nri.mRequests was changed by per-app default
9312         // functionality therefore if these two don't match, it means this particular nri is
9313         // currently being managed by a per-app default.
9314         return nri.getNetworkRequestForCallback() != nri.mRequests.get(0);
9315     }
9316 
9317     /**
9318      * Determine if an nri is a managed default request that disallows default networking.
9319      * @param nri the request to evaluate
9320      * @return true if device-default networking is disallowed
9321      */
9322     private boolean isDefaultBlocked(@NonNull final NetworkRequestInfo nri) {
9323         // Check if this nri is a managed default that supports the default network at its
9324         // lowest priority request.
9325         final NetworkRequest defaultNetworkRequest = mDefaultRequest.mRequests.get(0);
9326         final NetworkCapabilities lowestPriorityNetCap =
9327                 nri.mRequests.get(nri.mRequests.size() - 1).networkCapabilities;
9328         return isPerAppDefaultRequest(nri)
9329                 && !(defaultNetworkRequest.networkCapabilities.equalRequestableCapabilities(
9330                         lowestPriorityNetCap));
9331     }
9332 
9333     // Request used to optionally keep mobile data active even when higher
9334     // priority networks like Wi-Fi are active.
9335     private final NetworkRequest mDefaultMobileDataRequest;
9336 
9337     // Request used to optionally keep wifi data active even when higher
9338     // priority networks like ethernet are active.
9339     private final NetworkRequest mDefaultWifiRequest;
9340 
9341     // Request used to optionally keep vehicle internal network always active
9342     private final NetworkRequest mDefaultVehicleRequest;
9343 
9344     // Sentinel NAI used to direct apps with default networks that should have no connectivity to a
9345     // network with no service. This NAI should never be matched against, nor should any public API
9346     // ever return the associated network. For this reason, this NAI is not in the list of available
9347     // NAIs. It is used in computeNetworkReassignment() to be set as the satisfier for non-device
9348     // default requests that don't support using the device default network which will ultimately
9349     // allow ConnectivityService to use this no-service network when calling makeDefaultForApps().
9350     @VisibleForTesting
9351     final NetworkAgentInfo mNoServiceNetwork;
9352 
9353     // The NetworkAgentInfo currently satisfying the default request, if any.
9354     private NetworkAgentInfo getDefaultNetwork() {
9355         return mDefaultRequest.mSatisfier;
9356     }
9357 
9358     private NetworkAgentInfo getDefaultNetworkForUid(final int uid) {
9359         NetworkRequestInfo highestPriorityNri = mDefaultRequest;
9360         for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
9361             // Currently, all network requests will have the same uids therefore checking the first
9362             // one is sufficient. If/when uids are tracked at the nri level, this can change.
9363             final Set<UidRange> uids = nri.mRequests.get(0).networkCapabilities.getUidRanges();
9364             if (null == uids) {
9365                 continue;
9366             }
9367             for (final UidRange range : uids) {
9368                 if (range.contains(uid)) {
9369                     if (nri.hasHigherOrderThan(highestPriorityNri)) {
9370                         highestPriorityNri = nri;
9371                     }
9372                 }
9373             }
9374         }
9375         if (!highestPriorityNri.isBeingSatisfied()) return null;
9376         return highestPriorityNri.getSatisfier();
9377     }
9378 
9379     @Nullable
9380     private Network getNetwork(@Nullable NetworkAgentInfo nai) {
9381         return nai != null ? nai.network : null;
9382     }
9383 
9384     private void ensureRunningOnConnectivityServiceThread() {
9385         HandlerUtils.ensureRunningOnHandlerThread(mHandler);
9386     }
9387 
9388     @VisibleForTesting
9389     protected boolean isDefaultNetwork(NetworkAgentInfo nai) {
9390         return nai == getDefaultNetwork();
9391     }
9392 
9393     /**
9394      * Returns whether local agents are supported on this device.
9395      *
9396      * Local agents are supported from U on TVs, and from V on all devices.
9397      */
9398     @VisibleForTesting
9399     public boolean areLocalAgentsSupported() {
9400         final PackageManager pm = mContext.getPackageManager();
9401         // Local agents are supported starting on U on TVs and on V on everything else.
9402         return mDeps.isAtLeastV() || (mDeps.isAtLeastU() && pm.hasSystemFeature(FEATURE_LEANBACK));
9403     }
9404 
9405     /**
9406      * Register a new agent with ConnectivityService to handle a network.
9407      *
9408      * @param na a reference for ConnectivityService to contact the agent asynchronously.
9409      * @param networkInfo the initial info associated with this network. It can be updated later :
9410      *         see {@link #updateNetworkInfo}.
9411      * @param linkProperties the initial link properties of this network. They can be updated
9412      *         later : see {@link #updateLinkProperties}.
9413      * @param networkCapabilities the initial capabilites of this network. They can be updated
9414      *         later : see {@link #updateCapabilities}.
9415      * @param initialScore the initial score of the network. See {@link NetworkAgentInfo#getScore}.
9416      * @param localNetworkConfig config about this local network, or null if not a local network
9417      * @param networkAgentConfig metadata about the network. This is never updated.
9418      * @param providerId the ID of the provider owning this NetworkAgent.
9419      * @return the network created for this agent.
9420      */
9421     public NetworkAndAgentRegistryParcelable registerNetworkAgent(INetworkAgent na,
9422             NetworkInfo networkInfo,
9423             LinkProperties linkProperties,
9424             NetworkCapabilities networkCapabilities,
9425             @NonNull NetworkScore initialScore,
9426             @Nullable LocalNetworkConfig localNetworkConfig,
9427             NetworkAgentConfig networkAgentConfig,
9428             int providerId) {
9429         Objects.requireNonNull(networkInfo, "networkInfo must not be null");
9430         Objects.requireNonNull(linkProperties, "linkProperties must not be null");
9431         Objects.requireNonNull(networkCapabilities, "networkCapabilities must not be null");
9432         Objects.requireNonNull(initialScore, "initialScore must not be null");
9433         Objects.requireNonNull(networkAgentConfig, "networkAgentConfig must not be null");
9434         if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
9435             enforceAnyPermissionOf(mContext, Manifest.permission.MANAGE_TEST_NETWORKS);
9436         } else {
9437             enforceNetworkFactoryPermission();
9438         }
9439         final boolean hasLocalCap =
9440                 networkCapabilities.hasCapability(NET_CAPABILITY_LOCAL_NETWORK);
9441         if (hasLocalCap && !areLocalAgentsSupported()) {
9442             // Before U, netd doesn't support PHYSICAL_LOCAL networks so this can't work.
9443             throw new IllegalArgumentException("Local agents are not supported in this version");
9444         }
9445         final boolean hasLocalNetworkConfig = null != localNetworkConfig;
9446         if (hasLocalCap != hasLocalNetworkConfig) {
9447             throw new IllegalArgumentException(null != localNetworkConfig
9448                     ? "Only local network agents can have a LocalNetworkConfig"
9449                     : "Local network agents must have a LocalNetworkConfig"
9450             );
9451         }
9452 
9453         final int uid = mDeps.getCallingUid();
9454         final long token = Binder.clearCallingIdentity();
9455         try {
9456             return registerNetworkAgentInternal(na, networkInfo, linkProperties,
9457                     networkCapabilities, initialScore, networkAgentConfig, localNetworkConfig,
9458                     providerId, uid);
9459         } finally {
9460             Binder.restoreCallingIdentity(token);
9461         }
9462     }
9463 
9464     private NetworkAndAgentRegistryParcelable registerNetworkAgentInternal(
9465             INetworkAgent na, NetworkInfo networkInfo,
9466             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
9467             NetworkScore currentScore, NetworkAgentConfig networkAgentConfig,
9468             @Nullable LocalNetworkConfig localNetworkConfig, int providerId,
9469             int uid) {
9470 
9471         // Make a copy of the passed NI, LP, NC as the caller may hold a reference to them
9472         // and mutate them at any time.
9473         final NetworkInfo niCopy = new NetworkInfo(networkInfo);
9474         final NetworkCapabilities ncCopy = new NetworkCapabilities(networkCapabilities);
9475         final LinkProperties lpCopy = new LinkProperties(linkProperties);
9476         // No need to copy |localNetworkConfiguration| as it is immutable.
9477 
9478         // At this point the capabilities/properties are untrusted and unverified, e.g. checks that
9479         // the capabilities' access UIDs comply with security limitations. They will be sanitized
9480         // as the NAI registration finishes, in handleRegisterNetworkAgent(). This is
9481         // because some of the checks must happen on the handler thread.
9482         final NetworkAgentInfo nai = new NetworkAgentInfo(na,
9483                 new Network(mNetIdManager.reserveNetId()), niCopy, lpCopy, ncCopy,
9484                 localNetworkConfig, currentScore, mContext, mTrackerHandler,
9485                 new NetworkAgentConfig(networkAgentConfig), this, mNetd, mDnsResolver, providerId,
9486                 uid, mLingerDelayMs, mQosCallbackTracker, mDeps);
9487 
9488         final String extraInfo = niCopy.getExtraInfo();
9489         final String name = TextUtils.isEmpty(extraInfo)
9490                 ? nai.networkCapabilities.getSsid() : extraInfo;
9491         if (DBG) log("registerNetworkAgent " + nai);
9492         mDeps.getNetworkStack().makeNetworkMonitor(
9493                 nai.network, name, new NetworkMonitorCallbacks(nai));
9494         // NetworkAgentInfo registration is done, but CS will only accept messages when the
9495         // NetworkMonitor is created. If the network disconnects or sends any other event
9496         // before that, messages are deferred by the Tracker Handler until it is (by asking
9497         // NetworkAgentInfo to do it). The window is very small unless the NetworkStack
9498         // doesn't reply immediately, which would mean a broken system anyway.
9499         final NetworkAndAgentRegistryParcelable result = new NetworkAndAgentRegistryParcelable();
9500         result.network = nai.network;
9501         result.registry = nai.getRegistry();
9502         return result;
9503     }
9504 
9505     private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) {
9506         if (VDBG) log("Network Monitor created for " +  nai);
9507         // Store a copy of the declared capabilities.
9508         nai.setDeclaredCapabilities(nai.networkCapabilities);
9509         // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info said.
9510         nai.getAndSetNetworkCapabilities(mixInCapabilities(nai,
9511                 nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator)));
9512         processLinkPropertiesFromAgent(nai, nai.linkProperties);
9513 
9514         mNetworkAgentInfos.add(nai);
9515         synchronized (mNetworkForNetId) {
9516             mNetworkForNetId.put(nai.network.getNetId(), nai);
9517         }
9518 
9519         try {
9520             networkMonitor.start();
9521         } catch (RemoteException e) {
9522             e.rethrowAsRuntimeException();
9523         }
9524 
9525         if (nai.isLocalNetwork()) {
9526             handleUpdateLocalNetworkConfig(nai, null /* oldConfig */, nai.localNetworkConfig);
9527         }
9528         nai.notifyRegistered(networkMonitor);
9529         NetworkInfo networkInfo = nai.networkInfo;
9530         updateNetworkInfo(nai, networkInfo);
9531         if (nai.isVPN()) updateVpnUids(nai, null, nai.networkCapabilities);
9532         nai.processEnqueuedMessages(mTrackerHandler::handleMessage);
9533     }
9534 
9535     private class NetworkOfferInfo implements IBinder.DeathRecipient {
9536         @NonNull public final NetworkOffer offer;
9537 
9538         NetworkOfferInfo(@NonNull final NetworkOffer offer) {
9539             this.offer = offer;
9540         }
9541 
9542         @Override
9543         public void binderDied() {
9544             mHandler.post(() -> handleUnregisterNetworkOffer(this, true /* releaseReservations */));
9545         }
9546     }
9547 
9548     private boolean isNetworkProviderWithIdRegistered(final int providerId) {
9549         for (final NetworkProviderInfo npi : mNetworkProviderInfos.values()) {
9550             if (npi.providerId == providerId) return true;
9551         }
9552         return false;
9553     }
9554 
9555     @Nullable
9556     private NetworkRequestInfo maybeGetNriForReservedOffer(NetworkOfferInfo noi) {
9557         final int reservationId = noi.offer.caps.getReservationId();
9558         if (reservationId == RES_ID_UNSET) return null; // not a reserved offer.
9559 
9560         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
9561             if (reservationId == nri.getReservationId()) return nri;
9562         }
9563         // The reservation was withdrawn or the reserving process died.
9564         return null;
9565     }
9566 
9567     /**
9568      * Register or update a network offer.
9569      * @param newOffer The new offer. If the callback member is the same as an existing
9570      *                 offer, it is an update of that offer.
9571      */
9572     // TODO : rename this to handleRegisterOrUpdateNetworkOffer
9573     private void handleRegisterNetworkOffer(@NonNull final NetworkOffer newOffer) {
9574         ensureRunningOnConnectivityServiceThread();
9575         if (!isNetworkProviderWithIdRegistered(newOffer.providerId)) {
9576             // This may actually happen if a provider updates its score or registers and then
9577             // immediately unregisters. The offer would still be in the handler queue, but the
9578             // provider would have been removed.
9579             if (DBG) log("Received offer from an unregistered provider");
9580             return;
9581         }
9582         final NetworkOfferInfo existingOffer = findNetworkOfferInfoByCallback(newOffer.callback);
9583 
9584         // If a reserved offer is updated, ensure the capabilities are not changed. This ensures
9585         // that the reserved offer's capabilities match the ones passed by the onReserved callback,
9586         // which is sent only once.
9587         //
9588         // TODO: consider letting the provider change the capabilities of an offer as long as they
9589         // continue to satisfy the capabilities that were passed to onReserved. This is not needed
9590         // today, but it shouldn't violate the API contract:
9591         // - NetworkOffer capabilities are not promises
9592         // - The app making a reservation must never assume that the capabilities of the reserved
9593         // network are equal to the ones that were passed to onReserved. There will almost always be
9594         // other capabilities, for example, those that change at runtime such as VALIDATED or
9595         // NOT_SUSPENDED.
9596         if (null != existingOffer
9597                 && existingOffer.offer.caps.getReservationId() != RES_ID_UNSET
9598                 && existingOffer.offer.caps.getReservationId() != RES_ID_MATCH_ALL_RESERVATIONS
9599                 && !newOffer.caps.equals(existingOffer.offer.caps)) {
9600             // Reserved offers are not allowed to update their NetworkCapabilities.
9601             // Doing so will immediately remove the offer from CS and send onUnavailable to the app.
9602             handleUnregisterNetworkOffer(existingOffer, true /* releaseReservations */);
9603             existingOffer.offer.notifyUnneeded();
9604             logwtf("Reserved offers must never update their reserved NetworkCapabilities");
9605             return;
9606         }
9607 
9608         final NetworkOfferInfo noi = new NetworkOfferInfo(newOffer);
9609         if (null != existingOffer) {
9610             // Do not send onUnavailable for a reserved offer when updating it.
9611             handleUnregisterNetworkOffer(existingOffer, false /* releaseReservations */);
9612             newOffer.migrateFrom(existingOffer.offer);
9613             if (DBG) {
9614                 // handleUnregisterNetworkOffer has already logged the old offer
9615                 log("update offer from providerId " + newOffer.providerId + " new : " + newOffer);
9616             }
9617         } else {
9618             final NetworkRequestInfo reservationNri = maybeGetNriForReservedOffer(noi);
9619             if (reservationNri != null) {
9620                 // A NetworkRequest is only allowed to trigger a single reserved offer (and
9621                 // onReserved() callback). All subsequent offers are ignored. This either indicates
9622                 // a bug in the provider (e.g., responding twice to the same reservation, or
9623                 // updating the capabilities of a reserved offer), or multiple providers responding
9624                 // to the same offer (which could happen, but is not useful to the requesting app).
9625                 if (reservationNri.getReservedCapabilities() != null) {
9626                     loge("A reservation can only trigger a single offer; new offer is ignored.");
9627                     return;
9628                 }
9629                 // Always update the reserved offer before calling callCallbackForRequest.
9630                 reservationNri.setReservedCapabilities(noi.offer.caps);
9631                 callCallbackForRequest(
9632                         reservationNri, null /*networkAgent*/, CALLBACK_RESERVED, 0 /*arg1*/);
9633             }
9634             if (DBG) {
9635                 log("register offer from providerId " + newOffer.providerId + " : " + newOffer);
9636             }
9637         }
9638 
9639         try {
9640             noi.offer.callback.asBinder().linkToDeath(noi, 0 /* flags */);
9641         } catch (RemoteException e) {
9642             noi.binderDied();
9643             return;
9644         }
9645         mNetworkOffers.add(noi);
9646         issueNetworkNeeds(noi);
9647     }
9648 
9649     private void handleUnregisterNetworkOffer(@NonNull final NetworkOfferInfo noi,
9650                     boolean releaseReservations) {
9651         ensureRunningOnConnectivityServiceThread();
9652         if (DBG) {
9653             log("unregister offer from providerId " + noi.offer.providerId + " : " + noi.offer);
9654         }
9655 
9656         // If the provider removes the offer and dies immediately afterwards this
9657         // function may be called twice in a row, but the array will no longer contain
9658         // the offer.
9659         if (!mNetworkOffers.remove(noi)) return;
9660 
9661         // If the offer was brought up as a result of a reservation, inform the RESERVATION request
9662         // that it has disappeared. There is no need to reset nri.mReservedCapabilities to null, as
9663         // CALLBACK_UNAVAIL will cause the request to be torn down. In addition, leaving
9664         // nri.mReservedOffer set prevents an additional onReserved() callback in
9665         // handleRegisterNetworkOffer() in the case of a migration (which would be ignored as it
9666         // follows an onUnavailable).
9667         final NetworkRequestInfo nri = maybeGetNriForReservedOffer(noi);
9668         if (releaseReservations && nri != null) {
9669             handleRemoveNetworkRequest(nri);
9670             callCallbackForRequest(nri, null /* networkAgent */, CALLBACK_UNAVAIL, 0 /* arg1 */);
9671         }
9672         noi.offer.callback.asBinder().unlinkToDeath(noi, 0 /* flags */);
9673     }
9674 
9675     @Nullable private NetworkOfferInfo findNetworkOfferInfoByCallback(
9676             @NonNull final INetworkOfferCallback callback) {
9677         ensureRunningOnConnectivityServiceThread();
9678         for (final NetworkOfferInfo noi : mNetworkOffers) {
9679             if (noi.offer.callback.asBinder().equals(callback.asBinder())) return noi;
9680         }
9681         return null;
9682     }
9683 
9684     /**
9685      * Called when receiving LinkProperties directly from a NetworkAgent.
9686      * Stores into |nai| any data coming from the agent that might also be written to the network's
9687      * LinkProperties by ConnectivityService itself. This ensures that the data provided by the
9688      * agent is not lost when updateLinkProperties is called.
9689      * This method should never alter the agent's LinkProperties, only store data in |nai|.
9690      */
9691     private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) {
9692         lp.ensureDirectlyConnectedRoutes();
9693         nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix());
9694         nai.networkAgentPortalData = lp.getCaptivePortalData();
9695     }
9696 
9697     private void updateLinkProperties(NetworkAgentInfo networkAgent, @NonNull LinkProperties newLp,
9698             @Nullable LinkProperties oldLp) {
9699         int netId = networkAgent.network.getNetId();
9700 
9701         // The NetworkAgent does not know whether clatd is running on its network or not, or whether
9702         // a NAT64 prefix was discovered by the DNS resolver. Before we do anything else, make sure
9703         // the LinkProperties for the network are accurate.
9704         networkAgent.clatd.fixupLinkProperties(oldLp, newLp);
9705 
9706         updateInterfaces(newLp, oldLp, netId, networkAgent);
9707 
9708         // update filtering rules, need to happen after the interface update so netd knows about the
9709         // new interface (the interface name -> index map becomes initialized)
9710         updateVpnFiltering(newLp, oldLp, networkAgent);
9711 
9712         updateIngressToVpnAddressFiltering(newLp, oldLp, networkAgent);
9713 
9714         updateMtu(newLp, oldLp);
9715         // TODO - figure out what to do for clat
9716 //        for (LinkProperties lp : newLp.getStackedLinks()) {
9717 //            updateMtu(lp, null);
9718 //        }
9719         if (isDefaultNetwork(networkAgent)) {
9720             mProxyTracker.updateDefaultNetworkProxyPortForPAC(newLp, null);
9721             updateTcpBufferSizes(newLp.getTcpBufferSizes());
9722         }
9723 
9724         updateRoutes(newLp, oldLp, netId);
9725         updateDnses(newLp, oldLp, netId);
9726         // Make sure LinkProperties represents the latest private DNS status.
9727         // This does not need to be done before updateDnses because the
9728         // LinkProperties are not the source of the private DNS configuration.
9729         // updateDnses will fetch the private DNS configuration from DnsManager.
9730         mDnsManager.updatePrivateDnsStatus(netId, newLp);
9731 
9732         if (isDefaultNetwork(networkAgent)) {
9733             mProxyTracker.setDefaultProxy(newLp.getHttpProxy());
9734         } else if (networkAgent.everConnected()) {
9735             updateProxy(newLp, oldLp);
9736         }
9737 
9738         updateWakeOnLan(newLp);
9739 
9740         // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo.
9741         // It is not always contained in the LinkProperties sent from NetworkAgents, and if it
9742         // does, it needs to be merged here.
9743         newLp.setCaptivePortalData(mergeCaptivePortalData(networkAgent.networkAgentPortalData,
9744                 networkAgent.capportApiData));
9745 
9746         // TODO - move this check to cover the whole function
9747         if (!Objects.equals(newLp, oldLp)) {
9748             synchronized (networkAgent) {
9749                 networkAgent.linkProperties = newLp;
9750             }
9751             // Start or stop DNS64 detection and 464xlat according to network state.
9752             networkAgent.clatd.update();
9753             // Notify NSS when relevant events happened. Currently, NSS only cares about
9754             // interface changed to update clat interfaces accounting.
9755             final boolean interfacesChanged = oldLp == null
9756                     || !Objects.equals(newLp.getAllInterfaceNames(), oldLp.getAllInterfaceNames());
9757             if (interfacesChanged) {
9758                 notifyIfacesChangedForNetworkStats();
9759             }
9760             networkAgent.networkMonitor().notifyLinkPropertiesChanged(
9761                     new LinkProperties(newLp, true /* parcelSensitiveFields */));
9762             notifyNetworkCallbacks(networkAgent, CALLBACK_IP_CHANGED);
9763         }
9764 
9765         mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent);
9766     }
9767 
9768     private void applyInitialLinkProperties(@NonNull NetworkAgentInfo nai) {
9769         updateLinkProperties(nai, new LinkProperties(nai.linkProperties), null);
9770     }
9771 
9772     /**
9773      * @param naData captive portal data from NetworkAgent
9774      * @param apiData captive portal data from capport API
9775      */
9776     @Nullable
9777     private CaptivePortalData mergeCaptivePortalData(CaptivePortalData naData,
9778             CaptivePortalData apiData) {
9779         if (naData == null || apiData == null) {
9780             return naData == null ? apiData : naData;
9781         }
9782         final CaptivePortalData.Builder captivePortalBuilder =
9783                 new CaptivePortalData.Builder(naData);
9784 
9785         if (apiData.isCaptive()) {
9786             captivePortalBuilder.setCaptive(true);
9787         }
9788         if (apiData.isSessionExtendable()) {
9789             captivePortalBuilder.setSessionExtendable(true);
9790         }
9791         if (apiData.getExpiryTimeMillis() >= 0 || apiData.getByteLimit() >= 0) {
9792             // Expiry time, bytes remaining, refresh time all need to come from the same source,
9793             // otherwise data would be inconsistent. Prefer the capport API info if present,
9794             // as it can generally be refreshed more often.
9795             captivePortalBuilder.setExpiryTime(apiData.getExpiryTimeMillis());
9796             captivePortalBuilder.setBytesRemaining(apiData.getByteLimit());
9797             captivePortalBuilder.setRefreshTime(apiData.getRefreshTimeMillis());
9798         } else if (naData.getExpiryTimeMillis() < 0 && naData.getByteLimit() < 0) {
9799             // No source has time / bytes remaining information: surface the newest refresh time
9800             // for other fields
9801             captivePortalBuilder.setRefreshTime(
9802                     Math.max(naData.getRefreshTimeMillis(), apiData.getRefreshTimeMillis()));
9803         }
9804 
9805         // Prioritize the user portal URL from the network agent if the source is authenticated.
9806         if (apiData.getUserPortalUrl() != null && naData.getUserPortalUrlSource()
9807                 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) {
9808             captivePortalBuilder.setUserPortalUrl(apiData.getUserPortalUrl(),
9809                     apiData.getUserPortalUrlSource());
9810         }
9811         // Prioritize the venue information URL from the network agent if the source is
9812         // authenticated.
9813         if (apiData.getVenueInfoUrl() != null && naData.getVenueInfoUrlSource()
9814                 != CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) {
9815             captivePortalBuilder.setVenueInfoUrl(apiData.getVenueInfoUrl(),
9816                     apiData.getVenueInfoUrlSource());
9817         }
9818         return captivePortalBuilder.build();
9819     }
9820 
9821     @VisibleForTesting
9822     static String makeNflogPrefix(String iface, long networkHandle) {
9823         // This needs to be kept in sync and backwards compatible with the decoding logic in
9824         // NetdEventListenerService, which is non-mainline code.
9825         return SdkLevel.isAtLeastU() ? (networkHandle + ":" + iface) : ("iface:" + iface);
9826     }
9827 
9828     private static boolean isWakeupMarkingSupported(NetworkCapabilities capabilities) {
9829         if (capabilities.hasTransport(TRANSPORT_WIFI)) {
9830             return true;
9831         }
9832         if (SdkLevel.isAtLeastU() && capabilities.hasTransport(TRANSPORT_CELLULAR)) {
9833             return true;
9834         }
9835         return false;
9836     }
9837 
9838     private void wakeupModifyInterface(String iface, NetworkAgentInfo nai, boolean add) {
9839         // Marks are only available on WiFi interfaces. Checking for
9840         // marks on unsupported interfaces is harmless.
9841         if (!isWakeupMarkingSupported(nai.networkCapabilities)) {
9842             return;
9843         }
9844 
9845         // Mask/mark of zero will not detect anything interesting.
9846         // Don't install rules unless both values are nonzero.
9847         if (mWakeUpMark == 0 || mWakeUpMask == 0) {
9848             return;
9849         }
9850 
9851         final String prefix = makeNflogPrefix(iface, nai.network.getNetworkHandle());
9852         try {
9853             if (add) {
9854                 mNetd.wakeupAddInterface(iface, prefix, mWakeUpMark, mWakeUpMask);
9855             } else {
9856                 mNetd.wakeupDelInterface(iface, prefix, mWakeUpMark, mWakeUpMask);
9857             }
9858         } catch (Exception e) {
9859             loge("Exception modifying wakeup packet monitoring: " + e);
9860         }
9861     }
9862 
9863     private void updateInterfaces(final @NonNull LinkProperties newLp,
9864             final @Nullable LinkProperties oldLp, final int netId,
9865             final @NonNull NetworkAgentInfo nai) {
9866         final CompareResult<String> interfaceDiff = new CompareResult<>(
9867                 oldLp != null ? oldLp.getAllInterfaceNames() : null, newLp.getAllInterfaceNames());
9868         if (!interfaceDiff.added.isEmpty()) {
9869             for (final String iface : interfaceDiff.added) {
9870                 try {
9871                     if (DBG) log("Adding iface " + iface + " to network " + netId);
9872                     mRoutingCoordinatorService.addInterfaceToNetwork(netId, iface);
9873                     wakeupModifyInterface(iface, nai, true);
9874                     mDeps.reportNetworkInterfaceForTransports(mContext, iface,
9875                             nai.networkCapabilities.getTransportTypes());
9876                     mInterfaceTracker.addInterface(iface);
9877                 } catch (Exception e) {
9878                     logw("Exception adding interface: " + e);
9879                 }
9880             }
9881         }
9882 
9883         // The local network addresses needs to be updated before interfaces are removed because
9884         // modifying bpf map local_net_access requires mapping interface name to index.
9885         updateLocalNetworkAddresses(newLp, oldLp);
9886 
9887         for (final String iface : interfaceDiff.removed) {
9888             try {
9889                 if (DBG) log("Removing iface " + iface + " from network " + netId);
9890                 wakeupModifyInterface(iface, nai, false);
9891                 mRoutingCoordinatorService.removeInterfaceFromNetwork(netId, iface);
9892                 mInterfaceTracker.removeInterface(iface);
9893             } catch (Exception e) {
9894                 loge("Exception removing interface: " + e);
9895             }
9896         }
9897     }
9898 
9899     /**
9900      * Update Local Network Addresses to LocalNetAccess BPF map.
9901      * @param newLp new link properties
9902      * @param oldLp old link properties
9903      */
9904     private void updateLocalNetworkAddresses(@Nullable final LinkProperties newLp,
9905             @NonNull final LinkProperties oldLp) {
9906 
9907         // The maps are available only after 25Q2 release
9908         if (!BpfNetMaps.isAtLeast25Q2()) {
9909             return;
9910         }
9911 
9912         final CompareResult<String> interfaceDiff = new CompareResult<>(
9913                 oldLp != null ? oldLp.getAllInterfaceNames() : null,
9914                 newLp != null ? newLp.getAllInterfaceNames() : null);
9915 
9916         for (final String iface : interfaceDiff.added) {
9917             addLocalAddressesToBpfMap(iface, MULTICAST_AND_BROADCAST_PREFIXES, newLp);
9918         }
9919         for (final String iface : interfaceDiff.removed) {
9920             removeLocalAddressesFromBpfMap(iface, MULTICAST_AND_BROADCAST_PREFIXES, oldLp);
9921         }
9922 
9923         // The both list contain current link properties + stacked links for new and old LP.
9924         final List<LinkProperties> newLinkProperties = new ArrayList<>();
9925         final List<LinkProperties> oldLinkProperties = new ArrayList<>();
9926 
9927         if (newLp != null) {
9928             newLinkProperties.add(newLp);
9929             newLinkProperties.addAll(newLp.getStackedLinks());
9930         }
9931         if (oldLp != null) {
9932             oldLinkProperties.add(oldLp);
9933             oldLinkProperties.addAll(oldLp.getStackedLinks());
9934         }
9935 
9936         // map contains interface name to list of local network prefixes added because of change
9937         // in link properties
9938         final Map<String, List<IpPrefix>> prefixesAddedForInterface = new ArrayMap<>();
9939 
9940         final CompareResult<LinkProperties> linkPropertiesDiff = new CompareResult<>(
9941                 oldLinkProperties, newLinkProperties);
9942 
9943         for (LinkProperties linkProperty : linkPropertiesDiff.added) {
9944             final List<IpPrefix> unicastLocalPrefixesToBeAdded = new ArrayList<>();
9945             for (LinkAddress linkAddress : linkProperty.getLinkAddresses()) {
9946                 unicastLocalPrefixesToBeAdded.addAll(
9947                         getLocalNetworkPrefixesForAddress(linkAddress));
9948             }
9949             addLocalAddressesToBpfMap(linkProperty.getInterfaceName(),
9950                     unicastLocalPrefixesToBeAdded, linkProperty);
9951 
9952             // populating interface name -> ip prefixes which were added to local_net_access map.
9953             if (!prefixesAddedForInterface.containsKey(linkProperty.getInterfaceName())) {
9954                 prefixesAddedForInterface.put(linkProperty.getInterfaceName(), new ArrayList<>());
9955             }
9956             prefixesAddedForInterface.get(linkProperty.getInterfaceName())
9957                     .addAll(unicastLocalPrefixesToBeAdded);
9958         }
9959 
9960         for (LinkProperties linkProperty : linkPropertiesDiff.removed) {
9961             final List<IpPrefix> unicastLocalPrefixesToBeRemoved = new ArrayList<>();
9962             final List<IpPrefix> unicastLocalPrefixesAdded = prefixesAddedForInterface.getOrDefault(
9963                     linkProperty.getInterfaceName(), Collections.emptyList());
9964 
9965             for (LinkAddress linkAddress : linkProperty.getLinkAddresses()) {
9966                 unicastLocalPrefixesToBeRemoved.addAll(
9967                         getLocalNetworkPrefixesForAddress(linkAddress));
9968             }
9969 
9970             // This is to ensure if 10.0.10.0/24 was added and 10.0.11.0/24 was removed both will
9971             // still populate the same prefix of 10.0.0.0/8, which mean 10.0.0.0/8 should not be
9972             // removed due to removal of 10.0.11.0/24
9973             unicastLocalPrefixesToBeRemoved.removeAll(unicastLocalPrefixesAdded);
9974 
9975             removeLocalAddressesFromBpfMap(linkProperty.getInterfaceName(),
9976                     new ArrayList<>(unicastLocalPrefixesToBeRemoved), linkProperty);
9977         }
9978     }
9979 
9980     /**
9981      * Filters IpPrefix that are local prefixes and LinkAddress is part of them.
9982      * @param linkAddress link address used for filtering
9983      * @return list of IpPrefix that are local addresses.
9984      */
9985     private List<IpPrefix> getLocalNetworkPrefixesForAddress(LinkAddress linkAddress) {
9986         List<IpPrefix> localPrefixes = new ArrayList<>();
9987         if (linkAddress.isIpv6()) {
9988             // For IPv6, if the prefix length is greater than zero then they are part of local
9989             // network
9990             if (linkAddress.getPrefixLength() != 0) {
9991                 localPrefixes.add(
9992                         new IpPrefix(linkAddress.getAddress(), linkAddress.getPrefixLength()));
9993             }
9994         } else {
9995             // For IPv4, if the linkAddress is part of IpPrefix adding prefix to result.
9996             for (IpPrefix ipv4LocalPrefix : IPV4_LOCAL_PREFIXES) {
9997                 if (ipv4LocalPrefix.containsPrefix(
9998                         new IpPrefix(linkAddress.getAddress(), linkAddress.getPrefixLength()))) {
9999                     localPrefixes.add(ipv4LocalPrefix);
10000                 }
10001             }
10002         }
10003         return localPrefixes;
10004     }
10005 
10006     /**
10007      * Adds list of prefixes(addresses) to local network access map.
10008      * @param iface interface name
10009      * @param prefixes list of prefixes/addresses
10010      * @param lp LinkProperties
10011      */
10012     private void addLocalAddressesToBpfMap(final String iface, final List<IpPrefix> prefixes,
10013                                            @Nullable final LinkProperties lp) {
10014         if (!BpfNetMaps.isAtLeast25Q2()) return;
10015 
10016         for (IpPrefix prefix : prefixes) {
10017             // Add local dnses allow rule To BpfMap before adding the block rule for prefix
10018             addLocalDnsesToBpfMap(iface, prefix, lp);
10019             /*
10020             Prefix length is used by LPM trie map(local_net_access_map) for performing longest
10021             prefix matching, this length represents the maximum number of bits used for matching.
10022             The interface index should always be matched which is 32-bit integer. For IPv6, prefix
10023             length is calculated by adding the ip address prefix length along with interface index
10024             making it (32 + length). IPv4 addresses are stored as ipv4-mapped-ipv6 which implies
10025             first 96 bits are common for all ipv4 addresses. Hence, prefix length is calculated as
10026             32(interface index) + 96 (common for ipv4-mapped-ipv6) + length.
10027              */
10028             final int prefixLengthConstant = (prefix.isIPv4() ? (32 + 96) : 32);
10029             mBpfNetMaps.addLocalNetAccess(prefixLengthConstant + prefix.getPrefixLength(),
10030                     iface, prefix.getAddress(), 0, 0, false);
10031 
10032         }
10033 
10034     }
10035 
10036     /**
10037      * Removes list of prefixes(addresses) from local network access map.
10038      * @param iface interface name
10039      * @param prefixes list of prefixes/addresses
10040      * @param lp LinkProperties
10041      */
10042     private void removeLocalAddressesFromBpfMap(final String iface, final List<IpPrefix> prefixes,
10043                                                 @Nullable final LinkProperties lp) {
10044         if (!BpfNetMaps.isAtLeast25Q2()) return;
10045 
10046         for (IpPrefix prefix : prefixes) {
10047             // The reasoning for prefix length is explained in addLocalAddressesToBpfMap()
10048             final int prefixLengthConstant = (prefix.isIPv4() ? (32 + 96) : 32);
10049             mBpfNetMaps.removeLocalNetAccess(prefixLengthConstant
10050                     + prefix.getPrefixLength(), iface, prefix.getAddress(), 0, 0);
10051 
10052             // Also remove the allow rule for dnses included in the prefix after removing the block
10053             // rule for prefix.
10054             removeLocalDnsesFromBpfMap(iface, prefix, lp);
10055         }
10056     }
10057 
10058     /**
10059      * Adds DNS servers to local network access map, if included in the interface prefix
10060      * @param iface interface name
10061      * @param prefix IpPrefix
10062      * @param lp LinkProperties
10063      */
10064     private void addLocalDnsesToBpfMap(final String iface, IpPrefix prefix,
10065             @Nullable final LinkProperties lp) {
10066         if (!BpfNetMaps.isAtLeast25Q2() || lp == null) return;
10067 
10068         for (InetAddress dnsServer : lp.getDnsServers()) {
10069             // Adds dns allow rule to LocalNetAccessMap for both TCP and UDP protocol at port 53,
10070             // if it is a local dns (ie. it falls in the local prefix range).
10071             if (prefix.contains(dnsServer)) {
10072                 mBpfNetMaps.addLocalNetAccess(32 + 128 + 16 + 16, iface, dnsServer,
10073                         IPPROTO_UDP, 53, true);
10074                 mBpfNetMaps.addLocalNetAccess(32 + 128 + 16 + 16, iface, dnsServer,
10075                         IPPROTO_TCP, 53, true);
10076                 mBpfNetMaps.addLocalNetAccess(32 + 128 + 16 + 16, iface, dnsServer,
10077                         IPPROTO_TCP, 853, true);  // DNS over TLS
10078             }
10079         }
10080     }
10081 
10082     /**
10083      * Removes DNS servers from local network access map, if included in the interface prefix
10084      * @param iface interface name
10085      * @param prefix IpPrefix
10086      * @param lp LinkProperties
10087      */
10088     private void removeLocalDnsesFromBpfMap(final String iface, IpPrefix prefix,
10089             @Nullable final LinkProperties lp) {
10090         if (!BpfNetMaps.isAtLeast25Q2() || lp == null) return;
10091 
10092         for (InetAddress dnsServer : lp.getDnsServers()) {
10093             // Removes dns allow rule from LocalNetAccessMap for both TCP and UDP protocol
10094             // at port 53, if it is a local dns (ie. it falls in the prefix range).
10095             if (prefix.contains(dnsServer)) {
10096                 mBpfNetMaps.removeLocalNetAccess(32 + 128 + 16 + 16, iface, dnsServer,
10097                         IPPROTO_UDP, 53);
10098                 mBpfNetMaps.removeLocalNetAccess(32 + 128 + 16 + 16, iface, dnsServer,
10099                         IPPROTO_TCP, 53);
10100                 mBpfNetMaps.removeLocalNetAccess(32 + 128 + 16 + 16, iface, dnsServer,
10101                         IPPROTO_TCP, 853);  // DNS over TLS
10102             }
10103         }
10104     }
10105 
10106     /**
10107      * Have netd update routes from oldLp to newLp.
10108      * @return true if routes changed between oldLp and newLp
10109      */
10110     private boolean updateRoutes(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp,
10111             int netId) {
10112         // compare the route diff to determine which routes have been updated
10113         final CompareOrUpdateResult<RouteInfo.RouteKey, RouteInfo> routeDiff =
10114                 new CompareOrUpdateResult<>(
10115                         oldLp != null ? oldLp.getAllRoutes() : null,
10116                         newLp.getAllRoutes(),
10117                         (r) -> r.getRouteKey());
10118 
10119         // add routes before removing old in case it helps with continuous connectivity
10120 
10121         // do this twice, adding non-next-hop routes first, then routes they are dependent on
10122         for (RouteInfo route : routeDiff.added) {
10123             if (route.hasGateway()) continue;
10124             if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
10125             try {
10126                 mRoutingCoordinatorService.addRoute(netId, route);
10127             } catch (Exception e) {
10128                 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) {
10129                     loge("Exception in addRoute for non-gateway: " + e);
10130                 }
10131             }
10132         }
10133         for (RouteInfo route : routeDiff.added) {
10134             if (!route.hasGateway()) continue;
10135             if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
10136             try {
10137                 mRoutingCoordinatorService.addRoute(netId, route);
10138             } catch (Exception e) {
10139                 if ((route.getGateway() instanceof Inet4Address) || VDBG) {
10140                     loge("Exception in addRoute for gateway: " + e);
10141                 }
10142             }
10143         }
10144 
10145         for (RouteInfo route : routeDiff.removed) {
10146             if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId);
10147             try {
10148                 mRoutingCoordinatorService.removeRoute(netId, route);
10149             } catch (Exception e) {
10150                 loge("Exception in removeRoute: " + e);
10151             }
10152         }
10153 
10154         for (RouteInfo route : routeDiff.updated) {
10155             if (VDBG || DDBG) log("Updating Route [" + route + "] from network " + netId);
10156             try {
10157                 mRoutingCoordinatorService.updateRoute(netId, route);
10158             } catch (Exception e) {
10159                 loge("Exception in updateRoute: " + e);
10160             }
10161         }
10162         return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty()
10163                 || !routeDiff.updated.isEmpty();
10164     }
10165 
10166     private void updateDnses(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp,
10167             int netId) {
10168         if (oldLp != null && newLp.isIdenticalDnses(oldLp)) {
10169             return;  // no updating necessary
10170         }
10171 
10172         if (DBG) {
10173             final Collection<InetAddress> dnses = newLp.getDnsServers();
10174             log("Setting DNS servers for network " + netId + " to " + dnses);
10175         }
10176         try {
10177             mDnsManager.noteDnsServersForNetwork(netId, newLp);
10178             mDnsManager.flushVmDnsCache();
10179         } catch (Exception e) {
10180             loge("Exception in setDnsConfigurationForNetwork: " + e);
10181         }
10182     }
10183 
10184     private void updateVpnFiltering(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp,
10185             @NonNull NetworkAgentInfo nai) {
10186         final String oldIface = getVpnIsolationInterface(nai, nai.networkCapabilities, oldLp);
10187         final String newIface = getVpnIsolationInterface(nai, nai.networkCapabilities, newLp);
10188         final boolean wasFiltering = requiresVpnAllowRule(nai, oldLp, oldIface);
10189         final boolean needsFiltering = requiresVpnAllowRule(nai, newLp, newIface);
10190 
10191         if (!wasFiltering && !needsFiltering) {
10192             // Nothing to do.
10193             return;
10194         }
10195 
10196         if (Objects.equals(oldIface, newIface) && (wasFiltering == needsFiltering)) {
10197             // Nothing changed.
10198             return;
10199         }
10200 
10201         final Set<UidRange> ranges = nai.networkCapabilities.getUidRanges();
10202         if (ranges == null || ranges.isEmpty()) {
10203             return;
10204         }
10205 
10206         final int vpnAppUid = nai.networkCapabilities.getOwnerUid();
10207         // TODO: this create a window of opportunity for apps to receive traffic between the time
10208         // when the old rules are removed and the time when new rules are added. To fix this,
10209         // make eBPF support two allowlisted interfaces so here new rules can be added before the
10210         // old rules are being removed.
10211         if (wasFiltering) {
10212             mPermissionMonitor.onVpnUidRangesRemoved(oldIface, ranges, vpnAppUid);
10213         }
10214         if (needsFiltering) {
10215             mPermissionMonitor.onVpnUidRangesAdded(newIface, ranges, vpnAppUid);
10216         }
10217     }
10218 
10219     /**
10220      * Returns ingress discard rules to drop packets to VPN addresses ingressing via non-VPN
10221      * interfaces.
10222      * Ingress discard rule is added to the address iff
10223      *   1. The address is not a link local address
10224      *   2. The address is used by a single interface of VPN whose VPN type is not LEGACY, OEM or
10225      *      OEM_LEGACY and the address is not used by any other interfaces even non-VPN ones
10226      * Ingress discard rule is not be added to TYPE_VPN_LEGACY or TYPE_VPN_OEM VPN since these VPNs
10227      * might need to receive packet to VPN address via non-VPN interface.
10228      * This method can be called during network disconnects, when nai has already been removed from
10229      * mNetworkAgentInfos.
10230      *
10231      * @param nai This method generates rules assuming lp of this nai is the lp at the second
10232      *            argument.
10233      * @param lp  This method generates rules assuming lp of nai at the first argument is this lp.
10234      *            Caller passes old lp to generate old rules and new lp to generate new rules.
10235      * @return    ingress discard rules. Set of pairs of addresses and interface names
10236      */
10237     private Set<Pair<InetAddress, String>> generateIngressDiscardRules(
10238             @NonNull final NetworkAgentInfo nai, @Nullable final LinkProperties lp) {
10239         Set<NetworkAgentInfo> nais = new ArraySet<>(mNetworkAgentInfos);
10240         nais.add(nai);
10241         // Determine how many networks each IP address is currently configured on.
10242         // Ingress rules are added only for IP addresses that are configured on single interface.
10243         final Map<InetAddress, Integer> addressOwnerCounts = new ArrayMap<>();
10244         for (final NetworkAgentInfo agent : nais) {
10245             if (agent.isDestroyed()) {
10246                 continue;
10247             }
10248             final LinkProperties agentLp = (nai == agent) ? lp : agent.linkProperties;
10249             if (agentLp == null) {
10250                 continue;
10251             }
10252             for (final InetAddress addr: agentLp.getAllAddresses()) {
10253                 addressOwnerCounts.put(addr, addressOwnerCounts.getOrDefault(addr, 0) + 1);
10254             }
10255         }
10256 
10257         // Iterates all networks instead of only generating rule for nai that was passed in since
10258         // lp of the nai change could cause/resolve address collision and result in affecting rule
10259         // for different network.
10260         final Set<Pair<InetAddress, String>> ingressDiscardRules = new ArraySet<>();
10261         for (final NetworkAgentInfo agent : nais) {
10262             final int vpnType = getVpnType(agent);
10263             if (!agent.isVPN() || agent.isDestroyed() || !vpnSupportsInterfaceFiltering(agent)) {
10264                 continue;
10265             }
10266             final LinkProperties agentLp = (nai == agent) ? lp : agent.linkProperties;
10267             if (agentLp == null || agentLp.getInterfaceName() == null) {
10268                 continue;
10269             }
10270 
10271             for (final InetAddress addr: agentLp.getAllAddresses()) {
10272                 if (addressOwnerCounts.get(addr) == 1 && !addr.isLinkLocalAddress()) {
10273                     ingressDiscardRules.add(new Pair<>(addr, agentLp.getInterfaceName()));
10274                 }
10275             }
10276         }
10277         return ingressDiscardRules;
10278     }
10279 
10280     private void updateIngressToVpnAddressFiltering(@Nullable LinkProperties newLp,
10281             @Nullable LinkProperties oldLp, @NonNull NetworkAgentInfo nai) {
10282         // Having isAtleastT to avoid NewApi linter error (b/303382209)
10283         if (!mIngressToVpnAddressFiltering || !mDeps.isAtLeastT()) {
10284             return;
10285         }
10286         final CompareOrUpdateResult<InetAddress, Pair<InetAddress, String>> ruleDiff =
10287                 new CompareOrUpdateResult<>(
10288                         generateIngressDiscardRules(nai, oldLp),
10289                         generateIngressDiscardRules(nai, newLp),
10290                         (rule) -> rule.first);
10291         for (Pair<InetAddress, String> rule: ruleDiff.removed) {
10292             mBpfNetMaps.removeIngressDiscardRule(rule.first);
10293         }
10294         for (Pair<InetAddress, String> rule: ruleDiff.added) {
10295             mBpfNetMaps.setIngressDiscardRule(rule.first, rule.second);
10296         }
10297         // setIngressDiscardRule overrides the existing rule
10298         for (Pair<InetAddress, String> rule: ruleDiff.updated) {
10299             mBpfNetMaps.setIngressDiscardRule(rule.first, rule.second);
10300         }
10301     }
10302 
10303     private void updateWakeOnLan(@NonNull LinkProperties lp) {
10304         if (mWolSupportedInterfaces == null) {
10305             mWolSupportedInterfaces = new ArraySet<>(mResources.get().getStringArray(
10306                     R.array.config_wakeonlan_supported_interfaces));
10307         }
10308         lp.setWakeOnLanSupported(mWolSupportedInterfaces.contains(lp.getInterfaceName()));
10309     }
10310 
10311     private int getNetworkPermission(NetworkCapabilities nc) {
10312         if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
10313             return INetd.PERMISSION_SYSTEM;
10314         }
10315         if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) {
10316             return INetd.PERMISSION_NETWORK;
10317         }
10318         return INetd.PERMISSION_NONE;
10319     }
10320 
10321     private void updateNetworkPermissions(@NonNull final NetworkAgentInfo nai,
10322             @NonNull final NetworkCapabilities newNc) {
10323         final int oldPermission = getNetworkPermission(nai.networkCapabilities);
10324         final int newPermission = getNetworkPermission(newNc);
10325         if (oldPermission != newPermission && nai.isCreated() && !nai.isVPN()) {
10326             try {
10327                 mNetd.networkSetPermissionForNetwork(nai.network.getNetId(), newPermission);
10328             } catch (RemoteException | ServiceSpecificException e) {
10329                 loge("Exception in networkSetPermissionForNetwork: " + e);
10330             }
10331         }
10332     }
10333 
10334     /** Modifies |newNc| based on the capabilities of |underlyingNetworks| and |agentCaps|. */
10335     @VisibleForTesting
10336     void applyUnderlyingCapabilities(@Nullable Network[] underlyingNetworks,
10337             @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) {
10338         underlyingNetworks = underlyingNetworksOrDefault(
10339                 agentCaps.getOwnerUid(), underlyingNetworks);
10340         long transportTypes = BitUtils.packBits(agentCaps.getTransportTypes());
10341         int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
10342         int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
10343         // metered if any underlying is metered, or originally declared metered by the agent.
10344         boolean metered = !agentCaps.hasCapability(NET_CAPABILITY_NOT_METERED);
10345         boolean roaming = false; // roaming if any underlying is roaming
10346         boolean congested = false; // congested if any underlying is congested
10347         boolean suspended = true; // suspended if all underlying are suspended
10348 
10349         boolean hadUnderlyingNetworks = false;
10350         ArrayList<Network> newUnderlyingNetworks = null;
10351         if (null != underlyingNetworks) {
10352             newUnderlyingNetworks = new ArrayList<>();
10353             for (Network underlyingNetwork : underlyingNetworks) {
10354                 final NetworkAgentInfo underlying =
10355                         getNetworkAgentInfoForNetwork(underlyingNetwork);
10356                 if (underlying == null) continue;
10357 
10358                 final NetworkCapabilities underlyingCaps = underlying.networkCapabilities;
10359                 hadUnderlyingNetworks = true;
10360                 for (int underlyingType : underlyingCaps.getTransportTypes()) {
10361                     transportTypes |= 1L << underlyingType;
10362                 }
10363 
10364                 // Merge capabilities of this underlying network. For bandwidth, assume the
10365                 // worst case.
10366                 downKbps = NetworkCapabilities.minBandwidth(downKbps,
10367                         underlyingCaps.getLinkDownstreamBandwidthKbps());
10368                 upKbps = NetworkCapabilities.minBandwidth(upKbps,
10369                         underlyingCaps.getLinkUpstreamBandwidthKbps());
10370                 // If this underlying network is metered, the VPN is metered (it may cost money
10371                 // to send packets on this network).
10372                 metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED);
10373                 // If this underlying network is roaming, the VPN is roaming (the billing structure
10374                 // is different than the usual, local one).
10375                 roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING);
10376                 // If this underlying network is congested, the VPN is congested (the current
10377                 // condition of the network affects the performance of this network).
10378                 congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED);
10379                 // If this network is not suspended, the VPN is not suspended (the VPN
10380                 // is able to transfer some data).
10381                 suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
10382                 newUnderlyingNetworks.add(underlyingNetwork);
10383             }
10384         }
10385         if (!hadUnderlyingNetworks) {
10386             // No idea what the underlying networks are; assume reasonable defaults
10387             metered = true;
10388             roaming = false;
10389             congested = false;
10390             suspended = false;
10391         }
10392 
10393         newNc.setTransportTypes(BitUtils.unpackBits(transportTypes));
10394         newNc.setLinkDownstreamBandwidthKbps(downKbps);
10395         newNc.setLinkUpstreamBandwidthKbps(upKbps);
10396         newNc.setCapability(NET_CAPABILITY_NOT_METERED, !metered);
10397         newNc.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming);
10398         newNc.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested);
10399         newNc.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended);
10400         newNc.setUnderlyingNetworks(newUnderlyingNetworks);
10401     }
10402 
10403     /**
10404      * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are
10405      * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal,
10406      * and foreground status).
10407      */
10408     @NonNull
10409     private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) {
10410         // Once a NetworkAgent is connected, complain if some immutable capabilities are removed.
10411          // Don't complain for VPNs since they're not driven by requests and there is no risk of
10412          // causing a connect/teardown loop.
10413          // TODO: remove this altogether and make it the responsibility of the NetworkProviders to
10414          // avoid connect/teardown loops.
10415         if (nai.everConnected()
10416                 && !nai.isVPN()
10417                 && !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) {
10418             // TODO: consider not complaining when a network agent degrades its capabilities if this
10419             // does not cause any request (that is not a listen) currently matching that agent to
10420             // stop being matched by the updated agent.
10421             String diff = nai.networkCapabilities.describeImmutableDifferences(nc);
10422             if (!TextUtils.isEmpty(diff)) {
10423                 Log.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff);
10424             }
10425         }
10426 
10427         // Don't modify caller's NetworkCapabilities.
10428         final NetworkCapabilities newNc = new NetworkCapabilities(nc);
10429         if (nai.isValidated()) {
10430             newNc.addCapability(NET_CAPABILITY_VALIDATED);
10431         } else {
10432             newNc.removeCapability(NET_CAPABILITY_VALIDATED);
10433         }
10434         if (nai.captivePortalDetected()) {
10435             newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
10436         } else {
10437             newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
10438         }
10439         if (nai.isBackgroundNetwork()) {
10440             newNc.removeCapability(NET_CAPABILITY_FOREGROUND);
10441         } else {
10442             newNc.addCapability(NET_CAPABILITY_FOREGROUND);
10443         }
10444         if (nai.partialConnectivity()) {
10445             newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
10446         } else {
10447             newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
10448         }
10449         newNc.setPrivateDnsBroken(nai.networkCapabilities.isPrivateDnsBroken());
10450 
10451         // TODO : remove this once all factories are updated to send NOT_SUSPENDED and NOT_ROAMING
10452         if (!newNc.hasTransport(TRANSPORT_CELLULAR)) {
10453             newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
10454             newNc.addCapability(NET_CAPABILITY_NOT_ROAMING);
10455         }
10456 
10457         if (nai.propagateUnderlyingCapabilities()) {
10458             applyUnderlyingCapabilities(nai.declaredUnderlyingNetworks,
10459                     nai.getDeclaredCapabilitiesSanitized(mCarrierPrivilegeAuthenticator),
10460                     newNc);
10461         }
10462 
10463         return newNc;
10464     }
10465 
10466     private void updateNetworkInfoForRoamingAndSuspended(NetworkAgentInfo nai,
10467             NetworkCapabilities prevNc, NetworkCapabilities newNc) {
10468         final boolean prevSuspended = !prevNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
10469         final boolean suspended = !newNc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
10470         final boolean prevRoaming = !prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
10471         final boolean roaming = !newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
10472         if (prevSuspended != suspended) {
10473             // TODO (b/73132094) : remove this call once the few users of onSuspended and
10474             // onResumed have been removed.
10475             notifyNetworkCallbacks(nai, suspended ? CALLBACK_SUSPENDED : CALLBACK_RESUMED);
10476         }
10477         if (prevSuspended != suspended || prevRoaming != roaming) {
10478             // updateNetworkInfo will mix in the suspended info from the capabilities and
10479             // take appropriate action for the network having possibly changed state.
10480             updateNetworkInfo(nai, nai.networkInfo);
10481         }
10482     }
10483 
10484     private void handleUidCarrierPrivilegesLost(int uid, int subId) {
10485         if (!mRequestRestrictedWifiEnabled) {
10486             return;
10487         }
10488         ensureRunningOnConnectivityServiceThread();
10489         // A NetworkRequest needs to be revoked when all the conditions are met
10490         //   1. It requests restricted network
10491         //   2. The requestor uid matches the uid with the callback
10492         //   3. The app doesn't have Carrier Privileges
10493         //   4. The app doesn't have permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS
10494         for (final NetworkRequest nr : mNetworkRequests.keySet()) {
10495             if (nr.isRequest()
10496                     && !nr.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
10497                     && nr.getRequestorUid() == uid
10498                     && getSubscriptionIdFromNetworkCaps(nr.networkCapabilities) == subId
10499                     && !hasConnectivityRestrictedNetworksPermission(uid, true)) {
10500                 declareNetworkRequestUnfulfillable(nr);
10501             }
10502         }
10503 
10504         // A NetworkAgent's allowedUids may need to be updated if the app has lost
10505         // carrier config
10506         forEachNetworkAgentInfo(nai -> {
10507             if (nai.networkCapabilities.getAllowedUidsNoCopy().contains(uid)
10508                     && getSubscriptionIdFromNetworkCaps(nai.networkCapabilities) == subId) {
10509                 final NetworkCapabilities nc = new NetworkCapabilities(nai.networkCapabilities);
10510                 NetworkAgentInfo.restrictCapabilitiesFromNetworkAgent(
10511                         nc,
10512                         uid,
10513                         false /* hasAutomotiveFeature (irrelevant) */,
10514                         mDeps,
10515                         mCarrierPrivilegeAuthenticator);
10516                 updateCapabilities(nai.getScore(), nai, nc);
10517             }
10518         });
10519     }
10520 
10521     /**
10522      * Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically:
10523      *
10524      * 1. Calls mixInCapabilities to merge the passed-in NetworkCapabilities {@code nc} with the
10525      *    capabilities we manage and store in {@code nai}, such as validated status and captive
10526      *    portal status)
10527      * 2. Takes action on the result: changes network permissions, sends CAP_CHANGED callbacks, and
10528      *    potentially triggers rematches.
10529      * 3. Directly informs other network stack components (NetworkStatsService, VPNs, etc. of the
10530      *    change.)
10531      *
10532      * @param oldScore score of the network before any of the changes that prompted us
10533      *                 to call this function.
10534      * @param nai the network having its capabilities updated.
10535      * @param nc the new network capabilities.
10536      */
10537     private void updateCapabilities(final FullScore oldScore, @NonNull final NetworkAgentInfo nai,
10538             @NonNull final NetworkCapabilities nc) {
10539         NetworkCapabilities newNc = mixInCapabilities(nai, nc);
10540         if (Objects.equals(nai.networkCapabilities, newNc)) return;
10541         final String differences = newNc.describeCapsDifferencesFrom(nai.networkCapabilities);
10542         if (null != differences) {
10543             Log.i(TAG, "Update capabilities for net " + nai.network + " : " + differences);
10544         }
10545         updateNetworkPermissions(nai, newNc);
10546         final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc);
10547 
10548         updateVpnUids(nai, prevNc, newNc);
10549         updateAllowedUids(nai, prevNc, newNc);
10550         nai.updateScoreForNetworkAgentUpdate();
10551 
10552         if (nai.getScore().equals(oldScore) && newNc.equalRequestableCapabilities(prevNc)) {
10553             // If the requestable capabilities haven't changed, and the score hasn't changed, then
10554             // the change we're processing can't affect any requests, it can only affect the listens
10555             // on this network. We might have been called by rematchNetworkAndRequests when a
10556             // network changed foreground state.
10557             processListenRequests(nai);
10558         } else {
10559             // If the requestable capabilities have changed or the score changed, we can't have been
10560             // called by rematchNetworkAndRequests, so it's safe to start a rematch.
10561             rematchAllNetworksAndRequests();
10562             notifyNetworkCallbacks(nai, CALLBACK_CAP_CHANGED);
10563         }
10564         updateNetworkInfoForRoamingAndSuspended(nai, prevNc, newNc);
10565 
10566         final boolean oldMetered = prevNc.isMetered();
10567         final boolean newMetered = newNc.isMetered();
10568         final boolean meteredChanged = oldMetered != newMetered;
10569 
10570         if (meteredChanged) {
10571             maybeNotifyNetworkBlocked(nai, oldMetered, newMetered,
10572                     mVpnBlockedUidRanges, mVpnBlockedUidRanges);
10573         }
10574 
10575         final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING)
10576                 != newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
10577 
10578         // Report changes that are interesting for network statistics tracking.
10579         if (meteredChanged || roamingChanged) {
10580             notifyIfacesChangedForNetworkStats();
10581         }
10582 
10583         // This network might have been underlying another network. Propagate its capabilities.
10584         propagateUnderlyingNetworkCapabilities(nai.network);
10585 
10586         if (meteredChanged || !newNc.equalsTransportTypes(prevNc)) {
10587             mDnsManager.updateCapabilitiesForNetwork(nai.network.getNetId(), newNc);
10588         }
10589 
10590         maybeSendProxyBroadcast(nai, prevNc, newNc);
10591     }
10592 
10593     /** Convenience method to update the capabilities for a given network. */
10594     private void updateCapabilitiesForNetwork(NetworkAgentInfo nai) {
10595         updateCapabilities(nai.getScore(), nai, nai.networkCapabilities);
10596     }
10597 
10598     private void maybeApplyMulticastRoutingConfig(@NonNull final NetworkAgentInfo nai,
10599             final LocalNetworkConfig oldConfig,
10600             final LocalNetworkConfig newConfig) {
10601         final MulticastRoutingConfig oldUpstreamConfig =
10602                 oldConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE :
10603                         oldConfig.getUpstreamMulticastRoutingConfig();
10604         final MulticastRoutingConfig oldDownstreamConfig =
10605                 oldConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE :
10606                         oldConfig.getDownstreamMulticastRoutingConfig();
10607         final MulticastRoutingConfig newUpstreamConfig =
10608                 newConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE :
10609                         newConfig.getUpstreamMulticastRoutingConfig();
10610         final MulticastRoutingConfig newDownstreamConfig =
10611                 newConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE :
10612                         newConfig.getDownstreamMulticastRoutingConfig();
10613 
10614         if (oldUpstreamConfig.equals(newUpstreamConfig) &&
10615             oldDownstreamConfig.equals(newDownstreamConfig)) {
10616             return;
10617         }
10618 
10619         final String downstreamNetworkName = nai.linkProperties.getInterfaceName();
10620         final LocalNetworkInfo lni = localNetworkInfoForNai(nai);
10621         final Network upstreamNetwork = lni.getUpstreamNetwork();
10622 
10623         if (upstreamNetwork != null) {
10624             final String upstreamNetworkName =
10625                     getLinkProperties(upstreamNetwork).getInterfaceName();
10626             applyMulticastRoutingConfig(downstreamNetworkName, upstreamNetworkName, newConfig);
10627         }
10628     }
10629 
10630     private void applyMulticastRoutingConfig(@NonNull String localNetworkInterfaceName,
10631             @NonNull String upstreamNetworkInterfaceName,
10632             @NonNull final LocalNetworkConfig config) {
10633         if (mMulticastRoutingCoordinatorService == null) {
10634             if (config.getDownstreamMulticastRoutingConfig().getForwardingMode() != FORWARD_NONE ||
10635                 config.getUpstreamMulticastRoutingConfig().getForwardingMode() != FORWARD_NONE) {
10636                 loge("Multicast routing is not supported, failed to configure " + config
10637                         + " for " + localNetworkInterfaceName + " to "
10638                         +  upstreamNetworkInterfaceName);
10639             }
10640             return;
10641         }
10642 
10643         mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig(localNetworkInterfaceName,
10644                 upstreamNetworkInterfaceName, config.getUpstreamMulticastRoutingConfig());
10645         mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig
10646                 (upstreamNetworkInterfaceName, localNetworkInterfaceName,
10647                         config.getDownstreamMulticastRoutingConfig());
10648     }
10649 
10650     private void disableMulticastRouting(@NonNull String localNetworkInterfaceName,
10651             @NonNull String upstreamNetworkInterfaceName) {
10652         if (mMulticastRoutingCoordinatorService == null) {
10653             return;
10654         }
10655 
10656         mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig(localNetworkInterfaceName,
10657                 upstreamNetworkInterfaceName, MulticastRoutingConfig.CONFIG_FORWARD_NONE);
10658         mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig
10659                 (upstreamNetworkInterfaceName, localNetworkInterfaceName,
10660                         MulticastRoutingConfig.CONFIG_FORWARD_NONE);
10661     }
10662 
10663     // oldConfig is null iff this is the original registration of the local network config
10664     private void handleUpdateLocalNetworkConfig(@NonNull final NetworkAgentInfo nai,
10665             @Nullable final LocalNetworkConfig oldConfig,
10666             @NonNull final LocalNetworkConfig newConfig) {
10667         if (!nai.isLocalNetwork()) {
10668             Log.wtf(TAG, "Ignoring update of a local network info on non-local network " + nai);
10669             return;
10670         }
10671 
10672         if (VDBG) {
10673             Log.v(TAG, "Update local network config " + nai.network.netId + " : " + newConfig);
10674         }
10675         final LocalNetworkConfig.Builder configBuilder = new LocalNetworkConfig.Builder();
10676         configBuilder.setUpstreamMulticastRoutingConfig(
10677                 newConfig.getUpstreamMulticastRoutingConfig());
10678         configBuilder.setDownstreamMulticastRoutingConfig(
10679                 newConfig.getDownstreamMulticastRoutingConfig());
10680 
10681         final NetworkRequest oldRequest =
10682                 (null == oldConfig) ? null : oldConfig.getUpstreamSelector();
10683         final NetworkCapabilities oldCaps =
10684                 (null == oldRequest) ? null : oldRequest.networkCapabilities;
10685         final NetworkRequestInfo oldNri =
10686                 null == oldRequest ? null : mNetworkRequests.get(oldRequest);
10687         final NetworkAgentInfo oldSatisfier =
10688                 null == oldNri ? null : oldNri.getSatisfier();
10689         final NetworkRequest newRequest = newConfig.getUpstreamSelector();
10690         final NetworkCapabilities newCaps =
10691                 (null == newRequest) ? null : newRequest.networkCapabilities;
10692         final boolean requestUpdated = !Objects.equals(newCaps, oldCaps);
10693         if (null != oldRequest && requestUpdated) {
10694             handleRemoveNetworkRequest(mNetworkRequests.get(oldRequest));
10695             if (null == newRequest && null != oldSatisfier) {
10696                 // If there is an old satisfier, but no new request, then remove the old upstream.
10697                 removeLocalNetworkUpstream(nai, oldSatisfier);
10698                 nai.localNetworkConfig = configBuilder.build();
10699                 // When there is a new request, the rematch sees the new request and sends the
10700                 // LOCAL_NETWORK_INFO_CHANGED callbacks accordingly.
10701                 // But here there is no new request, so the rematch won't see anything. Send
10702                 // callbacks to apps now to tell them about the loss of upstream.
10703                 notifyNetworkCallbacks(nai,
10704                         CALLBACK_LOCAL_NETWORK_INFO_CHANGED);
10705                 return;
10706             }
10707         }
10708         if (null != newRequest && requestUpdated) {
10709             // File the new request if :
10710             //  - it has changed (requestUpdated), or
10711             //  - it's the first time this local info (null == oldConfig)
10712             // is updated and the request has not been filed yet.
10713             // Requests for local info are always LISTEN_FOR_BEST, because they have at most one
10714             // upstream (the best) but never request it to be brought up.
10715             final NetworkRequest nr = new NetworkRequest(newCaps, ConnectivityManager.TYPE_NONE,
10716                     nextNetworkRequestId(), LISTEN_FOR_BEST);
10717             configBuilder.setUpstreamSelector(nr);
10718             final NetworkRequestInfo nri = new NetworkRequestInfo(
10719                     nai.creatorUid, nr, null /* messenger */, null /* binder */,
10720                     0 /* callbackFlags */, null /* attributionTag */,
10721                     DECLARED_METHODS_NONE);
10722             if (null != oldSatisfier) {
10723                 // Set the old satisfier in the new NRI so that the rematch will see any changes
10724                 nri.setSatisfier(oldSatisfier, nr);
10725             }
10726             nai.localNetworkConfig = configBuilder.build();
10727             // handleRegisterNetworkRequest causes a rematch. The rematch must happen after
10728             // nai.localNetworkConfig is set, since it will base its callbacks on the old
10729             // satisfier and the new request.
10730             handleRegisterNetworkRequest(nri);
10731         } else {
10732             configBuilder.setUpstreamSelector(oldRequest);
10733             nai.localNetworkConfig = configBuilder.build();
10734         }
10735         maybeApplyMulticastRoutingConfig(nai, oldConfig, newConfig);
10736     }
10737 
10738     /**
10739      * Returns the interface which requires VPN isolation (ingress interface filtering).
10740      *
10741      * Ingress interface filtering enforces that all apps under the given network can only receive
10742      * packets from the network's interface (and loopback). This is important for VPNs because
10743      * apps that cannot bypass a fully-routed VPN shouldn't be able to receive packets from any
10744      * non-VPN interfaces.
10745      *
10746      * As a result, this method should return Non-null interface iff
10747      *  1. the network is an app VPN (not legacy VPN)
10748      *  2. the VPN does not allow bypass
10749      *  3. the VPN is fully-routed
10750      *  4. the VPN interface is non-null
10751      *
10752      * @see INetd#firewallAddUidInterfaceRules
10753      * @see INetd#firewallRemoveUidInterfaceRules
10754      */
10755     @Nullable
10756     private String getVpnIsolationInterface(@NonNull NetworkAgentInfo nai, NetworkCapabilities nc,
10757             LinkProperties lp) {
10758         if (nc == null || lp == null) return null;
10759         if (nai.isVPN()
10760                 && !nai.networkAgentConfig.allowBypass
10761                 && nc.getOwnerUid() != Process.SYSTEM_UID
10762                 && lp.getInterfaceName() != null
10763                 && (lp.hasIpv4DefaultRoute() || lp.hasIpv4UnreachableDefaultRoute())
10764                 && (lp.hasIpv6DefaultRoute() || lp.hasIpv6UnreachableDefaultRoute())
10765                 && !lp.hasExcludeRoute()) {
10766             return lp.getInterfaceName();
10767         }
10768         return null;
10769     }
10770 
10771     /**
10772      * Returns whether we need to set interface filtering rule or not
10773      */
10774     private boolean requiresVpnAllowRule(NetworkAgentInfo nai, LinkProperties lp,
10775             String isolationIface) {
10776         // Allow rules are always needed if VPN isolation is enabled.
10777         if (isolationIface != null) return true;
10778 
10779         // On T and above, allow rules are needed for all VPNs. Allow rule with null iface is a
10780         // wildcard to allow apps to receive packets on all interfaces. This is required to accept
10781         // incoming traffic in Lockdown mode by overriding the Lockdown blocking rule.
10782         return mDeps.isAtLeastT() && nai.isVPN() && lp != null && lp.getInterfaceName() != null;
10783     }
10784 
10785     private static UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) {
10786         final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.size()];
10787         int index = 0;
10788         for (UidRange range : ranges) {
10789             stableRanges[index] = new UidRangeParcel(range.start, range.stop);
10790             index++;
10791         }
10792         return stableRanges;
10793     }
10794 
10795     private static UidRangeParcel[] intsToUidRangeStableParcels(
10796             final @NonNull ArraySet<Integer> uids) {
10797         final UidRangeParcel[] stableRanges = new UidRangeParcel[uids.size()];
10798         int index = 0;
10799         for (int uid : uids) {
10800             stableRanges[index] = new UidRangeParcel(uid, uid);
10801             index++;
10802         }
10803         return stableRanges;
10804     }
10805 
10806     private static UidRangeParcel[] toUidRangeStableParcels(UidRange[] ranges) {
10807         final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length];
10808         for (int i = 0; i < ranges.length; i++) {
10809             stableRanges[i] = new UidRangeParcel(ranges[i].start, ranges[i].stop);
10810         }
10811         return stableRanges;
10812     }
10813 
10814     private void maybeCloseSockets(NetworkAgentInfo nai, Set<UidRange> ranges, int[] exemptUids) {
10815         if (nai.isVPN() && !nai.networkAgentConfig.allowBypass) {
10816             try {
10817                 if (mDeps.isAtLeastU()) {
10818                     final Set<Integer> exemptUidSet = new ArraySet<>();
10819                     for (final int uid: exemptUids) {
10820                         exemptUidSet.add(uid);
10821                     }
10822                     mDeps.destroyLiveTcpSockets(UidRange.toIntRanges(ranges), exemptUidSet);
10823                 } else {
10824                     mNetd.socketDestroy(toUidRangeStableParcels(ranges), exemptUids);
10825                 }
10826             } catch (Exception e) {
10827                 loge("Exception in socket destroy: ", e);
10828             }
10829         }
10830     }
10831 
10832     private void modifyNetworkUidRanges(boolean add, NetworkAgentInfo nai, UidRangeParcel[] ranges,
10833             int preference) throws RemoteException {
10834         // UID ranges can be added or removed to a network that has already been destroyed (e.g., if
10835         // the network disconnects, or a a multilayer request is filed after
10836         // unregisterAfterReplacement is called).
10837         if (nai.isDestroyed()) {
10838             return;
10839         }
10840         final NativeUidRangeConfig config = new NativeUidRangeConfig(nai.network.netId,
10841                 ranges, preference);
10842         if (add) {
10843             mNetd.networkAddUidRangesParcel(config);
10844         } else {
10845             mNetd.networkRemoveUidRangesParcel(config);
10846         }
10847     }
10848 
10849     private void modifyNetworkUidRanges(boolean add, NetworkAgentInfo nai, Set<UidRange> uidRanges,
10850             int preference) throws RemoteException {
10851         modifyNetworkUidRanges(add, nai, toUidRangeStableParcels(uidRanges), preference);
10852     }
10853 
10854     private void updateVpnUidRanges(boolean add, NetworkAgentInfo nai, Set<UidRange> uidRanges) {
10855         int[] exemptUids = new int[2];
10856         // TODO: Excluding VPN_UID is necessary in order to not to kill the TCP connection used
10857         // by PPTP. Fix this by making Vpn set the owner UID to VPN_UID instead of system when
10858         // starting a legacy VPN, and remove VPN_UID here. (b/176542831)
10859         exemptUids[0] = VPN_UID;
10860         exemptUids[1] = nai.networkCapabilities.getOwnerUid();
10861 
10862         // Close sockets before modifying uid ranges so that RST packets can reach to the server.
10863         maybeCloseSockets(nai, uidRanges, exemptUids);
10864         try {
10865             modifyNetworkUidRanges(add, nai, uidRanges, PREFERENCE_ORDER_VPN);
10866         } catch (Exception e) {
10867             loge("Exception while " + (add ? "adding" : "removing") + " uid ranges " + uidRanges +
10868                     " on netId " + nai.network.netId + ". " + e);
10869         }
10870         // Close sockets that established connection while requesting netd.
10871         maybeCloseSockets(nai, uidRanges, exemptUids);
10872     }
10873 
10874     private boolean isProxySetOnAnyDefaultNetwork() {
10875         ensureRunningOnConnectivityServiceThread();
10876         for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
10877             final NetworkAgentInfo nai = nri.getSatisfier();
10878             if (nai != null && nai.linkProperties.getHttpProxy() != null) {
10879                 return true;
10880             }
10881         }
10882         return false;
10883     }
10884 
10885     private void maybeSendProxyBroadcast(NetworkAgentInfo nai, NetworkCapabilities prevNc,
10886             NetworkCapabilities newNc) {
10887         // When the apps moved from/to a VPN, a proxy broadcast is needed to inform the apps that
10888         // the proxy might be changed since the default network satisfied by the apps might also
10889         // changed.
10890         // TODO: Try to track the default network that apps use and only send a proxy broadcast when
10891         //  that happens to prevent false alarms.
10892         final Set<UidRange> prevUids = prevNc == null ? null : prevNc.getUidRanges();
10893         final Set<UidRange> newUids = newNc == null ? null : newNc.getUidRanges();
10894         if (nai.isVPN() && nai.everConnected() && !UidRange.hasSameUids(prevUids, newUids)
10895                 && (nai.linkProperties.getHttpProxy() != null || isProxySetOnAnyDefaultNetwork())) {
10896             mProxyTracker.sendProxyBroadcast();
10897         }
10898     }
10899 
10900     private void updateVpnUids(@NonNull NetworkAgentInfo nai, @Nullable NetworkCapabilities prevNc,
10901             @Nullable NetworkCapabilities newNc) {
10902         Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUidRanges();
10903         Set<UidRange> newRanges = null == newNc ? null : newNc.getUidRanges();
10904         if (null == prevRanges) prevRanges = new ArraySet<>();
10905         if (null == newRanges) newRanges = new ArraySet<>();
10906         final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges);
10907 
10908         prevRanges.removeAll(newRanges);
10909         newRanges.removeAll(prevRangesCopy);
10910 
10911         try {
10912             // When updating the VPN uid routing rules, add the new range first then remove the old
10913             // range. If old range were removed first, there would be a window between the old
10914             // range being removed and the new range being added, during which UIDs contained
10915             // in both ranges are not subject to any VPN routing rules. Adding new range before
10916             // removing old range works because, unlike the filtering rules below, it's possible to
10917             // add duplicate UID routing rules.
10918             // TODO: calculate the intersection of add & remove. Imagining that we are trying to
10919             // remove uid 3 from a set containing 1-5. Intersection of the prev and new sets is:
10920             //   [1-5] & [1-2],[4-5] == [3]
10921             // Then we can do:
10922             //   maybeCloseSockets([3])
10923             //   mNetd.networkAddUidRanges([1-2],[4-5])
10924             //   mNetd.networkRemoveUidRanges([1-5])
10925             //   maybeCloseSockets([3])
10926             // This can prevent the sockets of uid 1-2, 4-5 from being closed. It also reduce the
10927             // number of binder calls from 6 to 4.
10928             if (!newRanges.isEmpty()) {
10929                 updateVpnUidRanges(true, nai, newRanges);
10930             }
10931             if (!prevRanges.isEmpty()) {
10932                 updateVpnUidRanges(false, nai, prevRanges);
10933             }
10934             final String oldIface = getVpnIsolationInterface(nai, prevNc, nai.linkProperties);
10935             final String newIface = getVpnIsolationInterface(nai, newNc, nai.linkProperties);
10936             final boolean wasFiltering = requiresVpnAllowRule(nai, nai.linkProperties, oldIface);
10937             final boolean shouldFilter = requiresVpnAllowRule(nai, nai.linkProperties, newIface);
10938             // For VPN uid interface filtering, old ranges need to be removed before new ranges can
10939             // be added, due to the range being expanded and stored as individual UIDs. For example
10940             // the UIDs might be updated from [0, 99999] to ([0, 10012], [10014, 99999]) which means
10941             // prevRanges = [0, 99999] while newRanges = [0, 10012], [10014, 99999]. If prevRanges
10942             // were added first and then newRanges got removed later, there would be only one uid
10943             // 10013 left. A consequence of removing old ranges before adding new ranges is that
10944             // there is now a window of opportunity when the UIDs are not subject to any filtering.
10945             // Note that this is in contrast with the (more robust) update of VPN routing rules
10946             // above, where the addition of new ranges happens before the removal of old ranges.
10947             // TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range
10948             // to be removed will never overlap with the new range to be added.
10949             if (wasFiltering && !prevRanges.isEmpty()) {
10950                 mPermissionMonitor.onVpnUidRangesRemoved(oldIface, prevRanges,
10951                         prevNc.getOwnerUid());
10952             }
10953             if (shouldFilter && !newRanges.isEmpty()) {
10954                 mPermissionMonitor.onVpnUidRangesAdded(newIface, newRanges, newNc.getOwnerUid());
10955             }
10956         } catch (Exception e) {
10957             // Never crash!
10958             loge("Exception in updateVpnUids: ", e);
10959         }
10960     }
10961 
10962     private void updateAllowedUids(@NonNull NetworkAgentInfo nai,
10963             @Nullable NetworkCapabilities prevNc, @Nullable NetworkCapabilities newNc) {
10964         // In almost all cases both NC code for empty access UIDs. return as fast as possible.
10965         final boolean prevEmpty = null == prevNc || prevNc.getAllowedUidsNoCopy().isEmpty();
10966         final boolean newEmpty = null == newNc || newNc.getAllowedUidsNoCopy().isEmpty();
10967         if (prevEmpty && newEmpty) return;
10968 
10969         final ArraySet<Integer> prevUids =
10970                 null == prevNc ? new ArraySet<>() : prevNc.getAllowedUidsNoCopy();
10971         final ArraySet<Integer> newUids =
10972                 null == newNc ? new ArraySet<>() : newNc.getAllowedUidsNoCopy();
10973 
10974         if (prevUids.equals(newUids)) return;
10975 
10976         // This implementation is very simple and vastly faster for sets of Integers than
10977         // CompareOrUpdateResult, which is tuned for sets that need to be compared based on
10978         // a key computed from the value and has storage for that.
10979         final ArraySet<Integer> toRemove = new ArraySet<>(prevUids);
10980         final ArraySet<Integer> toAdd = new ArraySet<>(newUids);
10981         toRemove.removeAll(newUids);
10982         toAdd.removeAll(prevUids);
10983         try {
10984             if (!toAdd.isEmpty()) {
10985                 modifyNetworkUidRanges(true /* add */, nai, intsToUidRangeStableParcels(toAdd),
10986                         PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT);
10987             }
10988             if (!toRemove.isEmpty()) {
10989                 modifyNetworkUidRanges(false /* add */, nai, intsToUidRangeStableParcels(toRemove),
10990                         PREFERENCE_ORDER_IRRELEVANT_BECAUSE_NOT_DEFAULT);
10991             }
10992         } catch (ServiceSpecificException e) {
10993             // Has the interface disappeared since the network was built ?
10994             Log.i(TAG, "Can't set access UIDs for network " + nai.network, e);
10995         } catch (RemoteException e) {
10996             // Netd died. This usually causes a runtime restart anyway.
10997         }
10998     }
10999 
11000     public void handleUpdateLinkProperties(@NonNull NetworkAgentInfo nai,
11001             @NonNull LinkProperties newLp) {
11002         ensureRunningOnConnectivityServiceThread();
11003 
11004         if (!mNetworkAgentInfos.contains(nai)) {
11005             // Ignore updates for disconnected networks
11006             return;
11007         }
11008         if (VDBG || DDBG) {
11009             log("Update of LinkProperties for " + nai.toShortString()
11010                     + "; created=" + nai.getCreatedTime()
11011                     + "; firstConnected=" + nai.getConnectedTime());
11012         }
11013         // TODO: eliminate this defensive copy after confirming that updateLinkProperties does not
11014         // modify its oldLp parameter.
11015         updateLinkProperties(nai, newLp, new LinkProperties(nai.linkProperties));
11016     }
11017 
11018     private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent,
11019             int notificationType) {
11020         if (notificationType == CALLBACK_AVAILABLE && !nri.mPendingIntentSent) {
11021             Intent intent = new Intent();
11022             intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network);
11023             // If apps could file multi-layer requests with PendingIntents, they'd need to know
11024             // which of the layer is satisfied alongside with some ID for the request. Hence, if
11025             // such an API is ever implemented, there is no doubt the right request to send in
11026             // EXTRA_NETWORK_REQUEST is the active request, and whatever ID would be added would
11027             // need to be sent as a separate extra.
11028             final NetworkRequest req = nri.isMultilayerRequest()
11029                     ? nri.getActiveRequest()
11030                     // Non-multilayer listen requests do not have an active request
11031                     : nri.mRequests.get(0);
11032             if (req == null) {
11033                 Log.wtf(TAG, "No request in NRI " + nri);
11034             }
11035             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, req);
11036             nri.mPendingIntentSent = true;
11037             sendIntent(nri.mPendingIntent, intent);
11038         }
11039         // else not handled
11040     }
11041 
11042     /**
11043      * A small class to manage releasing a lock exactly once even if releaseLock is called
11044      * multiple times. See b/390043283
11045      * PendingIntent#send throws CanceledException in various cases. In some of them it will
11046      * still call onSendFinished, in others it won't and the client can't know. This class
11047      * keeps a ref to the wakelock that it releases exactly once, thanks to Atomics semantics.
11048      */
11049     private class WakeLockOnFinishedReceiver implements PendingIntent.OnFinished {
11050         private final AtomicReference<PowerManager.WakeLock> mLock;
11051         WakeLockOnFinishedReceiver(@NonNull final PowerManager.WakeLock lock) {
11052             mLock = new AtomicReference<>(lock);
11053             lock.acquire();
11054         }
11055 
11056         public void releaseLock() {
11057             final PowerManager.WakeLock lock = mLock.getAndSet(null);
11058             if (null != lock) lock.release();
11059         }
11060 
11061         @Override
11062         public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
11063                 String resultData, Bundle resultExtras) {
11064             if (DBG) log("Finished sending " + pendingIntent);
11065             releaseLock();
11066             releasePendingNetworkRequestWithDelay(pendingIntent);
11067         }
11068     }
11069 
11070     // TODO(b/193460475): Remove when tooling supports SystemApi to public API.
11071     @SuppressLint("NewApi")
11072     private void sendIntent(PendingIntent pendingIntent, Intent intent) {
11073         // Since the receiver will take the lock exactly once and release it exactly once, it
11074         // is safe to pass the same wakelock to all receivers and avoid creating a new lock
11075         // every time.
11076         final WakeLockOnFinishedReceiver receiver =
11077                 new WakeLockOnFinishedReceiver(mPendingIntentWakeLock);
11078         try {
11079             if (DBG) log("Sending " + pendingIntent);
11080             final BroadcastOptions options = BroadcastOptions.makeBasic();
11081             if (mDeps.isAtLeastT()) {
11082                 // Explicitly disallow the receiver from starting activities, to prevent apps from
11083                 // utilizing the PendingIntent as a backdoor to do this.
11084                 options.setPendingIntentBackgroundActivityLaunchAllowed(false);
11085             }
11086             pendingIntent.send(mContext, 0, intent, receiver, null /* Handler */,
11087                     null /* requiredPermission */,
11088                     mDeps.isAtLeastT() ? options.toBundle() : null);
11089         } catch (PendingIntent.CanceledException e) {
11090             if (DBG) log(pendingIntent + " was not sent, it had been canceled.");
11091             receiver.releaseLock();
11092             releasePendingNetworkRequest(pendingIntent);
11093         }
11094     }
11095 
11096     @Nullable
11097     private LocalNetworkInfo localNetworkInfoForNai(@NonNull final NetworkAgentInfo nai) {
11098         if (!nai.isLocalNetwork()) return null;
11099         final Network upstream;
11100         final NetworkRequest selector = nai.localNetworkConfig.getUpstreamSelector();
11101         if (null == selector) {
11102             upstream = null;
11103         } else {
11104             final NetworkRequestInfo upstreamNri = mNetworkRequests.get(selector);
11105             final NetworkAgentInfo satisfier = upstreamNri.getSatisfier();
11106             upstream = (null == satisfier) ? null : satisfier.network;
11107         }
11108         return new LocalNetworkInfo.Builder().setUpstreamNetwork(upstream).build();
11109     }
11110 
11111     private Bundle makeCommonBundleForCallback(@NonNull final NetworkRequestInfo nri,
11112             @Nullable Network network) {
11113         final Bundle bundle = new Bundle();
11114         // TODO b/177608132: make sure callbacks are indexed by NRIs and not NetworkRequest objects.
11115         // TODO: check if defensive copies of data is needed.
11116         putParcelable(bundle, nri.getNetworkRequestForCallback());
11117         if (network != null) {
11118             putParcelable(bundle, network);
11119         }
11120         return bundle;
11121     }
11122 
11123     // networkAgent is only allowed to be null if notificationType is CALLBACK_UNAVAIL or
11124     // CALLBACK_RESERVED. This is because, per definition, no network is available for UNAVAIL, and
11125     // RESERVED callbacks happen when a NetworkOffer is created in response to a reservation.
11126     private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri,
11127             @Nullable final NetworkAgentInfo networkAgent, final int notificationType,
11128             final int arg1) {
11129         if (nri.mMessenger == null) {
11130             // Default request has no msgr. Also prevents callbacks from being invoked for
11131             // NetworkRequestInfos registered with ConnectivityDiagnostics requests. Those callbacks
11132             // are Type.LISTEN, but should not have NetworkCallbacks invoked.
11133             return;
11134         }
11135         // Even if a callback ends up not being sent, it may affect other callbacks in the queue, so
11136         // queue callbacks before checking the declared methods flags.
11137         // UNAVAIL and RESERVED callbacks are safe not to be queued, because RESERVED must always be
11138         // the first callback. In addition, RESERVED cannot be sent more than once and is only
11139         // cancelled by UNVAIL.
11140         // TODO: evaluate whether it makes sense to queue RESERVED callbacks.
11141         if (networkAgent != null && nri.maybeQueueCallback(networkAgent, notificationType)) {
11142             return;
11143         }
11144         if (!nri.isCallbackOverridden(notificationType)) {
11145             // No need to send the notification as the recipient method is not overridden
11146             return;
11147         }
11148         // networkAgent is only null for UNAVAIL and RESERVED.
11149         final Network bundleNetwork = (networkAgent != null) ? networkAgent.network : null;
11150         final Bundle bundle = makeCommonBundleForCallback(nri, bundleNetwork);
11151         final boolean includeLocationSensitiveInfo =
11152                 (nri.mCallbackFlags & NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) != 0;
11153         final NetworkRequest nrForCallback = nri.getNetworkRequestForCallback();
11154         switch (notificationType) {
11155             case CALLBACK_RESERVED: {
11156                 final NetworkCapabilities nc =
11157                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
11158                                 networkCapabilitiesRestrictedForCallerPermissions(
11159                                         nri.getReservedCapabilities(), nri.mPid, nri.mUid),
11160                                 includeLocationSensitiveInfo, nri.mPid, nri.mUid,
11161                                 nrForCallback.getRequestorPackageName(),
11162                                 nri.mCallingAttributionTag);
11163                 putParcelable(bundle, nc);
11164                 break;
11165             }
11166             case CALLBACK_AVAILABLE: {
11167                 final NetworkCapabilities nc =
11168                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
11169                                 networkCapabilitiesRestrictedForCallerPermissions(
11170                                         networkAgent.networkCapabilities, nri.mPid, nri.mUid),
11171                                 includeLocationSensitiveInfo, nri.mPid, nri.mUid,
11172                                 nrForCallback.getRequestorPackageName(),
11173                                 nri.mCallingAttributionTag);
11174                 putParcelable(bundle, nc);
11175                 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
11176                         networkAgent.linkProperties, nri.mPid, nri.mUid));
11177                 // The local network info is often null, so can't use the static putParcelable
11178                 // method here.
11179                 bundle.putParcelable(LocalNetworkInfo.class.getSimpleName(),
11180                         localNetworkInfoForNai(networkAgent));
11181                 break;
11182             }
11183             case CALLBACK_CAP_CHANGED: {
11184                 // networkAgent can't be null as it has been accessed a few lines above.
11185                 final NetworkCapabilities netCap =
11186                         networkCapabilitiesRestrictedForCallerPermissions(
11187                                 networkAgent.networkCapabilities, nri.mPid, nri.mUid);
11188                 putParcelable(
11189                         bundle,
11190                         createWithLocationInfoSanitizedIfNecessaryWhenParceled(
11191                                 netCap, includeLocationSensitiveInfo, nri.mPid, nri.mUid,
11192                                 nrForCallback.getRequestorPackageName(),
11193                                 nri.mCallingAttributionTag));
11194                 break;
11195             }
11196             case CALLBACK_IP_CHANGED: {
11197                 putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
11198                         networkAgent.linkProperties, nri.mPid, nri.mUid));
11199                 break;
11200             }
11201             case CALLBACK_BLK_CHANGED: {
11202                 maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1);
11203                 break;
11204             }
11205             case CALLBACK_LOCAL_NETWORK_INFO_CHANGED: {
11206                 if (!networkAgent.isLocalNetwork()) {
11207                     Log.wtf(TAG, "Callback for local info for a non-local network");
11208                     return;
11209                 }
11210                 putParcelable(bundle, localNetworkInfoForNai(networkAgent));
11211                 break;
11212             }
11213         }
11214         callCallbackForRequest(nri, notificationType, bundle, arg1);
11215     }
11216 
11217     private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri, int notificationType,
11218             Bundle bundle, int arg1) {
11219         Message msg = Message.obtain();
11220         msg.arg1 = arg1;
11221         msg.what = notificationType;
11222         msg.setData(bundle);
11223         try {
11224             if (VDBG) {
11225                 String notification = ConnectivityManager.getCallbackName(notificationType);
11226                 log("sending notification " + notification + " for "
11227                         + nri.getNetworkRequestForCallback());
11228             }
11229             nri.mMessenger.send(msg);
11230         } catch (RemoteException e) {
11231             // may occur naturally in the race of binder death.
11232             loge("RemoteException caught trying to send a callback msg for "
11233                     + nri.getNetworkRequestForCallback());
11234         }
11235     }
11236 
11237     private static <T extends Parcelable> void putParcelable(Bundle bundle, T t) {
11238         bundle.putParcelable(t.getClass().getSimpleName(), t);
11239     }
11240 
11241     /**
11242      * Returns whether reassigning a request from an NAI to another can be done gracefully.
11243      *
11244      * When a request should be assigned to a new network, it is normally lingered to give
11245      * time for apps to gracefully migrate their connections. When both networks are on the same
11246      * radio, but that radio can't do time-sharing efficiently, this may end up being
11247      * counter-productive because any traffic on the old network may drastically reduce the
11248      * performance of the new network.
11249      * The stack supports a configuration to let modem vendors state that their radio can't
11250      * do time-sharing efficiently. If this configuration is set, the stack assumes moving
11251      * from one cell network to another can't be done gracefully.
11252      *
11253      * @param oldNai the old network serving the request
11254      * @param newNai the new network serving the request
11255      * @return whether the switch can be graceful
11256      */
11257     private boolean canSupportGracefulNetworkSwitch(@NonNull final NetworkAgentInfo oldSatisfier,
11258             @NonNull final NetworkAgentInfo newSatisfier) {
11259         if (mCellularRadioTimesharingCapable) return true;
11260         return !oldSatisfier.networkCapabilities.hasSingleTransport(TRANSPORT_CELLULAR)
11261                 || !newSatisfier.networkCapabilities.hasSingleTransport(TRANSPORT_CELLULAR)
11262                 || !newSatisfier.getScore().hasPolicy(POLICY_TRANSPORT_PRIMARY);
11263     }
11264 
11265     private void teardownUnneededNetwork(NetworkAgentInfo nai) {
11266         if (nai.numRequestNetworkRequests() != 0) {
11267             for (int i = 0; i < nai.numNetworkRequests(); i++) {
11268                 NetworkRequest nr = nai.requestAt(i);
11269                 // Ignore listening and track default requests.
11270                 if (!nr.isRequest()) continue;
11271                 loge("Dead network still had at least " + nr);
11272                 break;
11273             }
11274         }
11275         if (mQueueNetworkAgentEventsInSystemServer) {
11276             disconnectAndDestroyNetwork(nai);
11277         } else {
11278             nai.disconnect();
11279         }
11280     }
11281 
11282     private void handleLingerComplete(NetworkAgentInfo oldNetwork) {
11283         if (oldNetwork == null) {
11284             loge("Unknown NetworkAgentInfo in handleLingerComplete");
11285             return;
11286         }
11287         if (DBG) log("handleLingerComplete for " + oldNetwork.toShortString());
11288 
11289         // If we get here it means that the last linger timeout for this network expired. So there
11290         // must be no other active linger timers, and we must stop lingering.
11291         oldNetwork.clearInactivityState();
11292 
11293         if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) {
11294             // Tear the network down.
11295             teardownUnneededNetwork(oldNetwork);
11296         } else {
11297             // Put the network in the background if it doesn't satisfy any foreground request.
11298             updateCapabilitiesForNetwork(oldNetwork);
11299         }
11300     }
11301 
11302     private void processDefaultNetworkChanges(@NonNull final NetworkReassignment changes) {
11303         boolean isDefaultChanged = false;
11304         for (final NetworkRequestInfo defaultRequestInfo : mDefaultNetworkRequests) {
11305             final NetworkReassignment.RequestReassignment reassignment =
11306                     changes.getReassignment(defaultRequestInfo);
11307             if (null == reassignment) {
11308                 continue;
11309             }
11310             // reassignment only contains those instances where the satisfying network changed.
11311             isDefaultChanged = true;
11312             // Notify system services of the new default.
11313             makeDefault(defaultRequestInfo, reassignment.mOldNetwork, reassignment.mNewNetwork);
11314         }
11315 
11316         if (isDefaultChanged) {
11317             // Hold a wakelock for a short time to help apps in migrating to a new default.
11318             scheduleReleaseNetworkTransitionWakelock();
11319         }
11320     }
11321 
11322     private void resetHttpProxyForNonDefaultNetwork(NetworkAgentInfo oldDefaultNetwork) {
11323         if (null == oldDefaultNetwork) return;
11324         // The network stopped being the default. If it was using a PAC proxy, then the
11325         // proxy needs to be reset, otherwise HTTP requests on this network may be sent
11326         // to the local proxy server, which would forward them over the newly default network.
11327         final ProxyInfo proxyInfo = oldDefaultNetwork.linkProperties.getHttpProxy();
11328         if (null == proxyInfo || !proxyInfo.isPacProxy()) return;
11329         oldDefaultNetwork.linkProperties.setHttpProxy(new ProxyInfo(proxyInfo.getPacFileUrl()));
11330         notifyNetworkCallbacks(oldDefaultNetwork, CALLBACK_IP_CHANGED);
11331     }
11332 
11333     private void makeDefault(@NonNull final NetworkRequestInfo nri,
11334             @Nullable final NetworkAgentInfo oldDefaultNetwork,
11335             @Nullable final NetworkAgentInfo newDefaultNetwork) {
11336         if (DBG) {
11337             log("Switching to new default network for: " + nri + " using " + newDefaultNetwork);
11338         }
11339 
11340         // Fix up the NetworkCapabilities of any networks that have this network as underlying.
11341         if (newDefaultNetwork != null) {
11342             propagateUnderlyingNetworkCapabilities(newDefaultNetwork.network);
11343         }
11344 
11345         // Set an app level managed default and return since further processing only applies to the
11346         // default network.
11347         if (mDefaultRequest != nri) {
11348             makeDefaultForApps(nri, oldDefaultNetwork, newDefaultNetwork);
11349             return;
11350         }
11351 
11352         makeDefaultNetwork(newDefaultNetwork);
11353 
11354         if (oldDefaultNetwork != null) {
11355             mLingerMonitor.noteLingerDefaultNetwork(oldDefaultNetwork, newDefaultNetwork);
11356         }
11357         mNetworkActivityTracker.updateDefaultNetwork(newDefaultNetwork, oldDefaultNetwork);
11358         maybeDestroyPendingSockets(newDefaultNetwork, oldDefaultNetwork);
11359         mProxyTracker.setDefaultProxy(null != newDefaultNetwork
11360                 ? newDefaultNetwork.linkProperties.getHttpProxy() : null);
11361         resetHttpProxyForNonDefaultNetwork(oldDefaultNetwork);
11362         updateTcpBufferSizes(null != newDefaultNetwork
11363                 ? newDefaultNetwork.linkProperties.getTcpBufferSizes() : null);
11364         notifyIfacesChangedForNetworkStats();
11365     }
11366 
11367     private void makeDefaultForApps(@NonNull final NetworkRequestInfo nri,
11368             @Nullable final NetworkAgentInfo oldDefaultNetwork,
11369             @Nullable final NetworkAgentInfo newDefaultNetwork) {
11370         try {
11371             if (VDBG) {
11372                 log("Setting default network for " + nri
11373                         + " using UIDs " + nri.getUids()
11374                         + " with old network " + (oldDefaultNetwork != null
11375                         ? oldDefaultNetwork.network().getNetId() : "null")
11376                         + " and new network " + (newDefaultNetwork != null
11377                         ? newDefaultNetwork.network().getNetId() : "null"));
11378             }
11379             if (nri.getUids().isEmpty()) {
11380                 throw new IllegalStateException("makeDefaultForApps called without specifying"
11381                         + " any applications to set as the default." + nri);
11382             }
11383             if (null != newDefaultNetwork) {
11384                 modifyNetworkUidRanges(true /* add */, newDefaultNetwork, nri.getUids(),
11385                         nri.getPreferenceOrderForNetd());
11386             }
11387             if (null != oldDefaultNetwork) {
11388                 modifyNetworkUidRanges(false /* add */, oldDefaultNetwork, nri.getUids(),
11389                         nri.getPreferenceOrderForNetd());
11390             }
11391         } catch (RemoteException | ServiceSpecificException e) {
11392             loge("Exception setting app default network", e);
11393         }
11394     }
11395 
11396     /**
11397      * Collect restricted uid ranges for the given network and UserHandle, these uids
11398      * are not restricted for matched enterprise networks but being restricted for non-matched
11399      * enterprise networks and non-enterprise networks.
11400      */
11401     @NonNull
11402     private ArraySet<UidRange> getRestrictedUidRangesForEnterpriseBlocking(
11403             @NonNull NetworkAgentInfo nai, @NonNull UserHandle user) {
11404         final ArraySet<UidRange> restrictedUidRanges = new ArraySet<>();
11405         for (final ProfileNetworkPreferenceInfo pref : mProfileNetworkPreferences) {
11406             if (!pref.user.equals(user) || !pref.blockingNonEnterprise) continue;
11407 
11408             if (nai.networkCapabilities.hasCapability(NET_CAPABILITY_ENTERPRISE)) {
11409                 // The NC is built from a `ProfileNetworkPreference` which has only one
11410                 // enterprise ID, so it's guaranteed to have exactly one.
11411                 final int prefId = pref.capabilities.getEnterpriseIds()[0];
11412                 if (nai.networkCapabilities.hasEnterpriseId(prefId)) {
11413                     continue;
11414                 }
11415             }
11416 
11417             if (UidRangeUtils.doesRangeSetOverlap(restrictedUidRanges,
11418                     pref.capabilities.getUidRanges())) {
11419                 throw new IllegalArgumentException(
11420                         "Overlapping uid range in preference: " + pref);
11421             }
11422             restrictedUidRanges.addAll(pref.capabilities.getUidRanges());
11423         }
11424         return restrictedUidRanges;
11425     }
11426 
11427     private void updateProfileAllowedNetworks() {
11428         // Netd command is not implemented before U.
11429         if (!mDeps.isAtLeastU()) return;
11430 
11431         ensureRunningOnConnectivityServiceThread();
11432         final ArrayList<NativeUidRangeConfig> configs = new ArrayList<>();
11433         final List<UserHandle> users = mContext.getSystemService(UserManager.class)
11434                         .getUserHandles(true /* excludeDying */);
11435         if (users.isEmpty()) {
11436             throw new IllegalStateException("No user is available");
11437         }
11438 
11439         forEachNetworkAgentInfo(nai -> {
11440             ArraySet<UidRange> allowedUidRanges = new ArraySet<>();
11441             for (final UserHandle user : users) {
11442                 final ArraySet<UidRange> restrictedUidRanges =
11443                         getRestrictedUidRangesForEnterpriseBlocking(nai, user);
11444                 allowedUidRanges.addAll(UidRangeUtils.removeRangeSetFromUidRange(
11445                         UidRange.createForUser(user), restrictedUidRanges));
11446             }
11447 
11448             final UidRangeParcel[] rangesParcel = toUidRangeStableParcels(allowedUidRanges);
11449             configs.add(new NativeUidRangeConfig(
11450                     nai.network.netId, rangesParcel, 0 /* subPriority */));
11451         });
11452 
11453         // The netd API replaces the previous configs with the current configs.
11454         // Thus, for network disconnection or preference removal, no need to
11455         // unset previous config. Instead, collecting all currently needed
11456         // configs and issue to netd.
11457         try {
11458             mNetd.setNetworkAllowlist(configs.toArray(new NativeUidRangeConfig[0]));
11459         } catch (ServiceSpecificException e) {
11460             // Has the interface disappeared since the network was built?
11461             Log.wtf(TAG, "Unexpected ServiceSpecificException", e);
11462         } catch (RemoteException e) {
11463             // Netd died. This will cause a runtime restart anyway.
11464             Log.wtf(TAG, "Unexpected RemoteException", e);
11465         }
11466     }
11467 
11468     private void makeDefaultNetwork(@Nullable final NetworkAgentInfo newDefaultNetwork) {
11469         try {
11470             if (null != newDefaultNetwork) {
11471                 mNetd.networkSetDefault(newDefaultNetwork.network.getNetId());
11472             } else {
11473                 mNetd.networkClearDefault();
11474             }
11475         } catch (RemoteException | ServiceSpecificException e) {
11476             loge("Exception setting default network :" + e);
11477         }
11478     }
11479 
11480     private void processListenRequests(@NonNull final NetworkAgentInfo nai) {
11481         // For consistency with previous behaviour, send onLost callbacks before onAvailable.
11482         processNewlyLostListenRequests(nai);
11483         notifyNetworkCallbacks(nai, CALLBACK_CAP_CHANGED);
11484         processNewlySatisfiedListenRequests(nai);
11485     }
11486 
11487     private void processNewlyLostListenRequests(@NonNull final NetworkAgentInfo nai) {
11488         for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
11489             if (nri.isMultilayerRequest()) {
11490                 continue;
11491             }
11492             final NetworkRequest nr = nri.mRequests.get(0);
11493             if (!nr.isListen()) continue;
11494             if (nai.isSatisfyingRequest(nr.requestId) && !nai.satisfies(nr)) {
11495                 nai.removeRequest(nr.requestId);
11496                 callCallbackForRequest(nri, nai, CALLBACK_LOST, 0);
11497             }
11498         }
11499     }
11500 
11501     private void processNewlySatisfiedListenRequests(@NonNull final NetworkAgentInfo nai) {
11502         for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
11503             if (nri.isMultilayerRequest()) {
11504                 continue;
11505             }
11506             final NetworkRequest nr = nri.mRequests.get(0);
11507             if (!nr.isListen()) continue;
11508             if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) {
11509                 nai.addRequest(nr);
11510                 notifyNetworkAvailable(nai, nri);
11511             }
11512         }
11513     }
11514 
11515     // An accumulator class to gather the list of changes that result from a rematch.
11516     private static class NetworkReassignment {
11517         static class RequestReassignment {
11518             @NonNull public final NetworkRequestInfo mNetworkRequestInfo;
11519             @Nullable public final NetworkRequest mOldNetworkRequest;
11520             @Nullable public final NetworkRequest mNewNetworkRequest;
11521             @Nullable public final NetworkAgentInfo mOldNetwork;
11522             @Nullable public final NetworkAgentInfo mNewNetwork;
11523             RequestReassignment(@NonNull final NetworkRequestInfo networkRequestInfo,
11524                     @Nullable final NetworkRequest oldNetworkRequest,
11525                     @Nullable final NetworkRequest newNetworkRequest,
11526                     @Nullable final NetworkAgentInfo oldNetwork,
11527                     @Nullable final NetworkAgentInfo newNetwork) {
11528                 mNetworkRequestInfo = networkRequestInfo;
11529                 mOldNetworkRequest = oldNetworkRequest;
11530                 mNewNetworkRequest = newNetworkRequest;
11531                 mOldNetwork = oldNetwork;
11532                 mNewNetwork = newNetwork;
11533             }
11534 
11535             public String toString() {
11536                 final NetworkRequest requestToShow = null != mNewNetworkRequest
11537                         ? mNewNetworkRequest : mNetworkRequestInfo.mRequests.get(0);
11538                 return requestToShow.requestId + " : "
11539                         + (null != mOldNetwork ? mOldNetwork.network.getNetId() : "null")
11540                         + " → " + (null != mNewNetwork ? mNewNetwork.network.getNetId() : "null");
11541             }
11542         }
11543 
11544         @NonNull private final ArrayList<RequestReassignment> mReassignments = new ArrayList<>();
11545 
11546         @NonNull Iterable<RequestReassignment> getRequestReassignments() {
11547             return mReassignments;
11548         }
11549 
11550         void addRequestReassignment(@NonNull final RequestReassignment reassignment) {
11551             if (Build.isDebuggable()) {
11552                 // The code is never supposed to add two reassignments of the same request. Make
11553                 // sure this stays true, but without imposing this expensive check on all
11554                 // reassignments on all user devices.
11555                 for (final RequestReassignment existing : mReassignments) {
11556                     if (existing.mNetworkRequestInfo.equals(reassignment.mNetworkRequestInfo)) {
11557                         throw new IllegalStateException("Trying to reassign ["
11558                                 + reassignment + "] but already have ["
11559                                 + existing + "]");
11560                     }
11561                 }
11562             }
11563             mReassignments.add(reassignment);
11564         }
11565 
11566         // Will return null if this reassignment does not change the network assigned to
11567         // the passed request.
11568         @Nullable
11569         private RequestReassignment getReassignment(@NonNull final NetworkRequestInfo nri) {
11570             for (final RequestReassignment event : getRequestReassignments()) {
11571                 if (nri == event.mNetworkRequestInfo) return event;
11572             }
11573             return null;
11574         }
11575 
11576         public String toString() {
11577             final StringJoiner sj = new StringJoiner(", " /* delimiter */,
11578                     "NetReassign [" /* prefix */, "]" /* suffix */);
11579             if (mReassignments.isEmpty()) return sj.add("no changes").toString();
11580             for (final RequestReassignment rr : getRequestReassignments()) {
11581                 sj.add(rr.toString());
11582             }
11583             return sj.toString();
11584         }
11585 
11586         public String debugString() {
11587             final StringBuilder sb = new StringBuilder();
11588             sb.append("NetworkReassignment :");
11589             if (mReassignments.isEmpty()) return sb.append(" no changes").toString();
11590             for (final RequestReassignment rr : getRequestReassignments()) {
11591                 sb.append("\n  ").append(rr);
11592             }
11593             return sb.append("\n").toString();
11594         }
11595     }
11596 
11597     private void updateSatisfiersForRematchRequest(@NonNull final NetworkRequestInfo nri,
11598             @Nullable final NetworkRequest previousRequest,
11599             @Nullable final NetworkRequest newRequest,
11600             @Nullable final NetworkAgentInfo previousSatisfier,
11601             @Nullable final NetworkAgentInfo newSatisfier,
11602             final long now) {
11603         if (null != newSatisfier && mNoServiceNetwork != newSatisfier) {
11604             if (VDBG) log("rematch for " + newSatisfier.toShortString());
11605             if (null != previousRequest && null != previousSatisfier) {
11606                 if (VDBG || DDBG) {
11607                     log("   accepting network in place of " + previousSatisfier.toShortString()
11608                             + " for " + newRequest);
11609                 }
11610                 previousSatisfier.removeRequest(previousRequest.requestId);
11611                 if (canSupportGracefulNetworkSwitch(previousSatisfier, newSatisfier)
11612                         && !previousSatisfier.isDestroyed()) {
11613                     // If this network switch can't be supported gracefully, the request is not
11614                     // lingered. This allows letting go of the network sooner to reclaim some
11615                     // performance on the new network, since the radio can't do both at the same
11616                     // time while preserving good performance.
11617                     //
11618                     // Also don't linger the request if the old network has been destroyed.
11619                     // A destroyed network does not provide actual network connectivity, so
11620                     // lingering it is not useful. In particular this ensures that a destroyed
11621                     // network is outscored by its replacement,
11622                     // then it is torn down immediately instead of being lingered, and any apps that
11623                     // were using it immediately get onLost and can connect using the new network.
11624                     previousSatisfier.lingerRequest(previousRequest.requestId, now);
11625                 }
11626             } else {
11627                 if (VDBG || DDBG) log("   accepting network in place of null for " + newRequest);
11628             }
11629 
11630             // To prevent constantly CPU wake up for nascent timer, if a network comes up
11631             // and immediately satisfies a request then remove the timer. This will happen for
11632             // all networks except in the case of an underlying network for a VCN.
11633             if (newSatisfier.isNascent()) {
11634                 newSatisfier.unlingerRequest(NetworkRequest.REQUEST_ID_NONE);
11635                 newSatisfier.unsetInactive();
11636             }
11637 
11638             // if newSatisfier is not null, then newRequest may not be null.
11639             newSatisfier.unlingerRequest(newRequest.requestId);
11640             if (!newSatisfier.addRequest(newRequest)) {
11641                 Log.wtf(TAG, "BUG: " + newSatisfier.toShortString() + " already has "
11642                         + newRequest);
11643             }
11644         } else if (null != previousRequest && null != previousSatisfier) {
11645             if (DBG) {
11646                 log("Network " + previousSatisfier.toShortString() + " stopped satisfying"
11647                         + " request " + previousRequest.requestId);
11648             }
11649             previousSatisfier.removeRequest(previousRequest.requestId);
11650         }
11651         nri.setSatisfier(newSatisfier, newRequest);
11652     }
11653 
11654     /**
11655      * This function is triggered when something can affect what network should satisfy what
11656      * request, and it computes the network reassignment from the passed collection of requests to
11657      * network match to the one that the system should now have. That data is encoded in an
11658      * object that is a list of changes, each of them having an NRI, and old satisfier, and a new
11659      * satisfier.
11660      *
11661      * After the reassignment is computed, it is applied to the state objects.
11662      *
11663      * @param networkRequests the nri objects to evaluate for possible network reassignment
11664      * @return NetworkReassignment listing of proposed network assignment changes
11665      */
11666     @NonNull
11667     private NetworkReassignment computeNetworkReassignment(
11668             @NonNull final Collection<NetworkRequestInfo> networkRequests) {
11669         final NetworkReassignment changes = new NetworkReassignment();
11670 
11671         // Gather the list of all relevant agents.
11672         final ArrayList<NetworkAgentInfo> nais = new ArrayList<>();
11673         forEachNetworkAgentInfo(nai -> nais.add(nai));
11674 
11675         for (final NetworkRequestInfo nri : networkRequests) {
11676             // Non-multilayer listen requests can be ignored.
11677             if (!nri.isMultilayerRequest() && nri.mRequests.get(0).isListen()) {
11678                 continue;
11679             }
11680             NetworkAgentInfo bestNetwork = null;
11681             NetworkRequest bestRequest = null;
11682             for (final NetworkRequest req : nri.mRequests) {
11683                 bestNetwork = mNetworkRanker.getBestNetwork(req, nais, nri.getSatisfier());
11684                 // Stop evaluating as the highest possible priority request is satisfied.
11685                 if (null != bestNetwork) {
11686                     bestRequest = req;
11687                     break;
11688                 }
11689             }
11690             if (null == bestNetwork && isDefaultBlocked(nri)) {
11691                 // Remove default networking if disallowed for managed default requests.
11692                 bestNetwork = mNoServiceNetwork;
11693             }
11694             if (nri.getSatisfier() != bestNetwork) {
11695                 // bestNetwork may be null if no network can satisfy this request.
11696                 changes.addRequestReassignment(new NetworkReassignment.RequestReassignment(
11697                         nri, nri.mActiveRequest, bestRequest, nri.getSatisfier(), bestNetwork));
11698             }
11699         }
11700         return changes;
11701     }
11702 
11703     private Set<NetworkRequestInfo> getNrisFromGlobalRequests() {
11704         return new HashSet<>(mNetworkRequests.values());
11705     }
11706 
11707     /**
11708      * Attempt to rematch all Networks with all NetworkRequests.  This may result in Networks
11709      * being disconnected.
11710      */
11711     private void rematchAllNetworksAndRequests() {
11712         rematchNetworksAndRequests(getNrisFromGlobalRequests());
11713     }
11714 
11715     /**
11716      * Attempt to rematch all Networks with given NetworkRequests.  This may result in Networks
11717      * being disconnected.
11718      */
11719     private void rematchNetworksAndRequests(
11720             @NonNull final Set<NetworkRequestInfo> networkRequests) {
11721         ensureRunningOnConnectivityServiceThread();
11722         // TODO: This may be slow, and should be optimized.
11723         final long start = SystemClock.elapsedRealtime();
11724         final NetworkReassignment changes = computeNetworkReassignment(networkRequests);
11725         final long computed = SystemClock.elapsedRealtime();
11726         applyNetworkReassignment(changes, start);
11727         final long applied = SystemClock.elapsedRealtime();
11728         issueNetworkNeeds();
11729         final long end = SystemClock.elapsedRealtime();
11730         if (VDBG || DDBG) {
11731             log(String.format("Rematched networks [computed %dms] [applied %dms] [issued %d]",
11732                     computed - start, applied - computed, end - applied));
11733             log(changes.debugString());
11734         } else if (DBG) {
11735             // Shorter form, only one line of log
11736             log(String.format("%s [c %d] [a %d] [i %d]", changes.toString(),
11737                     computed - start, applied - computed, end - applied));
11738         }
11739     }
11740 
11741     private boolean hasSameInterfaceName(@Nullable final NetworkAgentInfo nai1,
11742             @Nullable final NetworkAgentInfo nai2) {
11743         if (null == nai1) return null == nai2;
11744         if (null == nai2) return false;
11745         return nai1.linkProperties.getInterfaceName()
11746                 .equals(nai2.linkProperties.getInterfaceName());
11747     }
11748 
11749     private void applyNetworkReassignment(@NonNull final NetworkReassignment changes,
11750             final long now) {
11751         final Collection<NetworkAgentInfo> nais = mNetworkAgentInfos;
11752 
11753         // Since most of the time there are only 0 or 1 background networks, it would probably
11754         // be more efficient to just use an ArrayList here. TODO : measure performance
11755         final ArraySet<NetworkAgentInfo> oldBgNetworks = new ArraySet<>();
11756         for (final NetworkAgentInfo nai : nais) {
11757             if (nai.isBackgroundNetwork()) oldBgNetworks.add(nai);
11758         }
11759 
11760         // First, update the lists of satisfied requests in the network agents. This is necessary
11761         // because some code later depends on this state to be correct, most prominently computing
11762         // the linger status.
11763         for (final NetworkReassignment.RequestReassignment event :
11764                 changes.getRequestReassignments()) {
11765             updateSatisfiersForRematchRequest(event.mNetworkRequestInfo,
11766                     event.mOldNetworkRequest, event.mNewNetworkRequest,
11767                     event.mOldNetwork, event.mNewNetwork,
11768                     now);
11769         }
11770 
11771         // Process default network changes if applicable.
11772         processDefaultNetworkChanges(changes);
11773 
11774         // Update forwarding rules for the upstreams of local networks. Do this before sending
11775         // onAvailable so that by the time onAvailable is sent the forwarding rules are set up.
11776         // Don't send CALLBACK_LOCAL_NETWORK_INFO_CHANGED yet though : they should be sent after
11777         // onAvailable so clients know what network the change is about. Store such changes in
11778         // an array that's only allocated if necessary (because it's almost never necessary).
11779         final ArrayList<NetworkAgentInfo> localInfoChangedAgents = new ArrayList<>();
11780         forEachNetworkAgentInfo(nai -> {
11781             if (!nai.isLocalNetwork()) return; // return@forEach
11782             final NetworkRequest nr = nai.localNetworkConfig.getUpstreamSelector();
11783             if (null == nr) return; // return@forEach, no upstream for this local network
11784             final NetworkRequestInfo nri = mNetworkRequests.get(nr);
11785             final NetworkReassignment.RequestReassignment change = changes.getReassignment(nri);
11786             if (null == change) return; // return@forEach, no change in upstreams for this network
11787             final String fromIface = nai.linkProperties.getInterfaceName();
11788             if (!hasSameInterfaceName(change.mOldNetwork, change.mNewNetwork)
11789                     || change.mOldNetwork.isDestroyed()) {
11790                 // There can be a change with the same interface name if the new network is the
11791                 // replacement for the old network that was unregisteredAfterReplacement.
11792                 try {
11793                     if (null != change.mOldNetwork) {
11794                         mRoutingCoordinatorService.removeInterfaceForward(fromIface,
11795                                 change.mOldNetwork.linkProperties.getInterfaceName());
11796                         disableMulticastRouting(fromIface,
11797                                 change.mOldNetwork.linkProperties.getInterfaceName());
11798                     }
11799                     // If the new upstream is already destroyed, there is no point in setting up
11800                     // a forward (in fact, it might forward to the interface for some new network !)
11801                     // Later when the upstream disconnects CS will try to remove the forward, which
11802                     // is ignored with a benign log by RoutingCoordinatorService.
11803                     if (null != change.mNewNetwork && !change.mNewNetwork.isDestroyed()) {
11804                         mRoutingCoordinatorService.addInterfaceForward(fromIface,
11805                                 change.mNewNetwork.linkProperties.getInterfaceName());
11806                         applyMulticastRoutingConfig(fromIface,
11807                                 change.mNewNetwork.linkProperties.getInterfaceName(),
11808                                 nai.localNetworkConfig);
11809                     }
11810                 } catch (final RemoteException e) {
11811                     loge("Can't update forwarding rules", e);
11812                 }
11813             }
11814             localInfoChangedAgents.add(nai);
11815         });
11816 
11817         // Notify requested networks are available after the default net is switched, but
11818         // before LegacyTypeTracker sends legacy broadcasts
11819         for (final NetworkReassignment.RequestReassignment event :
11820                 changes.getRequestReassignments()) {
11821             if (null != event.mNewNetwork) {
11822                 notifyNetworkAvailable(event.mNewNetwork, event.mNetworkRequestInfo);
11823             } else {
11824                 callCallbackForRequest(event.mNetworkRequestInfo, event.mOldNetwork,
11825                         CALLBACK_LOST, 0);
11826             }
11827         }
11828 
11829         // Update the inactivity state before processing listen callbacks, because the background
11830         // computation depends on whether the network is inactive. Don't send the LOSING callbacks
11831         // just yet though, because they have to be sent after the listens are processed to keep
11832         // backward compatibility.
11833         final ArrayList<NetworkAgentInfo> inactiveNetworks = new ArrayList<>();
11834         for (final NetworkAgentInfo nai : nais) {
11835             // Rematching may have altered the inactivity state of some networks, so update all
11836             // inactivity timers. updateInactivityState reads the state from the network agent
11837             // and does nothing if the state has not changed : the source of truth is controlled
11838             // with NetworkAgentInfo#lingerRequest and NetworkAgentInfo#unlingerRequest, which
11839             // have been called while rematching the individual networks above.
11840             if (updateInactivityState(nai, now)) {
11841                 inactiveNetworks.add(nai);
11842             }
11843         }
11844 
11845         for (final NetworkAgentInfo nai : nais) {
11846             final boolean oldBackground = oldBgNetworks.contains(nai);
11847             // Process listen requests and update capabilities if the background state has
11848             // changed for this network. For consistency with previous behavior, send onLost
11849             // callbacks before onAvailable.
11850             processNewlyLostListenRequests(nai);
11851             if (oldBackground != nai.isBackgroundNetwork()) {
11852                 applyBackgroundChangeForRematch(nai);
11853             }
11854             processNewlySatisfiedListenRequests(nai);
11855         }
11856 
11857         for (final NetworkAgentInfo nai : inactiveNetworks) {
11858             // For nascent networks, if connecting with no foreground request, skip broadcasting
11859             // LOSING for backward compatibility. This is typical when mobile data connected while
11860             // wifi connected with mobile data always-on enabled.
11861             if (nai.isNascent()) continue;
11862             notifyNetworkLosing(nai, now);
11863         }
11864 
11865         // Send LOCAL_NETWORK_INFO_CHANGED callbacks now that onAvailable and onLost have been sent.
11866         for (final NetworkAgentInfo nai : localInfoChangedAgents) {
11867           notifyNetworkCallbacks(nai, CALLBACK_LOCAL_NETWORK_INFO_CHANGED);
11868         }
11869 
11870         updateLegacyTypeTrackerAndVpnLockdownForRematch(changes, nais);
11871 
11872         // Tear down all unneeded networks.
11873         forEachNetworkAgentInfo(nai -> {
11874             if (unneeded(nai, UnneededFor.TEARDOWN)) {
11875                 if (nai.getInactivityExpiry() > 0) {
11876                     // This network has active linger timers and no requests, but is not
11877                     // lingering. Linger it.
11878                     //
11879                     // One way (the only way?) this can happen if this network is unvalidated
11880                     // and became unneeded due to another network improving its score to the
11881                     // point where this network will no longer be able to satisfy any requests
11882                     // even if it validates.
11883                     if (updateInactivityState(nai, now)) {
11884                         notifyNetworkLosing(nai, now);
11885                     }
11886                 } else {
11887                     if (DBG) log("Reaping " + nai.toShortString());
11888                     teardownUnneededNetwork(nai);
11889                 }
11890             }
11891         });
11892     }
11893 
11894     /**
11895      * Apply a change in background state resulting from rematching networks with requests.
11896      *
11897      * During rematch, a network may change background states by starting to satisfy or stopping
11898      * to satisfy a foreground request. Listens don't count for this. When a network changes
11899      * background states, its capabilities need to be updated and callbacks fired for the
11900      * capability change.
11901      *
11902      * @param nai The network that changed background states
11903      */
11904     private void applyBackgroundChangeForRematch(@NonNull final NetworkAgentInfo nai) {
11905         final NetworkCapabilities newNc = mixInCapabilities(nai, nai.networkCapabilities);
11906         if (Objects.equals(nai.networkCapabilities, newNc)) return;
11907         updateNetworkPermissions(nai, newNc);
11908         nai.getAndSetNetworkCapabilities(newNc);
11909         notifyNetworkCallbacks(nai, CALLBACK_CAP_CHANGED);
11910     }
11911 
11912     private void updateLegacyTypeTrackerAndVpnLockdownForRematch(
11913             @NonNull final NetworkReassignment changes,
11914             @NonNull final Collection<NetworkAgentInfo> nais) {
11915         final NetworkReassignment.RequestReassignment reassignmentOfDefault =
11916                 changes.getReassignment(mDefaultRequest);
11917         final NetworkAgentInfo oldDefaultNetwork =
11918                 null != reassignmentOfDefault ? reassignmentOfDefault.mOldNetwork : null;
11919         final NetworkAgentInfo newDefaultNetwork =
11920                 null != reassignmentOfDefault ? reassignmentOfDefault.mNewNetwork : null;
11921 
11922         if (oldDefaultNetwork != newDefaultNetwork) {
11923             // Maintain the illusion : since the legacy API only understands one network at a time,
11924             // if the default network changed, apps should see a disconnected broadcast for the
11925             // old default network before they see a connected broadcast for the new one.
11926             if (oldDefaultNetwork != null) {
11927                 mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
11928                         oldDefaultNetwork, true);
11929             }
11930             if (newDefaultNetwork != null) {
11931                 // The new default network can be newly null if and only if the old default
11932                 // network doesn't satisfy the default request any more because it lost a
11933                 // capability.
11934                 mDefaultInetConditionPublished = newDefaultNetwork.isValidated() ? 100 : 0;
11935                 mLegacyTypeTracker.add(
11936                         newDefaultNetwork.networkInfo.getType(), newDefaultNetwork);
11937             }
11938         }
11939 
11940         // Now that all the callbacks have been sent, send the legacy network broadcasts
11941         // as needed. This is necessary so that legacy requests correctly bind dns
11942         // requests to this network. The legacy users are listening for this broadcast
11943         // and will generally do a dns request so they can ensureRouteToHost and if
11944         // they do that before the callbacks happen they'll use the default network.
11945         //
11946         // TODO: Is there still a race here? The legacy broadcast will be sent after sending
11947         // callbacks, but if apps can receive the broadcast before the callback, they still might
11948         // have an inconsistent view of networking.
11949         //
11950         // This *does* introduce a race where if the user uses the new api
11951         // (notification callbacks) and then uses the old api (getNetworkInfo(type))
11952         // they may get old info. Reverse this after the old startUsing api is removed.
11953         // This is on top of the multiple intent sequencing referenced in the todo above.
11954         for (NetworkAgentInfo nai : nais) {
11955             if (nai.everConnected()) {
11956                 addNetworkToLegacyTypeTracker(nai);
11957             }
11958         }
11959     }
11960 
11961     private void issueNetworkNeeds() {
11962         ensureRunningOnConnectivityServiceThread();
11963         for (final NetworkOfferInfo noi : mNetworkOffers) {
11964             issueNetworkNeeds(noi);
11965         }
11966     }
11967 
11968     private void issueNetworkNeeds(@NonNull final NetworkOfferInfo noi) {
11969         ensureRunningOnConnectivityServiceThread();
11970         for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
11971             informOffer(nri, noi.offer, mNetworkRanker);
11972         }
11973     }
11974 
11975     /**
11976      * Inform a NetworkOffer about any new situation of a request.
11977      *
11978      * This function handles updates to offers. A number of events may happen that require
11979      * updating the registrant for this offer about the situation :
11980      * • The offer itself was updated. This may lead the offer to no longer being able
11981      *     to satisfy a request or beat a satisfier (and therefore be no longer needed),
11982      *     or conversely being strengthened enough to beat the satisfier (and therefore
11983      *     start being needed)
11984      * • The network satisfying a request changed (including cases where the request
11985      *     starts or stops being satisfied). The new network may be a stronger or weaker
11986      *     match than the old one, possibly affecting whether the offer is needed.
11987      * • The network satisfying a request updated their score. This may lead the offer
11988      *     to no longer be able to beat it if the current satisfier got better, or
11989      *     conversely start being a good choice if the current satisfier got weaker.
11990      *
11991      * @param nri The request
11992      * @param offer The offer. This may be an updated offer.
11993      */
11994     private static void informOffer(@NonNull NetworkRequestInfo nri,
11995             @NonNull final NetworkOffer offer, @NonNull final NetworkRanker networkRanker) {
11996         final NetworkRequest activeRequest = nri.isBeingSatisfied() ? nri.getActiveRequest() : null;
11997         final NetworkAgentInfo satisfier = null != activeRequest ? nri.getSatisfier() : null;
11998 
11999         // Multi-layer requests have a currently active request, the one being satisfied.
12000         // Since the system will try to bring up a better network than is currently satisfying
12001         // the request, NetworkProviders need to be told the offers matching the requests *above*
12002         // the currently satisfied one are needed, that the ones *below* the satisfied one are
12003         // not needed, and the offer is needed for the active request iff the offer can beat
12004         // the satisfier.
12005         // For non-multilayer requests, the logic above gracefully degenerates to only the
12006         // last case.
12007         // To achieve this, the loop below will proceed in three steps. In a first phase, inform
12008         // providers that the offer is needed for this request, until the active request is found.
12009         // In a second phase, deal with the currently active request. In a third phase, inform
12010         // the providers that offer is unneeded for the remaining requests.
12011 
12012         // First phase : inform providers of all requests above the active request.
12013         int i;
12014         for (i = 0; nri.mRequests.size() > i; ++i) {
12015             final NetworkRequest request = nri.mRequests.get(i);
12016             if (activeRequest == request) break; // Found the active request : go to phase 2
12017             if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers
12018             // Since this request is higher-priority than the one currently satisfied, if the
12019             // offer can satisfy it, the provider should try and bring up the network for sure ;
12020             // no need to even ask the ranker – an offer that can satisfy is always better than
12021             // no network. Hence tell the provider so unless it already knew.
12022             if (request.canBeSatisfiedBy(offer.caps) && !offer.neededFor(request)) {
12023                 offer.onNetworkNeeded(request);
12024             }
12025         }
12026 
12027         // Second phase : deal with the active request (if any)
12028         if (null != activeRequest && activeRequest.isRequest()) {
12029             final boolean oldNeeded = offer.neededFor(activeRequest);
12030             // If an offer can satisfy the request, it is considered needed if it is currently
12031             // served by this provider or if this offer can beat the current satisfier.
12032             final boolean currentlyServing = satisfier != null
12033                     && satisfier.factorySerialNumber == offer.providerId
12034                     && activeRequest.canBeSatisfiedBy(offer.caps);
12035             final boolean newNeeded = currentlyServing
12036                     || networkRanker.mightBeat(activeRequest, satisfier, offer);
12037             if (newNeeded != oldNeeded) {
12038                 if (newNeeded) {
12039                     offer.onNetworkNeeded(activeRequest);
12040                 } else {
12041                     // The offer used to be able to beat the satisfier. Now it can't.
12042                     offer.onNetworkUnneeded(activeRequest);
12043                 }
12044             }
12045         }
12046 
12047         // Third phase : inform the providers that the offer isn't needed for any request
12048         // below the active one.
12049         for (++i /* skip the active request */; nri.mRequests.size() > i; ++i) {
12050             final NetworkRequest request = nri.mRequests.get(i);
12051             if (!request.isRequest()) continue; // Listens/track defaults are never sent to offers
12052             // Since this request is lower-priority than the one currently satisfied, if the
12053             // offer can satisfy it, the provider should not try and bring up the network.
12054             // Hence tell the provider so unless it already knew.
12055             if (offer.neededFor(request)) {
12056                 offer.onNetworkUnneeded(request);
12057             }
12058         }
12059     }
12060 
12061     private void addNetworkToLegacyTypeTracker(@NonNull final NetworkAgentInfo nai) {
12062         for (int i = 0; i < nai.numNetworkRequests(); i++) {
12063             NetworkRequest nr = nai.requestAt(i);
12064             if (nr.legacyType != TYPE_NONE && nr.isRequest()) {
12065                 // legacy type tracker filters out repeat adds
12066                 mLegacyTypeTracker.add(nr.legacyType, nai);
12067             }
12068         }
12069 
12070         // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above,
12071         // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest
12072         // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the
12073         // newNetwork to the tracker explicitly (it's a no-op if it has already been added).
12074         if (nai.isVPN()) {
12075             mLegacyTypeTracker.add(TYPE_VPN, nai);
12076         }
12077     }
12078 
12079     private void updateInetCondition(NetworkAgentInfo nai) {
12080         // Don't bother updating until we've graduated to validated at least once.
12081         if (!nai.everValidated()) return;
12082         // For now only update icons for the default connection.
12083         // TODO: Update WiFi and cellular icons separately. b/17237507
12084         if (!isDefaultNetwork(nai)) return;
12085 
12086         int newInetCondition = nai.isValidated() ? 100 : 0;
12087         // Don't repeat publish.
12088         if (newInetCondition == mDefaultInetConditionPublished) return;
12089 
12090         mDefaultInetConditionPublished = newInetCondition;
12091         sendInetConditionBroadcast(nai.networkInfo);
12092     }
12093 
12094     @NonNull
12095     private NetworkInfo mixInInfo(@NonNull final NetworkAgentInfo nai, @NonNull NetworkInfo info) {
12096         final NetworkInfo newInfo = new NetworkInfo(info);
12097         // The suspended and roaming bits are managed in NetworkCapabilities.
12098         final boolean suspended =
12099                 !nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_SUSPENDED);
12100         if (suspended && info.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
12101             // Only override the state with SUSPENDED if the network is currently in CONNECTED
12102             // state. This is because the network could have been suspended before connecting,
12103             // or it could be disconnecting while being suspended, and in both these cases
12104             // the state should not be overridden. Note that the only detailed state that
12105             // maps to State.CONNECTED is DetailedState.CONNECTED, so there is also no need to
12106             // worry about multiple different substates of CONNECTED.
12107             newInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, info.getReason(),
12108                     info.getExtraInfo());
12109         } else if (!suspended && info.getDetailedState() == NetworkInfo.DetailedState.SUSPENDED) {
12110             // SUSPENDED state is currently only overridden from CONNECTED state. In the case the
12111             // network agent is created, then goes to suspended, then goes out of suspended without
12112             // ever setting connected. Check if network agent is ever connected to update the state.
12113             newInfo.setDetailedState(nai.everConnected()
12114                     ? NetworkInfo.DetailedState.CONNECTED
12115                     : NetworkInfo.DetailedState.CONNECTING,
12116                     info.getReason(),
12117                     info.getExtraInfo());
12118         }
12119         newInfo.setRoaming(!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING));
12120         return newInfo;
12121     }
12122 
12123     private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo info) {
12124         final NetworkInfo newInfo = mixInInfo(networkAgent, info);
12125 
12126         final NetworkInfo.State state = newInfo.getState();
12127         NetworkInfo oldInfo = null;
12128         synchronized (networkAgent) {
12129             oldInfo = networkAgent.networkInfo;
12130             networkAgent.networkInfo = newInfo;
12131         }
12132 
12133         if (DBG) {
12134             log(networkAgent.toShortString() + " EVENT_NETWORK_INFO_CHANGED, going from "
12135                     + oldInfo.getState() + " to " + state);
12136         }
12137 
12138         if (shouldCreateNativeNetwork(networkAgent, state)) {
12139             // A network that has just connected has zero requests and is thus a foreground network.
12140             networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND);
12141 
12142             if (!createNativeNetwork(networkAgent)) return;
12143 
12144             networkAgent.setCreated();
12145 
12146             // If the network is created immediately on register, then apply the LinkProperties now.
12147             // Otherwise, this is done further down when the network goes into connected state.
12148             // Applying the LinkProperties means that the network is ready to carry traffic -
12149             // interfaces and routing rules have been added, DNS servers programmed, etc.
12150             // For VPNs, this must be done before the capabilities are updated, because as soon as
12151             // that happens, UIDs are routed to the network.
12152             if (shouldCreateNetworksImmediately(networkAgent.getCapsNoCopy())) {
12153                 applyInitialLinkProperties(networkAgent);
12154             }
12155 
12156             // TODO: should this move earlier? It doesn't seem to have anything to do with whether
12157             // a network is created or not.
12158             if (networkAgent.propagateUnderlyingCapabilities()) {
12159                 // Initialize the network's capabilities to their starting values according to the
12160                 // underlying networks. This ensures that the capabilities are correct before
12161                 // anything happens to the network.
12162                 updateCapabilitiesForNetwork(networkAgent);
12163             }
12164             networkAgent.onNetworkCreated();
12165             updateAllowedUids(networkAgent, null, networkAgent.networkCapabilities);
12166             updateProfileAllowedNetworks();
12167         }
12168 
12169         if (!networkAgent.everConnected() && state == NetworkInfo.State.CONNECTED) {
12170             networkAgent.setConnected();
12171 
12172             // NetworkCapabilities need to be set before sending the private DNS config to
12173             // NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required.
12174             networkAgent.getAndSetNetworkCapabilities(networkAgent.networkCapabilities);
12175 
12176             handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig());
12177             if (!shouldCreateNetworksImmediately(networkAgent.getCapsNoCopy())) {
12178                 applyInitialLinkProperties(networkAgent);
12179             } else {
12180                 // The network was created when the agent registered, and the LinkProperties are
12181                 // already up-to-date. However, updateLinkProperties also makes some changes only
12182                 // when the network connects. Apply those changes here. On T and below these are
12183                 // handled by the applyInitialLinkProperties call just above.
12184                 // TODO: stop relying on updateLinkProperties(..., null) to do this.
12185                 // If something depends on both LinkProperties and connected state, it should be in
12186                 // this method as well.
12187                 networkAgent.clatd.update();
12188                 updateProxy(networkAgent.linkProperties, null);
12189             }
12190 
12191             // If a rate limit has been configured and is applicable to this network (network
12192             // provides internet connectivity), apply it. The tc police filter cannot be attached
12193             // before the clsact qdisc is added which happens as part of updateLinkProperties ->
12194             // updateInterfaces -> RoutingCoordinatorManager#addInterfaceToNetwork
12195             // Note: in case of a system server crash, the NetworkController constructor in netd
12196             // (called when netd starts up) deletes the clsact qdisc of all interfaces.
12197             if (canNetworkBeRateLimited(networkAgent) && mIngressRateLimit >= 0) {
12198                 mDeps.enableIngressRateLimit(networkAgent.linkProperties.getInterfaceName(),
12199                         mIngressRateLimit);
12200             }
12201 
12202             // Until parceled LinkProperties are sent directly to NetworkMonitor, the connect
12203             // command must be sent after updating LinkProperties to maximize chances of
12204             // NetworkMonitor seeing the correct LinkProperties when starting.
12205             // TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call.
12206             if (networkAgent.networkAgentConfig.acceptPartialConnectivity) {
12207                 networkAgent.networkMonitor().setAcceptPartialConnectivity();
12208             }
12209             final NetworkMonitorParameters params = new NetworkMonitorParameters();
12210             params.networkAgentConfig = networkAgent.networkAgentConfig;
12211             params.networkCapabilities = networkAgent.networkCapabilities;
12212             params.linkProperties = new LinkProperties(networkAgent.linkProperties,
12213                     true /* parcelSensitiveFields */);
12214             // isAtLeastT() is conservative here, as recent versions of NetworkStack support the
12215             // newer callback even before T. However getInterfaceVersion is a synchronized binder
12216             // call that would cause a Log.wtf to be emitted from the system_server process, and
12217             // in the absence of a satisfactory, scalable solution which follows an easy/standard
12218             // process to check the interface version, just use an SDK check. NetworkStack will
12219             // always be new enough when running on T+.
12220             if (mDeps.isAtLeastT()) {
12221                 networkAgent.networkMonitor().notifyNetworkConnected(params);
12222             } else {
12223                 networkAgent.networkMonitor().notifyNetworkConnected(params.linkProperties,
12224                         params.networkCapabilities);
12225             }
12226             final long evaluationDelay;
12227             if (!networkAgent.networkCapabilities.hasSingleTransport(TRANSPORT_WIFI)) {
12228                 // If the network is anything other than pure wifi, use the default timeout.
12229                 evaluationDelay = DEFAULT_EVALUATION_TIMEOUT_MS;
12230             } else if (networkAgent.networkAgentConfig.isExplicitlySelected()) {
12231                 // If the network is explicitly selected, use the default timeout because it's
12232                 // shorter and the user is likely staring at the screen expecting it to validate
12233                 // right away.
12234                 evaluationDelay = DEFAULT_EVALUATION_TIMEOUT_MS;
12235             } else if (avoidBadWifi() || !activelyPreferBadWifi()) {
12236                 // If avoiding bad wifi, or if not avoiding but also not preferring bad wifi
12237                 evaluationDelay = DEFAULT_EVALUATION_TIMEOUT_MS;
12238             } else {
12239                 // It's wifi, automatically connected, and bad wifi is preferred : use the
12240                 // longer timeout to avoid the device switching to captive portals with bad
12241                 // signal or very slow response.
12242                 evaluationDelay = ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS;
12243             }
12244             scheduleEvaluationTimeout(networkAgent.network, evaluationDelay);
12245 
12246             // Whether a particular NetworkRequest listen should cause signal strength thresholds to
12247             // be communicated to a particular NetworkAgent depends only on the network's immutable,
12248             // capabilities, so it only needs to be done once on initial connect, not every time the
12249             // network's capabilities change. Note that we do this before rematching the network,
12250             // so we could decide to tear it down immediately afterwards. That's fine though - on
12251             // disconnection NetworkAgents should stop any signal strength monitoring they have been
12252             // doing.
12253             updateSignalStrengthThresholds(networkAgent, "CONNECT", null);
12254 
12255             // Before first rematching networks, put an inactivity timer without any request, this
12256             // allows {@code updateInactivityState} to update the state accordingly and prevent
12257             // tearing down for any {@code unneeded} evaluation in this period.
12258             // Note that the timer will not be rescheduled since the expiry time is
12259             // fixed after connection regardless of the network satisfying other requests or not.
12260             // But it will be removed as soon as the network satisfies a request for the first time.
12261             networkAgent.lingerRequest(NetworkRequest.REQUEST_ID_NONE,
12262                     SystemClock.elapsedRealtime(), mNascentDelayMs);
12263             networkAgent.setInactive();
12264 
12265             if (mTrackMultiNetworkActivities) {
12266                 // Start tracking activity of this network.
12267                 // This must be called before rematchAllNetworksAndRequests since the network
12268                 // should be tracked when the network becomes the default network.
12269                 // This method does not trigger any callbacks or broadcasts. Callbacks or broadcasts
12270                 // can be triggered later if this network becomes the default network.
12271                 mNetworkActivityTracker.setupDataActivityTracking(networkAgent);
12272             }
12273 
12274             // Consider network even though it is not yet validated.
12275             rematchAllNetworksAndRequests();
12276 
12277             // This has to happen after matching the requests, because callbacks are just requests.
12278             notifyNetworkCallbacks(networkAgent, CALLBACK_PRECHECK);
12279         } else if (state == NetworkInfo.State.DISCONNECTED) {
12280             if (!mQueueNetworkAgentEventsInSystemServer) {
12281                 networkAgent.disconnect();
12282             }
12283             if (networkAgent.isVPN()) {
12284                 updateVpnUids(networkAgent, networkAgent.networkCapabilities, null);
12285             }
12286             disconnectAndDestroyNetwork(networkAgent);
12287             if (networkAgent.isVPN()) {
12288                 // As the active or bound network changes for apps, broadcast the default proxy, as
12289                 // apps may need to update their proxy data. This is called after disconnecting from
12290                 // VPN to make sure we do not broadcast the old proxy data.
12291                 // TODO(b/122649188): send the broadcast only to VPN users.
12292                 mProxyTracker.sendProxyBroadcast();
12293             }
12294         } else if (networkAgent.isCreated() && (oldInfo.getState() == NetworkInfo.State.SUSPENDED
12295                 || state == NetworkInfo.State.SUSPENDED)) {
12296             mLegacyTypeTracker.update(networkAgent);
12297         }
12298     }
12299 
12300     private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final NetworkScore score) {
12301         if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score);
12302         nai.setScore(score);
12303         rematchAllNetworksAndRequests();
12304     }
12305 
12306     // Notify only this one new request of the current state. Transfer all the
12307     // current state by calling NetworkCapabilities and LinkProperties callbacks
12308     // so that callers can be guaranteed to have as close to atomicity in state
12309     // transfer as can be supported by this current API.
12310     protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) {
12311         mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri);
12312         if (nri.mPendingIntent != null) {
12313             sendPendingIntentForRequest(nri, nai, CALLBACK_AVAILABLE);
12314             // Attempt no subsequent state pushes where intents are involved.
12315             return;
12316         }
12317 
12318         callCallbackForRequest(nri, nai, CALLBACK_AVAILABLE, getBlockedState(nai, nri.mAsUid));
12319     }
12320 
12321     // Notify the requests on this NAI that the network is now lingered.
12322     private void notifyNetworkLosing(@NonNull final NetworkAgentInfo nai, final long now) {
12323         final int lingerTime = (int) (nai.getInactivityExpiry() - now);
12324         notifyNetworkCallbacks(nai, CALLBACK_LOSING, lingerTime);
12325     }
12326 
12327     private int getPermissionBlockedState(final int uid, final int reasons) {
12328         // Before V, the blocked reasons come from NPMS, and that code already behaves as if the
12329         // change was disabled: apps without the internet permission will never be told they are
12330         // blocked.
12331         if (!mDeps.isAtLeastV()) return reasons;
12332 
12333         if (hasInternetPermission(uid)) return reasons;
12334 
12335         return mDeps.isChangeEnabled(NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION, uid)
12336                 ? reasons | BLOCKED_REASON_NETWORK_RESTRICTED
12337                 : BLOCKED_REASON_NONE;
12338     }
12339 
12340     private int getBlockedState(int uid, int reasons, boolean metered, boolean vpnBlocked) {
12341         reasons = getPermissionBlockedState(uid, reasons);
12342         if (!metered) reasons &= ~BLOCKED_METERED_REASON_MASK;
12343         return vpnBlocked
12344                 ? reasons | BLOCKED_REASON_LOCKDOWN_VPN
12345                 : reasons & ~BLOCKED_REASON_LOCKDOWN_VPN;
12346     }
12347 
12348     private int getBlockedState(@NonNull NetworkAgentInfo nai, int uid) {
12349         final boolean metered = nai.networkCapabilities.isMetered();
12350         final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges);
12351         final int blockedReasons = mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE);
12352         return getBlockedState(uid, blockedReasons, metered, vpnBlocked);
12353     }
12354 
12355     private void setUidBlockedReasons(int uid, @BlockedReason int blockedReasons) {
12356         if (blockedReasons == BLOCKED_REASON_NONE) {
12357             mUidBlockedReasons.delete(uid);
12358         } else {
12359             mUidBlockedReasons.put(uid, blockedReasons);
12360         }
12361     }
12362 
12363     /**
12364      * Notify of the blocked state apps with a registered callback matching a given NAI.
12365      *
12366      * Unlike other callbacks, blocked status is different between each individual uid. So for
12367      * any given nai, all requests need to be considered according to the uid who filed it.
12368      *
12369      * @param nai The target NetworkAgentInfo.
12370      * @param oldMetered True if the previous network capabilities were metered.
12371      * @param newMetered True if the current network capabilities are metered.
12372      * @param oldBlockedUidRanges list of UID ranges previously blocked by lockdown VPN.
12373      * @param newBlockedUidRanges list of UID ranges blocked by lockdown VPN.
12374      */
12375     private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
12376             boolean newMetered, List<UidRange> oldBlockedUidRanges,
12377             List<UidRange> newBlockedUidRanges) {
12378 
12379         for (int i = 0; i < nai.numNetworkRequests(); i++) {
12380             NetworkRequest nr = nai.requestAt(i);
12381             NetworkRequestInfo nri = mNetworkRequests.get(nr);
12382 
12383             final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
12384             final boolean oldVpnBlocked = isUidBlockedByVpn(nri.mAsUid, oldBlockedUidRanges);
12385             final boolean newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges)
12386                     ? isUidBlockedByVpn(nri.mAsUid, newBlockedUidRanges)
12387                     : oldVpnBlocked;
12388 
12389             final int oldBlockedState = getBlockedState(
12390                     nri.mAsUid, blockedReasons, oldMetered, oldVpnBlocked);
12391             final int newBlockedState = getBlockedState(
12392                     nri.mAsUid, blockedReasons, newMetered, newVpnBlocked);
12393             if (oldBlockedState != newBlockedState) {
12394                 callCallbackForRequest(nri, nai, CALLBACK_BLK_CHANGED,
12395                         newBlockedState);
12396             }
12397         }
12398     }
12399 
12400     /**
12401      * Notify apps with a given UID of the new blocked state according to new uid state.
12402      * @param uid The uid for which the rules changed.
12403      * @param blockedReasons The reasons for why an uid is blocked.
12404      */
12405     private void maybeNotifyNetworkBlockedForNewState(int uid, @BlockedReason int blockedReasons) {
12406         forEachNetworkAgentInfo(nai -> {
12407             final boolean metered = nai.networkCapabilities.isMetered();
12408             final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges);
12409 
12410             final int oldBlockedState = getBlockedState(
12411                     uid, mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered, vpnBlocked);
12412             final int newBlockedState =
12413                     getBlockedState(uid, blockedReasons, metered, vpnBlocked);
12414             if (oldBlockedState == newBlockedState) return; // return@forEach
12415             for (int i = 0; i < nai.numNetworkRequests(); i++) {
12416                 NetworkRequest nr = nai.requestAt(i);
12417                 NetworkRequestInfo nri = mNetworkRequests.get(nr);
12418                 if (nri != null && nri.mAsUid == uid) {
12419                     callCallbackForRequest(nri, nai, CALLBACK_BLK_CHANGED,
12420                             newBlockedState);
12421                 }
12422             }
12423         });
12424     }
12425 
12426     @VisibleForTesting
12427     protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
12428         // The NetworkInfo we actually send out has no bearing on the real
12429         // state of affairs. For example, if the default connection is mobile,
12430         // and a request for HIPRI has just gone away, we need to pretend that
12431         // HIPRI has just disconnected. So we need to set the type to HIPRI and
12432         // the state to DISCONNECTED, even though the network is of type MOBILE
12433         // and is still connected.
12434         NetworkInfo info = new NetworkInfo(nai.networkInfo);
12435         info.setType(type);
12436         filterForLegacyLockdown(info);
12437         if (state != DetailedState.DISCONNECTED) {
12438             info.setDetailedState(state, null, info.getExtraInfo());
12439             sendConnectedBroadcast(info);
12440         } else {
12441             info.setDetailedState(state, info.getReason(), info.getExtraInfo());
12442             Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
12443             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
12444             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
12445             if (info.isFailover()) {
12446                 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
12447                 nai.networkInfo.setFailover(false);
12448             }
12449             if (info.getReason() != null) {
12450                 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
12451             }
12452             if (info.getExtraInfo() != null) {
12453                 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
12454             }
12455             NetworkAgentInfo newDefaultAgent = null;
12456             if (nai.isSatisfyingRequest(mDefaultRequest.mRequests.get(0).requestId)) {
12457                 newDefaultAgent = mDefaultRequest.getSatisfier();
12458                 if (newDefaultAgent != null) {
12459                     intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
12460                             newDefaultAgent.networkInfo);
12461                 } else {
12462                     intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
12463                 }
12464             }
12465             intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
12466                     mDefaultInetConditionPublished);
12467             sendStickyBroadcast(intent);
12468             if (newDefaultAgent != null) {
12469                 sendConnectedBroadcast(newDefaultAgent.networkInfo);
12470             }
12471         }
12472     }
12473 
12474     protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) {
12475         if (VDBG || DDBG) {
12476             String notification = ConnectivityManager.getCallbackName(notifyType);
12477             log("notifyType " + notification + " for " + networkAgent.toShortString());
12478         }
12479         for (int i = 0; i < networkAgent.numNetworkRequests(); i++) {
12480             NetworkRequest nr = networkAgent.requestAt(i);
12481             NetworkRequestInfo nri = mNetworkRequests.get(nr);
12482             if (VDBG) log(" sending notification for " + nr);
12483             if (nri.mPendingIntent == null) {
12484                 callCallbackForRequest(nri, networkAgent, notifyType, arg1);
12485             } else {
12486                 sendPendingIntentForRequest(nri, networkAgent, notifyType);
12487             }
12488         }
12489     }
12490 
12491     protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
12492         notifyNetworkCallbacks(networkAgent, notifyType, 0);
12493     }
12494 
12495     /**
12496      * Returns the list of all interfaces that could be used by network traffic that does not
12497      * explicitly specify a network. This includes the default network, but also all VPNs that are
12498      * currently connected.
12499      *
12500      * Must be called on the handler thread.
12501      */
12502     @NonNull
12503     private ArrayList<Network> getDefaultNetworks() {
12504         ensureRunningOnConnectivityServiceThread();
12505         final ArrayList<Network> defaultNetworks = new ArrayList<>();
12506         final Set<Integer> activeNetIds = new ArraySet<>();
12507         for (final NetworkRequestInfo nri : mDefaultNetworkRequests) {
12508             if (nri.isBeingSatisfied()) {
12509                 activeNetIds.add(nri.getSatisfier().network().netId);
12510             }
12511         }
12512         forEachNetworkAgentInfo(nai -> {
12513             if (activeNetIds.contains(nai.network().netId) || nai.isVPN()) {
12514                 defaultNetworks.add(nai.network);
12515             }
12516         });
12517         return defaultNetworks;
12518     }
12519 
12520     /**
12521      * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the
12522      * active iface's tracked properties has changed.
12523      */
12524     private void notifyIfacesChangedForNetworkStats() {
12525         ensureRunningOnConnectivityServiceThread();
12526         String activeIface = null;
12527         LinkProperties activeLinkProperties = getActiveLinkProperties();
12528         if (activeLinkProperties != null) {
12529             activeIface = activeLinkProperties.getInterfaceName();
12530         }
12531 
12532         final UnderlyingNetworkInfo[] underlyingNetworkInfos = getAllVpnInfo();
12533         try {
12534             final ArrayList<NetworkStateSnapshot> snapshots = new ArrayList<>();
12535             snapshots.addAll(getAllNetworkStateSnapshots());
12536             mStatsManager.notifyNetworkStatus(getDefaultNetworks(),
12537                     snapshots, activeIface, Arrays.asList(underlyingNetworkInfos));
12538         } catch (Exception ignored) {
12539         }
12540     }
12541 
12542     @Override
12543     public String getCaptivePortalServerUrl() {
12544         enforceNetworkStackOrSettingsPermission();
12545         String settingUrl = mResources.get().getString(
12546                 R.string.config_networkCaptivePortalServerUrl);
12547 
12548         if (!TextUtils.isEmpty(settingUrl)) {
12549             return settingUrl;
12550         }
12551 
12552         settingUrl = Settings.Global.getString(mContext.getContentResolver(),
12553                 ConnectivitySettingsManager.CAPTIVE_PORTAL_HTTP_URL);
12554         if (!TextUtils.isEmpty(settingUrl)) {
12555             return settingUrl;
12556         }
12557 
12558         return DEFAULT_CAPTIVE_PORTAL_HTTP_URL;
12559     }
12560 
12561     @Override
12562     public void startNattKeepalive(Network network, int intervalSeconds,
12563             ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr) {
12564         enforceKeepalivePermission();
12565         mKeepaliveTracker.startNattKeepalive(
12566                 getNetworkAgentInfoForNetwork(network), null /* fd */,
12567                 intervalSeconds, cb, srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT,
12568                 // Keep behavior of the deprecated method as it is. Set automaticOnOffKeepalives to
12569                 // false and set the underpinned network to null because there is no way and no
12570                 // plan to configure automaticOnOffKeepalives or underpinnedNetwork in this
12571                 // deprecated method.
12572                 false /* automaticOnOffKeepalives */, null /* underpinnedNetwork */);
12573     }
12574 
12575     @Override
12576     public void startNattKeepaliveWithFd(Network network, ParcelFileDescriptor pfd, int resourceId,
12577             int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr,
12578             String dstAddr, boolean automaticOnOffKeepalives, Network underpinnedNetwork) {
12579         try {
12580             final FileDescriptor fd = pfd.getFileDescriptor();
12581             mKeepaliveTracker.startNattKeepalive(
12582                     getNetworkAgentInfoForNetwork(network), fd, resourceId,
12583                     intervalSeconds, cb, srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT,
12584                     automaticOnOffKeepalives, underpinnedNetwork);
12585         } finally {
12586             // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
12587             // startNattKeepalive calls Os.dup(fd) before returning, so we can close immediately.
12588             if (pfd != null && Binder.getCallingPid() != Process.myPid()) {
12589                 IoUtils.closeQuietly(pfd);
12590             }
12591         }
12592     }
12593 
12594     @Override
12595     public void startTcpKeepalive(Network network, ParcelFileDescriptor pfd, int intervalSeconds,
12596             ISocketKeepaliveCallback cb) {
12597         try {
12598             enforceKeepalivePermission();
12599             final FileDescriptor fd = pfd.getFileDescriptor();
12600             mKeepaliveTracker.startTcpKeepalive(
12601                     getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb);
12602         } finally {
12603             // FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
12604             // startTcpKeepalive calls Os.dup(fd) before returning, so we can close immediately.
12605             if (pfd != null && Binder.getCallingPid() != Process.myPid()) {
12606                 IoUtils.closeQuietly(pfd);
12607             }
12608         }
12609     }
12610 
12611     @Override
12612     public void stopKeepalive(@NonNull final ISocketKeepaliveCallback cb) {
12613         mHandler.sendMessage(mHandler.obtainMessage(
12614                 NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE, 0, SocketKeepalive.SUCCESS,
12615                 Objects.requireNonNull(cb).asBinder()));
12616     }
12617 
12618     @Override
12619     public int[] getSupportedKeepalives() {
12620         enforceAnyPermissionOf(mContext, android.Manifest.permission.NETWORK_SETTINGS,
12621                 // Backwards compatibility with CTS 13
12622                 android.Manifest.permission.QUERY_ALL_PACKAGES);
12623 
12624         return BinderUtils.withCleanCallingIdentity(() ->
12625                 KeepaliveResourceUtil.getSupportedKeepalives(mContext));
12626     }
12627 
12628     @Override
12629     public void factoryReset() {
12630         enforceSettingsPermission();
12631 
12632         final int uid = mDeps.getCallingUid();
12633         final long token = Binder.clearCallingIdentity();
12634         try {
12635             if (mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_NETWORK_RESET,
12636                     UserHandle.getUserHandleForUid(uid))) {
12637                 return;
12638             }
12639 
12640             final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext);
12641             ipMemoryStore.factoryReset();
12642 
12643             // Turn airplane mode off
12644             setAirplaneMode(false);
12645 
12646             // restore private DNS settings to default mode (opportunistic)
12647             if (!mUserManager.hasUserRestrictionForUser(UserManager.DISALLOW_CONFIG_PRIVATE_DNS,
12648                     UserHandle.getUserHandleForUid(uid))) {
12649                 ConnectivitySettingsManager.setPrivateDnsMode(mContext,
12650                         PRIVATE_DNS_MODE_OPPORTUNISTIC);
12651             }
12652 
12653             Settings.Global.putString(mContext.getContentResolver(),
12654                     ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null);
12655         } finally {
12656             Binder.restoreCallingIdentity(token);
12657         }
12658     }
12659 
12660     @Override
12661     public byte[] getNetworkWatchlistConfigHash() {
12662         NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class);
12663         if (nwm == null) {
12664             loge("Unable to get NetworkWatchlistManager");
12665             return null;
12666         }
12667         // Redirect it to network watchlist service to access watchlist file and calculate hash.
12668         return nwm.getWatchlistConfigHash();
12669     }
12670 
12671     private void logNetworkEvent(NetworkAgentInfo nai, int evtype) {
12672         int[] transports = nai.networkCapabilities.getTransportTypes();
12673         mMetricsLog.log(nai.network.getNetId(), transports, new NetworkEvent(evtype));
12674     }
12675 
12676     private static boolean toBool(int encodedBoolean) {
12677         return encodedBoolean != 0; // Only 0 means false.
12678     }
12679 
12680     private static int encodeBool(boolean b) {
12681         return b ? 1 : 0;
12682     }
12683 
12684     @Override
12685     public int handleShellCommand(@NonNull ParcelFileDescriptor in,
12686             @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
12687             @NonNull String[] args) {
12688         return new ShellCmd().exec(this, in.getFileDescriptor(), out.getFileDescriptor(),
12689                 err.getFileDescriptor(), args);
12690     }
12691 
12692     private class ShellCmd extends BasicShellCommandHandler {
12693 
12694         private Boolean parseBooleanArgument(final String arg) {
12695             if ("true".equals(arg)) {
12696                 return true;
12697             } else if ("false".equals(arg)) {
12698                 return false;
12699             } else {
12700                 getOutPrintWriter().println("Invalid boolean argument: " + arg);
12701                 return null;
12702             }
12703         }
12704 
12705         private Integer parseIntegerArgument(final String arg) {
12706             try {
12707                 return Integer.valueOf(arg);
12708             } catch (NumberFormatException ne) {
12709                 getOutPrintWriter().println("Invalid integer argument: " + arg);
12710                 return null;
12711             }
12712         }
12713 
12714         @Override
12715         public int onCommand(String cmd) {
12716             if (cmd == null) {
12717                 return handleDefaultCommands(cmd);
12718             }
12719             final PrintWriter pw = getOutPrintWriter();
12720             try {
12721                 switch (cmd) {
12722                     case "airplane-mode":
12723                         // Usage : adb shell cmd connectivity airplane-mode [enable|disable]
12724                         // If no argument, get and display the current status
12725                         final String action = getNextArg();
12726                         if ("enable".equals(action)) {
12727                             setAirplaneMode(true);
12728                             return 0;
12729                         } else if ("disable".equals(action)) {
12730                             setAirplaneMode(false);
12731                             return 0;
12732                         } else if (action == null) {
12733                             final ContentResolver cr = mContext.getContentResolver();
12734                             final int enabled = Settings.Global.getInt(cr,
12735                                     Settings.Global.AIRPLANE_MODE_ON);
12736                             pw.println(enabled == 0 ? "disabled" : "enabled");
12737                             return 0;
12738                         } else {
12739                             onHelp();
12740                             return -1;
12741                         }
12742                     case "set-chain3-enabled": {
12743                         final Boolean enabled = parseBooleanArgument(getNextArg());
12744                         if (null == enabled) {
12745                             onHelp();
12746                             return -1;
12747                         }
12748                         Log.i(TAG, (enabled ? "En" : "Dis") + "abled FIREWALL_CHAIN_OEM_DENY_3");
12749                         setFirewallChainEnabled(ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3,
12750                                 enabled);
12751                         return 0;
12752                     }
12753                     case "get-chain3-enabled": {
12754                         final boolean chainEnabled = getFirewallChainEnabled(
12755                                 ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3);
12756                         pw.println("chain:" + (chainEnabled ? "enabled" : "disabled"));
12757                         return 0;
12758                     }
12759                     case "set-package-networking-enabled": {
12760                         final Boolean enabled = parseBooleanArgument(getNextArg());
12761                         final String packageName = getNextArg();
12762                         if (null == enabled || null == packageName) {
12763                             onHelp();
12764                             return -1;
12765                         }
12766                         // Throws NameNotFound if the package doesn't exist.
12767                         final int appId = setPackageFirewallRule(
12768                                 ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3,
12769                                 packageName, enabled ? FIREWALL_RULE_DEFAULT : FIREWALL_RULE_DENY);
12770                         final String msg = (enabled ? "Enabled" : "Disabled")
12771                                 + " networking for " + packageName + ", appId " + appId;
12772                         Log.i(TAG, msg);
12773                         pw.println(msg);
12774                         return 0;
12775                     }
12776                     case "get-package-networking-enabled": {
12777                         if (!mDeps.isAtLeastT()) {
12778                             throw new UnsupportedOperationException(
12779                                     "This command is not supported on T-");
12780                         }
12781                         final String packageName = getNextArg();
12782                         final int rule = getPackageFirewallRule(
12783                                 ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3, packageName);
12784                         if (FIREWALL_RULE_ALLOW == rule || FIREWALL_RULE_DEFAULT == rule) {
12785                             pw.println(packageName + ":" + "allow");
12786                         } else if (FIREWALL_RULE_DENY == rule) {
12787                             pw.println(packageName + ":" + "deny");
12788                         } else {
12789                             throw new IllegalStateException("Unknown rule " + rule + " for package "
12790                                     + packageName);
12791                         }
12792                         return 0;
12793                     }
12794                     case "set-background-networking-enabled-for-uid": {
12795                         final Integer uid = parseIntegerArgument(getNextArg());
12796                         final Boolean enabled = parseBooleanArgument(getNextArg());
12797                         if (null == enabled || null == uid) {
12798                             onHelp();
12799                             return -1;
12800                         }
12801                         final int rule = enabled ? FIREWALL_RULE_ALLOW : FIREWALL_RULE_DEFAULT;
12802                         setUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, uid, rule);
12803                         final String msg = (enabled ? "Enabled" : "Disabled")
12804                                 + " background networking for  uid " + uid;
12805                         Log.i(TAG, msg);
12806                         pw.println(msg);
12807                         return 0;
12808                     }
12809                     case "get-background-networking-enabled-for-uid": {
12810                         if (!mDeps.isAtLeastT()) {
12811                             throw new UnsupportedOperationException(
12812                                     "This command is not supported on T-");
12813                         }
12814                         final Integer uid = parseIntegerArgument(getNextArg());
12815                         if (null == uid) {
12816                             onHelp();
12817                             return -1;
12818                         }
12819                         final int rule = getUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, uid);
12820                         if (FIREWALL_RULE_ALLOW == rule) {
12821                             pw.println(uid + ": allow");
12822                         } else if (FIREWALL_RULE_DENY == rule  || FIREWALL_RULE_DEFAULT == rule) {
12823                             pw.println(uid + ": deny");
12824                         } else {
12825                             throw new IllegalStateException(
12826                                     "Unknown rule " + rule + " for uid " + uid);
12827                         }
12828                         return 0;
12829                     }
12830                     case "reevaluate":
12831                         // Usage : adb shell cmd connectivity reevaluate <netId>
12832                         // If netId is omitted, then reevaluate the default network
12833                         final String netId = getNextArg();
12834                         final NetworkAgentInfo nai;
12835                         if (null == netId) {
12836                             // Note that the command is running on the wrong thread to call this,
12837                             // so this could in principle return stale data. But it can't crash.
12838                             nai = getDefaultNetwork();
12839                         } else {
12840                             // If netId can't be parsed, this throws NumberFormatException, which
12841                             // is passed back to adb who prints it.
12842                             nai = getNetworkAgentInfoForNetId(Integer.parseInt(netId));
12843                         }
12844                         if (null == nai) {
12845                             pw.println("Unknown network (net ID not found or no default network)");
12846                             return 0;
12847                         }
12848                         Log.d(TAG, "Reevaluating network " + nai.network);
12849                         reportNetworkConnectivity(nai.network, !nai.isValidated());
12850                         return 0;
12851                     case "bpf-get-cgroup-program-id": {
12852                         // Usage : adb shell cmd connectivity bpf-get-cgroup-program-id <type>
12853                         // Get cgroup bpf program Id for the given type. See BpfUtils#getProgramId
12854                         // for more detail.
12855                         // If type can't be parsed, this throws NumberFormatException, which
12856                         // is passed back to adb who prints it.
12857                         final int type = Integer.parseInt(getNextArg());
12858                         final int ret = BpfUtils.getProgramId(type);
12859                         pw.println(ret);
12860                         return 0;
12861                     }
12862                     default:
12863                         return handleDefaultCommands(cmd);
12864                 }
12865             } catch (Exception e) {
12866                 pw.println(e);
12867             }
12868             return -1;
12869         }
12870 
12871         @Override
12872         public void onHelp() {
12873             PrintWriter pw = getOutPrintWriter();
12874             pw.println("Connectivity service commands:");
12875             pw.println("  help");
12876             pw.println("    Print this help text.");
12877             pw.println("  airplane-mode [enable|disable]");
12878             pw.println("    Turn airplane mode on or off.");
12879             pw.println("  airplane-mode");
12880             pw.println("    Get airplane mode.");
12881             pw.println("  set-chain3-enabled [true|false]");
12882             pw.println("    Enable or disable FIREWALL_CHAIN_OEM_DENY_3 for debugging.");
12883             pw.println("  get-chain3-enabled");
12884             pw.println("    Returns whether FIREWALL_CHAIN_OEM_DENY_3 is enabled.");
12885             pw.println("  set-package-networking-enabled [true|false] [package name]");
12886             pw.println("    Set the deny bit in FIREWALL_CHAIN_OEM_DENY_3 to package. This has\n"
12887                     + "    no effect if the chain is disabled.");
12888             pw.println("  get-package-networking-enabled [package name]");
12889             pw.println("    Get the deny bit in FIREWALL_CHAIN_OEM_DENY_3 for package.");
12890             pw.println("  set-background-networking-enabled-for-uid [uid] [true|false]");
12891             pw.println("    Set the allow bit in FIREWALL_CHAIN_BACKGROUND for the given uid.");
12892             pw.println("  get-background-networking-enabled-for-uid [uid]");
12893             pw.println("    Get the allow bit in FIREWALL_CHAIN_BACKGROUND for the given uid.");
12894         }
12895     }
12896 
12897     private int getVpnType(@Nullable NetworkAgentInfo vpn) {
12898         if (vpn == null) return VpnManager.TYPE_VPN_NONE;
12899         final TransportInfo ti = vpn.networkCapabilities.getTransportInfo();
12900         if (!(ti instanceof VpnTransportInfo)) return VpnManager.TYPE_VPN_NONE;
12901         return ((VpnTransportInfo) ti).getType();
12902     }
12903 
12904     private boolean isVpnServiceVpn(NetworkAgentInfo nai) {
12905         final int vpnType = getVpnType(nai);
12906         return vpnType == VpnManager.TYPE_VPN_SERVICE || vpnType == VpnManager.TYPE_VPN_OEM_SERVICE;
12907     }
12908 
12909     private boolean isLegacyVpn(NetworkAgentInfo nai) {
12910         final int vpnType = getVpnType(nai);
12911         return vpnType == VpnManager.TYPE_VPN_LEGACY || vpnType == VpnManager.TYPE_VPN_OEM_LEGACY;
12912     }
12913 
12914     private boolean vpnSupportsInterfaceFiltering(NetworkAgentInfo vpn) {
12915         final int vpnType = getVpnType(vpn);
12916         return vpnType != VpnManager.TYPE_VPN_LEGACY
12917                 && vpnType != VpnManager.TYPE_VPN_OEM
12918                 && vpnType != VpnManager.TYPE_VPN_OEM_LEGACY;
12919     }
12920 
12921     private void maybeUpdateWifiRoamTimestamp(@NonNull NetworkAgentInfo nai,
12922             @NonNull NetworkCapabilities nc) {
12923         final TransportInfo prevInfo = nai.networkCapabilities.getTransportInfo();
12924         final TransportInfo newInfo = nc.getTransportInfo();
12925         if (!(prevInfo instanceof WifiInfo) || !(newInfo instanceof WifiInfo)) {
12926             return;
12927         }
12928         if (!TextUtils.equals(((WifiInfo)prevInfo).getBSSID(), ((WifiInfo)newInfo).getBSSID())) {
12929             nai.lastRoamTime = SystemClock.elapsedRealtime();
12930         }
12931     }
12932 
12933     /**
12934      * @param connectionInfo the connection to resolve.
12935      * @return {@code uid} if the connection is found and the app has permission to observe it
12936      * (e.g., if it is associated with the calling VPN app's tunnel) or {@code INVALID_UID} if the
12937      * connection is not found.
12938      */
12939     public int getConnectionOwnerUid(ConnectionInfo connectionInfo) {
12940         if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) {
12941             throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol);
12942         }
12943 
12944         final int uid = mDeps.getConnectionOwnerUid(connectionInfo.protocol,
12945                 connectionInfo.local, connectionInfo.remote);
12946 
12947         if (uid == INVALID_UID) return uid;  // Not found.
12948 
12949         // Connection owner UIDs are visible only to the network stack and to the VpnService-based
12950         // VPN, if any, that applies to the UID that owns the connection.
12951         if (hasNetworkStackPermission()) return uid;
12952 
12953         final NetworkAgentInfo vpn = getVpnForUid(uid);
12954         if (vpn == null || !isVpnServiceVpn(vpn)
12955                 || vpn.networkCapabilities.getOwnerUid() != mDeps.getCallingUid()) {
12956             return INVALID_UID;
12957         }
12958 
12959         return uid;
12960     }
12961 
12962     /**
12963      * Returns a IBinder to a TestNetworkService. Will be lazily created as needed.
12964      *
12965      * <p>The TestNetworkService must be run in the system server due to TUN creation.
12966      */
12967     @Override
12968     public IBinder startOrGetTestNetworkService() {
12969         synchronized (mTNSLock) {
12970             TestNetworkService.enforceTestNetworkPermissions(mContext);
12971 
12972             if (mTNS == null) {
12973                 mTNS = new TestNetworkService(mContext);
12974             }
12975 
12976             return mTNS;
12977         }
12978     }
12979 
12980     /**
12981      * Handler used for managing all Connectivity Diagnostics related functions.
12982      *
12983      * @see android.net.ConnectivityDiagnosticsManager
12984      *
12985      * TODO(b/147816404): Explore moving ConnectivityDiagnosticsHandler to a separate file
12986      */
12987     @VisibleForTesting
12988     class ConnectivityDiagnosticsHandler extends Handler {
12989         private final String mTag = ConnectivityDiagnosticsHandler.class.getSimpleName();
12990 
12991         /**
12992          * Used to handle ConnectivityDiagnosticsCallback registration events from {@link
12993          * android.net.ConnectivityDiagnosticsManager}.
12994          * obj = ConnectivityDiagnosticsCallbackInfo with IConnectivityDiagnosticsCallback and
12995          * NetworkRequestInfo to be registered
12996          */
12997         private static final int EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 1;
12998 
12999         /**
13000          * Used to handle ConnectivityDiagnosticsCallback unregister events from {@link
13001          * android.net.ConnectivityDiagnosticsManager}.
13002          * obj = the IConnectivityDiagnosticsCallback to be unregistered
13003          * arg1 = the uid of the caller
13004          */
13005         private static final int EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK = 2;
13006 
13007         /**
13008          * Event for {@link NetworkStateTrackerHandler} to trigger ConnectivityReport callbacks
13009          * after processing {@link #CMD_SEND_CONNECTIVITY_REPORT} events.
13010          * obj = {@link ConnectivityReportEvent} representing ConnectivityReport info reported from
13011          * NetworkMonitor.
13012          * data = PersistableBundle of extras passed from NetworkMonitor.
13013          */
13014         private static final int CMD_SEND_CONNECTIVITY_REPORT = 3;
13015 
13016         /**
13017          * Event for NetworkMonitor to inform ConnectivityService that a potential data stall has
13018          * been detected on the network.
13019          * obj = Long the timestamp (in millis) for when the suspected data stall was detected.
13020          * arg1 = {@link DataStallReport#DetectionMethod} indicating the detection method.
13021          * arg2 = NetID.
13022          * data = PersistableBundle of extras passed from NetworkMonitor.
13023          */
13024         private static final int EVENT_DATA_STALL_SUSPECTED = 4;
13025 
13026         /**
13027          * Event for ConnectivityDiagnosticsHandler to handle network connectivity being reported to
13028          * the platform. This event will invoke {@link
13029          * IConnectivityDiagnosticsCallback#onNetworkConnectivityReported} for permissioned
13030          * callbacks.
13031          * obj = ReportedNetworkConnectivityInfo with info on reported Network connectivity.
13032          */
13033         private static final int EVENT_NETWORK_CONNECTIVITY_REPORTED = 5;
13034 
13035         private ConnectivityDiagnosticsHandler(Looper looper) {
13036             super(looper);
13037         }
13038 
13039         @Override
13040         public void handleMessage(Message msg) {
13041             switch (msg.what) {
13042                 case EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: {
13043                     handleRegisterConnectivityDiagnosticsCallback(
13044                             (ConnectivityDiagnosticsCallbackInfo) msg.obj);
13045                     break;
13046                 }
13047                 case EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK: {
13048                     handleUnregisterConnectivityDiagnosticsCallback(
13049                             (IConnectivityDiagnosticsCallback) msg.obj, msg.arg1);
13050                     break;
13051                 }
13052                 case CMD_SEND_CONNECTIVITY_REPORT: {
13053                     final ConnectivityReportEvent reportEvent =
13054                             (ConnectivityReportEvent) msg.obj;
13055 
13056                     handleNetworkTestedWithExtras(reportEvent, reportEvent.mExtras);
13057                     break;
13058                 }
13059                 case EVENT_DATA_STALL_SUSPECTED: {
13060                     final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
13061                     final Pair<Long, PersistableBundle> arg =
13062                             (Pair<Long, PersistableBundle>) msg.obj;
13063                     if (nai == null) break;
13064 
13065                     handleDataStallSuspected(nai, arg.first, msg.arg1, arg.second);
13066                     break;
13067                 }
13068                 case EVENT_NETWORK_CONNECTIVITY_REPORTED: {
13069                     handleNetworkConnectivityReported((ReportedNetworkConnectivityInfo) msg.obj);
13070                     break;
13071                 }
13072                 default: {
13073                     Log.e(mTag, "Unrecognized event in ConnectivityDiagnostics: " + msg.what);
13074                 }
13075             }
13076         }
13077     }
13078 
13079     /** Class used for cleaning up IConnectivityDiagnosticsCallback instances after their death. */
13080     @VisibleForTesting
13081     class ConnectivityDiagnosticsCallbackInfo implements Binder.DeathRecipient {
13082         @NonNull private final IConnectivityDiagnosticsCallback mCb;
13083         @NonNull private final NetworkRequestInfo mRequestInfo;
13084         @NonNull private final String mCallingPackageName;
13085 
13086         @VisibleForTesting
13087         ConnectivityDiagnosticsCallbackInfo(
13088                 @NonNull IConnectivityDiagnosticsCallback cb,
13089                 @NonNull NetworkRequestInfo nri,
13090                 @NonNull String callingPackageName) {
13091             mCb = cb;
13092             mRequestInfo = nri;
13093             mCallingPackageName = callingPackageName;
13094         }
13095 
13096         @Override
13097         public void binderDied() {
13098             log("ConnectivityDiagnosticsCallback IBinder died.");
13099             unregisterConnectivityDiagnosticsCallback(mCb);
13100         }
13101     }
13102 
13103     /**
13104      * Class used for sending information from {@link
13105      * NetworkMonitorCallbacks#notifyNetworkTestedWithExtras} to the handler for processing it.
13106      */
13107     private static class NetworkTestedResults {
13108         private final int mNetId;
13109         private final int mTestResult;
13110         @Nullable private final String mRedirectUrl;
13111 
13112         private NetworkTestedResults(
13113                 int netId, int testResult, long timestampMillis, @Nullable String redirectUrl) {
13114             mNetId = netId;
13115             mTestResult = testResult;
13116             mRedirectUrl = redirectUrl;
13117         }
13118     }
13119 
13120     /**
13121      * Class used for sending information from {@link NetworkStateTrackerHandler} to {@link
13122      * ConnectivityDiagnosticsHandler}.
13123      */
13124     private static class ConnectivityReportEvent {
13125         private final long mTimestampMillis;
13126         @NonNull private final NetworkAgentInfo mNai;
13127         private final PersistableBundle mExtras;
13128 
13129         private ConnectivityReportEvent(long timestampMillis, @NonNull NetworkAgentInfo nai,
13130                 PersistableBundle p) {
13131             mTimestampMillis = timestampMillis;
13132             mNai = nai;
13133             mExtras = p;
13134         }
13135     }
13136 
13137     /**
13138      * Class used for sending info for a call to {@link #reportNetworkConnectivity()} to {@link
13139      * ConnectivityDiagnosticsHandler}.
13140      */
13141     private static class ReportedNetworkConnectivityInfo {
13142         public final boolean hasConnectivity;
13143         public final boolean isNetworkRevalidating;
13144         public final int reporterUid;
13145         @NonNull public final NetworkAgentInfo nai;
13146 
13147         private ReportedNetworkConnectivityInfo(
13148                 boolean hasConnectivity,
13149                 boolean isNetworkRevalidating,
13150                 int reporterUid,
13151                 @NonNull NetworkAgentInfo nai) {
13152             this.hasConnectivity = hasConnectivity;
13153             this.isNetworkRevalidating = isNetworkRevalidating;
13154             this.reporterUid = reporterUid;
13155             this.nai = nai;
13156         }
13157     }
13158 
13159     private void handleRegisterConnectivityDiagnosticsCallback(
13160             @NonNull ConnectivityDiagnosticsCallbackInfo cbInfo) {
13161         ensureRunningOnConnectivityServiceThread();
13162 
13163         final IConnectivityDiagnosticsCallback cb = cbInfo.mCb;
13164         final IBinder iCb = cb.asBinder();
13165         final NetworkRequestInfo nri = cbInfo.mRequestInfo;
13166 
13167         // Connectivity Diagnostics are meant to be used with a single network request. It would be
13168         // confusing for these networks to change when an NRI is satisfied in another layer.
13169         if (nri.isMultilayerRequest()) {
13170             throw new IllegalArgumentException("Connectivity Diagnostics do not support multilayer "
13171                 + "network requests.");
13172         }
13173 
13174         // This means that the client registered the same callback multiple times. Do
13175         // not override the previous entry, and exit silently.
13176         if (mConnectivityDiagnosticsCallbacks.containsKey(iCb)) {
13177             if (VDBG) log("Diagnostics callback is already registered");
13178 
13179             // Decrement the reference count for this NetworkRequestInfo. The reference count is
13180             // incremented when the NetworkRequestInfo is created as part of
13181             // enforceRequestCountLimit().
13182             nri.mPerUidCounter.decrementCount(nri.mUid);
13183             return;
13184         }
13185 
13186         mConnectivityDiagnosticsCallbacks.put(iCb, cbInfo);
13187 
13188         try {
13189             iCb.linkToDeath(cbInfo, 0);
13190         } catch (RemoteException e) {
13191             cbInfo.binderDied();
13192             return;
13193         }
13194 
13195         // Once registered, provide ConnectivityReports for matching Networks
13196         final List<NetworkAgentInfo> matchingNetworks = new ArrayList<>();
13197         synchronized (mNetworkForNetId) {
13198             for (int i = 0; i < mNetworkForNetId.size(); i++) {
13199                 final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
13200                 // Connectivity Diagnostics rejects multilayer requests at registration hence get(0)
13201                 if (nai.satisfies(nri.mRequests.get(0))) {
13202                     matchingNetworks.add(nai);
13203                 }
13204             }
13205         }
13206         for (final NetworkAgentInfo nai : matchingNetworks) {
13207             final ConnectivityReport report = nai.getConnectivityReport();
13208             if (report == null) {
13209                 continue;
13210             }
13211             if (!hasConnectivityDiagnosticsPermissions(
13212                     nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) {
13213                 continue;
13214             }
13215 
13216             try {
13217                 cb.onConnectivityReportAvailable(report);
13218             } catch (RemoteException e) {
13219                 // Exception while sending the ConnectivityReport. Move on to the next network.
13220             }
13221         }
13222     }
13223 
13224     private void handleUnregisterConnectivityDiagnosticsCallback(
13225             @NonNull IConnectivityDiagnosticsCallback cb, int uid) {
13226         ensureRunningOnConnectivityServiceThread();
13227         final IBinder iCb = cb.asBinder();
13228 
13229         final ConnectivityDiagnosticsCallbackInfo cbInfo =
13230                 mConnectivityDiagnosticsCallbacks.remove(iCb);
13231         if (cbInfo == null) {
13232             if (VDBG) log("Removing diagnostics callback that is not currently registered");
13233             return;
13234         }
13235 
13236         final NetworkRequestInfo nri = cbInfo.mRequestInfo;
13237 
13238         // Caller's UID must either be the registrants (if they are unregistering) or the System's
13239         // (if the Binder died)
13240         if (uid != nri.mUid && uid != Process.SYSTEM_UID) {
13241             if (DBG) loge("Uid(" + uid + ") not registrant's (" + nri.mUid + ") or System's");
13242             return;
13243         }
13244 
13245         // Decrement the reference count for this NetworkRequestInfo. The reference count is
13246         // incremented when the NetworkRequestInfo is created as part of
13247         // enforceRequestCountLimit().
13248         nri.mPerUidCounter.decrementCount(nri.mUid);
13249 
13250         iCb.unlinkToDeath(cbInfo, 0);
13251     }
13252 
13253     private void handleNetworkTestedWithExtras(
13254             @NonNull ConnectivityReportEvent reportEvent, @NonNull PersistableBundle extras) {
13255         final NetworkAgentInfo nai = reportEvent.mNai;
13256         final NetworkCapabilities networkCapabilities =
13257                 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities);
13258         final ConnectivityReport report =
13259                 new ConnectivityReport(
13260                         reportEvent.mNai.network,
13261                         reportEvent.mTimestampMillis,
13262                         nai.linkProperties,
13263                         networkCapabilities,
13264                         extras);
13265         nai.setConnectivityReport(report);
13266 
13267         final List<IConnectivityDiagnosticsCallback> results =
13268                 getMatchingPermissionedCallbacks(nai, Process.INVALID_UID);
13269         for (final IConnectivityDiagnosticsCallback cb : results) {
13270             try {
13271                 cb.onConnectivityReportAvailable(report);
13272             } catch (RemoteException ex) {
13273                 loge("Error invoking onConnectivityReportAvailable", ex);
13274             }
13275         }
13276     }
13277 
13278     private void handleDataStallSuspected(
13279             @NonNull NetworkAgentInfo nai, long timestampMillis, int detectionMethod,
13280             @NonNull PersistableBundle extras) {
13281         final NetworkCapabilities networkCapabilities =
13282                 getNetworkCapabilitiesWithoutUids(nai.networkCapabilities);
13283         final DataStallReport report =
13284                 new DataStallReport(
13285                         nai.network,
13286                         timestampMillis,
13287                         detectionMethod,
13288                         nai.linkProperties,
13289                         networkCapabilities,
13290                         extras);
13291         final List<IConnectivityDiagnosticsCallback> results =
13292                 getMatchingPermissionedCallbacks(nai, Process.INVALID_UID);
13293         for (final IConnectivityDiagnosticsCallback cb : results) {
13294             try {
13295                 cb.onDataStallSuspected(report);
13296             } catch (RemoteException ex) {
13297                 loge("Error invoking onDataStallSuspected", ex);
13298             }
13299         }
13300     }
13301 
13302     private void handleNetworkConnectivityReported(
13303             @NonNull ReportedNetworkConnectivityInfo reportedNetworkConnectivityInfo) {
13304         final NetworkAgentInfo nai = reportedNetworkConnectivityInfo.nai;
13305         final ConnectivityReport cachedReport = nai.getConnectivityReport();
13306 
13307         // If the Network is being re-validated as a result of this call to
13308         // reportNetworkConnectivity(), notify all permissioned callbacks. Otherwise, only notify
13309         // permissioned callbacks registered by the reporter.
13310         final List<IConnectivityDiagnosticsCallback> results =
13311                 getMatchingPermissionedCallbacks(
13312                         nai,
13313                         reportedNetworkConnectivityInfo.isNetworkRevalidating
13314                                 ? Process.INVALID_UID
13315                                 : reportedNetworkConnectivityInfo.reporterUid);
13316 
13317         for (final IConnectivityDiagnosticsCallback cb : results) {
13318             try {
13319                 cb.onNetworkConnectivityReported(
13320                         nai.network, reportedNetworkConnectivityInfo.hasConnectivity);
13321             } catch (RemoteException ex) {
13322                 loge("Error invoking onNetworkConnectivityReported", ex);
13323             }
13324 
13325             // If the Network isn't re-validating, also provide the cached report. If there is no
13326             // cached report, the Network is still being validated and a report will be sent once
13327             // validation is complete. Note that networks which never undergo validation will still
13328             // have a cached ConnectivityReport with RESULT_SKIPPED.
13329             if (!reportedNetworkConnectivityInfo.isNetworkRevalidating && cachedReport != null) {
13330                 try {
13331                     cb.onConnectivityReportAvailable(cachedReport);
13332                 } catch (RemoteException ex) {
13333                     loge("Error invoking onConnectivityReportAvailable", ex);
13334                 }
13335             }
13336         }
13337     }
13338 
13339     private NetworkCapabilities getNetworkCapabilitiesWithoutUids(@NonNull NetworkCapabilities nc) {
13340         final NetworkCapabilities sanitized = new NetworkCapabilities(nc,
13341                 NetworkCapabilities.REDACT_ALL);
13342         sanitized.setUids(null);
13343         sanitized.setAdministratorUids(new int[0]);
13344         sanitized.setOwnerUid(Process.INVALID_UID);
13345         return sanitized;
13346     }
13347 
13348     /**
13349      * Gets a list of ConnectivityDiagnostics callbacks that match the specified Network and uid.
13350      *
13351      * <p>If Process.INVALID_UID is specified, all matching callbacks will be returned.
13352      */
13353     private List<IConnectivityDiagnosticsCallback> getMatchingPermissionedCallbacks(
13354             @NonNull NetworkAgentInfo nai, int uid) {
13355         final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>();
13356         for (Entry<IBinder, ConnectivityDiagnosticsCallbackInfo> entry :
13357                 mConnectivityDiagnosticsCallbacks.entrySet()) {
13358             final ConnectivityDiagnosticsCallbackInfo cbInfo = entry.getValue();
13359             final NetworkRequestInfo nri = cbInfo.mRequestInfo;
13360 
13361             // Connectivity Diagnostics rejects multilayer requests at registration hence get(0).
13362             if (!nai.satisfies(nri.mRequests.get(0))) {
13363                 continue;
13364             }
13365 
13366             // UID for this callback must either be:
13367             //  - INVALID_UID (which sends callbacks to all UIDs), or
13368             //  - The callback's owner (the owner called reportNetworkConnectivity() and is being
13369             //    notified as a result)
13370             if (uid != Process.INVALID_UID && uid != nri.mUid) {
13371                 continue;
13372             }
13373 
13374             if (!hasConnectivityDiagnosticsPermissions(
13375                     nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) {
13376                 continue;
13377             }
13378 
13379             results.add(entry.getValue().mCb);
13380         }
13381         return results;
13382     }
13383 
13384     private boolean isLocationPermissionRequiredForConnectivityDiagnostics(
13385             @NonNull NetworkAgentInfo nai) {
13386         // TODO(b/188483916): replace with a transport-agnostic location-aware check
13387         return nai.networkCapabilities.hasTransport(TRANSPORT_WIFI);
13388     }
13389 
13390     private boolean hasLocationPermission(String packageName, int uid) {
13391         // LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid
13392         // and package name don't match. Throwing on the CS thread is not acceptable, so wrap the
13393         // call in a try-catch.
13394         try {
13395             if (!mLocationPermissionChecker.checkLocationPermission(
13396                         packageName, null /* featureId */, uid, null /* message */)) {
13397                 return false;
13398             }
13399         } catch (SecurityException e) {
13400             return false;
13401         }
13402 
13403         return true;
13404     }
13405 
13406     private boolean ownsVpnRunningOverNetwork(int uid, Network network) {
13407         return anyNetworkAgentInfo(virtual ->
13408                 virtual.propagateUnderlyingCapabilities()
13409                         && virtual.networkCapabilities.getOwnerUid() == uid
13410                         && CollectionUtils.contains(virtual.declaredUnderlyingNetworks, network));
13411     }
13412 
13413     @CheckResult
13414     @VisibleForTesting
13415     boolean hasConnectivityDiagnosticsPermissions(
13416             int callbackPid, int callbackUid, NetworkAgentInfo nai, String callbackPackageName) {
13417         if (hasNetworkStackPermission(callbackPid, callbackUid)) {
13418             return true;
13419         }
13420         if (mAllowSysUiConnectivityReports
13421                 && hasSystemBarServicePermission(callbackPid, callbackUid)) {
13422             return true;
13423         }
13424 
13425         // Administrator UIDs also contains the Owner UID
13426         final int[] administratorUids = nai.networkCapabilities.getAdministratorUids();
13427         if (!CollectionUtils.contains(administratorUids, callbackUid)
13428                 && !ownsVpnRunningOverNetwork(callbackUid, nai.network)) {
13429             return false;
13430         }
13431 
13432         return !isLocationPermissionRequiredForConnectivityDiagnostics(nai)
13433                 || hasLocationPermission(callbackPackageName, callbackUid);
13434     }
13435 
13436     @Override
13437     public void registerConnectivityDiagnosticsCallback(
13438             @NonNull IConnectivityDiagnosticsCallback callback,
13439             @NonNull NetworkRequest request,
13440             @NonNull String callingPackageName) {
13441         Objects.requireNonNull(callback, "callback must not be null");
13442         Objects.requireNonNull(request, "request must not be null");
13443         Objects.requireNonNull(callingPackageName, "callingPackageName must not be null");
13444 
13445         if (request.legacyType != TYPE_NONE) {
13446             throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated."
13447                     + " Please use NetworkCapabilities instead.");
13448         }
13449         final int callingUid = mDeps.getCallingUid();
13450         mAppOpsManager.checkPackage(callingUid, callingPackageName);
13451 
13452         // This NetworkCapabilities is only used for matching to Networks. Clear out its owner uid
13453         // and administrator uids to be safe.
13454         final NetworkCapabilities nc = new NetworkCapabilities(request.networkCapabilities);
13455         restrictRequestNetworkCapabilitiesForCaller(nc, callingUid, callingPackageName);
13456 
13457         final NetworkRequest requestWithId =
13458                 new NetworkRequest(
13459                         nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN);
13460 
13461         // NetworkRequestInfos created here count towards MAX_NETWORK_REQUESTS_PER_UID limit.
13462         //
13463         // nri is not bound to the death of callback. Instead, callback.bindToDeath() is set in
13464         // handleRegisterConnectivityDiagnosticsCallback(). nri will be cleaned up as part of the
13465         // callback's binder death.
13466         final NetworkRequestInfo nri = new NetworkRequestInfo(callingUid, requestWithId);
13467         nri.mPerUidCounter.incrementCountOrThrow(nri.mUid);
13468         final ConnectivityDiagnosticsCallbackInfo cbInfo =
13469                 new ConnectivityDiagnosticsCallbackInfo(callback, nri, callingPackageName);
13470 
13471         mConnectivityDiagnosticsHandler.sendMessage(
13472                 mConnectivityDiagnosticsHandler.obtainMessage(
13473                         ConnectivityDiagnosticsHandler
13474                                 .EVENT_REGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK,
13475                         cbInfo));
13476     }
13477 
13478     @Override
13479     public void unregisterConnectivityDiagnosticsCallback(
13480             @NonNull IConnectivityDiagnosticsCallback callback) {
13481         Objects.requireNonNull(callback, "callback must be non-null");
13482         mConnectivityDiagnosticsHandler.sendMessage(
13483                 mConnectivityDiagnosticsHandler.obtainMessage(
13484                         ConnectivityDiagnosticsHandler
13485                                 .EVENT_UNREGISTER_CONNECTIVITY_DIAGNOSTICS_CALLBACK,
13486                         mDeps.getCallingUid(),
13487                         0,
13488                         callback));
13489     }
13490 
13491     private boolean hasUnderlyingTestNetworks(NetworkCapabilities nc) {
13492         final List<Network> underlyingNetworks = nc.getUnderlyingNetworks();
13493         if (underlyingNetworks == null) return false;
13494 
13495         for (Network network : underlyingNetworks) {
13496             if (getNetworkCapabilitiesInternal(network).hasTransport(TRANSPORT_TEST)) {
13497                 return true;
13498             }
13499         }
13500         return false;
13501     }
13502 
13503     @Override
13504     public void simulateDataStall(int detectionMethod, long timestampMillis,
13505             @NonNull Network network, @NonNull PersistableBundle extras) {
13506         Objects.requireNonNull(network, "network must not be null");
13507         Objects.requireNonNull(extras, "extras must not be null");
13508 
13509         enforceAnyPermissionOf(mContext,
13510                 android.Manifest.permission.MANAGE_TEST_NETWORKS,
13511                 android.Manifest.permission.NETWORK_STACK);
13512         final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
13513         if (!nc.hasTransport(TRANSPORT_TEST) && !hasUnderlyingTestNetworks(nc)) {
13514             throw new SecurityException(
13515                     "Data Stall simulation is only possible for test networks or networks built on"
13516                             + " top of test networks");
13517         }
13518 
13519         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
13520         if (nai == null
13521                 || (nai.creatorUid != mDeps.getCallingUid()
13522                         && nai.creatorUid != Process.SYSTEM_UID)) {
13523             throw new SecurityException(
13524                     "Data Stall simulation is only possible for network " + "creators");
13525         }
13526 
13527         // Instead of passing the data stall directly to the ConnectivityDiagnostics handler, treat
13528         // this as a Data Stall received directly from NetworkMonitor. This requires wrapping the
13529         // Data Stall information as a DataStallReportParcelable and passing to
13530         // #notifyDataStallSuspected. This ensures that unknown Data Stall detection methods are
13531         // still passed to ConnectivityDiagnostics (with new detection methods masked).
13532         final DataStallReportParcelable p = new DataStallReportParcelable();
13533         p.timestampMillis = timestampMillis;
13534         p.detectionMethod = detectionMethod;
13535 
13536         if (hasDataStallDetectionMethod(p, DETECTION_METHOD_DNS_EVENTS)) {
13537             p.dnsConsecutiveTimeouts = extras.getInt(KEY_DNS_CONSECUTIVE_TIMEOUTS);
13538         }
13539         if (hasDataStallDetectionMethod(p, DETECTION_METHOD_TCP_METRICS)) {
13540             p.tcpPacketFailRate = extras.getInt(KEY_TCP_PACKET_FAIL_RATE);
13541             p.tcpMetricsCollectionPeriodMillis = extras.getInt(
13542                     KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS);
13543         }
13544 
13545         notifyDataStallSuspected(p, network.getNetId());
13546     }
13547 
13548     /**
13549      * Class to hold the information for network activity change event from idle timers
13550      * {@link NetdCallback#onInterfaceClassActivityChanged(boolean, int, long, int)}
13551      */
13552     private static final class NetworkActivityParams {
13553         public final boolean isActive;
13554         // If TrackMultiNetworkActivities is enabled, idleTimer label is netid.
13555         // If TrackMultiNetworkActivities is disabled, idleTimer label is transport type.
13556         public final int label;
13557         public final long timestampNs;
13558         // Uid represents the uid that was responsible for waking the radio.
13559         // -1 for no uid and uid is -1 if isActive is false.
13560         public final int uid;
13561 
13562         NetworkActivityParams(boolean isActive, int label, long timestampNs, int uid) {
13563             this.isActive = isActive;
13564             this.label = label;
13565             this.timestampNs = timestampNs;
13566             this.uid = uid;
13567         }
13568     }
13569 
13570     private class NetdCallback extends BaseNetdUnsolicitedEventListener {
13571         @Override
13572         public void onInterfaceClassActivityChanged(boolean isActive, int label,
13573                 long timestampNs, int uid) {
13574             mHandler.sendMessage(mHandler.obtainMessage(EVENT_REPORT_NETWORK_ACTIVITY,
13575                     new NetworkActivityParams(isActive, label, timestampNs, uid)));
13576         }
13577 
13578         @Override
13579         public void onInterfaceLinkStateChanged(@NonNull String iface, boolean up) {
13580             mHandler.post(() -> {
13581                 forEachNetworkAgentInfo(nai ->
13582                         nai.clatd.handleInterfaceLinkStateChanged(iface, up));
13583             });
13584         }
13585 
13586         @Override
13587         public void onInterfaceRemoved(@NonNull String iface) {
13588             mHandler.post(() -> {
13589                 forEachNetworkAgentInfo(nai ->
13590                         nai.clatd.handleInterfaceRemoved(iface));
13591             });
13592         }
13593     }
13594 
13595     private final boolean mTrackMultiNetworkActivities;
13596     private final LegacyNetworkActivityTracker mNetworkActivityTracker;
13597 
13598     /**
13599      * Class used for updating network activity tracking with netd and notify network activity
13600      * changes.
13601      */
13602     @VisibleForTesting
13603     public static final class LegacyNetworkActivityTracker {
13604         private static final int NO_UID = -1;
13605         private final Context mContext;
13606         private final INetd mNetd;
13607         private final Handler mHandler;
13608         private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
13609                 new RemoteCallbackList<>();
13610         // Indicate the current system default network activity is active or not.
13611         // This needs to be volatile to allow non handler threads to read this value without lock.
13612         // If there is no default network, default network is considered active to keep the existing
13613         // behavior. Initial value is used until first connect to the default network.
13614         private volatile boolean mIsDefaultNetworkActive = true;
13615         private Network mDefaultNetwork;
13616         // Key is netId. Value is configured idle timer information.
13617         private final SparseArray<IdleTimerParams> mActiveIdleTimers = new SparseArray<>();
13618         private final boolean mTrackMultiNetworkActivities;
13619         private final int mDefaultCellularDataInactivityTimeout;
13620         private final int mDefaultWifiDataInactivityTimeout;
13621         // Store netIds of Wi-Fi networks whose idletimers report that they are active
13622         private final Set<Integer> mActiveWifiNetworks = new ArraySet<>();
13623         // Store netIds of cellular networks whose idletimers report that they are active
13624         private final Set<Integer> mActiveCellularNetworks = new ArraySet<>();
13625 
13626         private static class IdleTimerParams {
13627             public final int timeout;
13628             public final int transportType;
13629 
13630             IdleTimerParams(int timeout, int transport) {
13631                 this.timeout = timeout;
13632                 this.transportType = transport;
13633             }
13634         }
13635 
13636         LegacyNetworkActivityTracker(@NonNull Context context, @NonNull INetd netd,
13637                 @NonNull Handler handler, boolean trackMultiNetworkActivities,
13638                 int defaultCellularDataInactivityTimeout, int defaultWifiDataInactivityTimeout) {
13639             mContext = context;
13640             mNetd = netd;
13641             mHandler = handler;
13642             mTrackMultiNetworkActivities = trackMultiNetworkActivities;
13643             mDefaultCellularDataInactivityTimeout = defaultCellularDataInactivityTimeout;
13644             mDefaultWifiDataInactivityTimeout = defaultWifiDataInactivityTimeout;
13645         }
13646 
13647         private void ensureRunningOnConnectivityServiceThread() {
13648             HandlerUtils.ensureRunningOnHandlerThread(mHandler);
13649         }
13650 
13651         /**
13652          * Update network activity and call BatteryStats to update radio power state if the
13653          * mobile or Wi-Fi activity is changed.
13654          * LegacyNetworkActivityTracker considers the mobile network is active if at least one
13655          * mobile network is active since BatteryStatsService only maintains a single power state
13656          * for the mobile network.
13657          * The Wi-Fi network is also the same.
13658          *
13659          * {@link #setupDataActivityTracking} and {@link #removeDataActivityTracking} use
13660          * TRANSPORT_CELLULAR as the transportType argument if the network has both cell and Wi-Fi
13661          * transports.
13662          */
13663         private void maybeUpdateRadioPowerState(final int netId, final int transportType,
13664                 final boolean isActive, final int uid) {
13665             if (transportType != TRANSPORT_WIFI && transportType != TRANSPORT_CELLULAR) {
13666                 Log.e(TAG, "Unexpected transportType in maybeUpdateRadioPowerState: "
13667                         + transportType);
13668                 return;
13669             }
13670             final Set<Integer> activeNetworks = transportType == TRANSPORT_WIFI
13671                     ? mActiveWifiNetworks : mActiveCellularNetworks;
13672 
13673             final boolean wasEmpty = activeNetworks.isEmpty();
13674             if (isActive) {
13675                 activeNetworks.add(netId);
13676             } else {
13677                 activeNetworks.remove(netId);
13678             }
13679 
13680             if (wasEmpty != activeNetworks.isEmpty()) {
13681                 updateRadioPowerState(isActive, transportType, uid);
13682             }
13683         }
13684 
13685         private void handleDefaultNetworkActivity(final int transportType,
13686                 final boolean isActive, final long timestampNs) {
13687             mIsDefaultNetworkActive = isActive;
13688             sendDataActivityBroadcast(transportTypeToLegacyType(transportType),
13689                     isActive, timestampNs);
13690             if (isActive) {
13691                 reportNetworkActive();
13692             }
13693         }
13694 
13695         private void handleReportNetworkActivityWithNetIdLabel(
13696                 NetworkActivityParams activityParams) {
13697             final int netId = activityParams.label;
13698             final IdleTimerParams idleTimerParams = mActiveIdleTimers.get(netId);
13699             if (idleTimerParams == null) {
13700                 // This network activity change is not tracked anymore
13701                 // This can happen if netd callback post activity change event message but idle
13702                 // timer is removed before processing this message.
13703                 return;
13704             }
13705             // TODO: if a network changes transports, storing the transport type in the
13706             // IdleTimerParams is not correct. Consider getting it from the network's
13707             // NetworkCapabilities instead.
13708             final int transportType = idleTimerParams.transportType;
13709             maybeUpdateRadioPowerState(netId, transportType,
13710                     activityParams.isActive, activityParams.uid);
13711 
13712             if (mDefaultNetwork == null || mDefaultNetwork.netId != netId) {
13713                 // This activity change is not for the default network.
13714                 return;
13715             }
13716 
13717             handleDefaultNetworkActivity(transportType, activityParams.isActive,
13718                     activityParams.timestampNs);
13719         }
13720 
13721         private void handleReportNetworkActivityWithTransportTypeLabel(
13722                 NetworkActivityParams activityParams) {
13723             if (mActiveIdleTimers.size() == 0) {
13724                 // This activity change is not for the current default network.
13725                 // This can happen if netd callback post activity change event message but
13726                 // the default network is lost before processing this message.
13727                 return;
13728             }
13729             handleDefaultNetworkActivity(activityParams.label, activityParams.isActive,
13730                     activityParams.timestampNs);
13731         }
13732 
13733         /**
13734          * Handle network activity change
13735          */
13736         public void handleReportNetworkActivity(NetworkActivityParams activityParams) {
13737             ensureRunningOnConnectivityServiceThread();
13738             if (mTrackMultiNetworkActivities) {
13739                 handleReportNetworkActivityWithNetIdLabel(activityParams);
13740             } else {
13741                 handleReportNetworkActivityWithTransportTypeLabel(activityParams);
13742             }
13743         }
13744 
13745         private void reportNetworkActive() {
13746             final int length = mNetworkActivityListeners.beginBroadcast();
13747             if (DDBG) log("reportNetworkActive, notify " + length + " listeners");
13748             try {
13749                 for (int i = 0; i < length; i++) {
13750                     try {
13751                         mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
13752                     } catch (RemoteException | RuntimeException e) {
13753                         loge("Fail to send network activity to listener " + e);
13754                     }
13755                 }
13756             } finally {
13757                 mNetworkActivityListeners.finishBroadcast();
13758             }
13759         }
13760 
13761         // This is deprecated and only to support legacy use cases.
13762         private int transportTypeToLegacyType(int type) {
13763             switch (type) {
13764                 case NetworkCapabilities.TRANSPORT_CELLULAR:
13765                     return TYPE_MOBILE;
13766                 case NetworkCapabilities.TRANSPORT_WIFI:
13767                     return TYPE_WIFI;
13768                 case NetworkCapabilities.TRANSPORT_BLUETOOTH:
13769                     return TYPE_BLUETOOTH;
13770                 case NetworkCapabilities.TRANSPORT_ETHERNET:
13771                     return TYPE_ETHERNET;
13772                 default:
13773                     loge("Unexpected transport in transportTypeToLegacyType: " + type);
13774             }
13775             return ConnectivityManager.TYPE_NONE;
13776         }
13777 
13778         public void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) {
13779             final Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE);
13780             intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType);
13781             intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active);
13782             intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos);
13783             final long ident = Binder.clearCallingIdentity();
13784             try {
13785                 mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL,
13786                         RECEIVE_DATA_ACTIVITY_CHANGE,
13787                         null /* resultReceiver */,
13788                         null /* scheduler */,
13789                         0 /* initialCode */,
13790                         null /* initialData */,
13791                         null /* initialExtra */);
13792             } finally {
13793                 Binder.restoreCallingIdentity(ident);
13794             }
13795         }
13796 
13797         /**
13798          * Get idle timer label
13799          */
13800         @VisibleForTesting
13801         public static int getIdleTimerLabel(final boolean trackMultiNetworkActivities,
13802                 final int netId, final int transportType) {
13803             return trackMultiNetworkActivities ? netId : transportType;
13804         }
13805 
13806         private boolean maybeCreateIdleTimer(
13807                 String iface, int netId, int timeout, int transportType) {
13808             if (timeout <= 0 || iface == null) return false;
13809             try {
13810                 final String label = Integer.toString(getIdleTimerLabel(
13811                         mTrackMultiNetworkActivities, netId, transportType));
13812                 mNetd.idletimerAddInterface(iface, timeout, label);
13813                 mActiveIdleTimers.put(netId, new IdleTimerParams(timeout, transportType));
13814                 return true;
13815             } catch (Exception e) {
13816                 loge("Exception in createIdleTimer", e);
13817                 return false;
13818             }
13819         }
13820 
13821         /**
13822          * Setup data activity tracking for the given network.
13823          *
13824          * Every {@code setupDataActivityTracking} should be paired with a
13825          * {@link #removeDataActivityTracking} for cleanup.
13826          *
13827          * @return true if the idleTimer is added to the network, false otherwise
13828          */
13829         private boolean setupDataActivityTracking(NetworkAgentInfo networkAgent) {
13830             ensureRunningOnConnectivityServiceThread();
13831             final String iface = networkAgent.linkProperties.getInterfaceName();
13832             final int netId = networkAgent.network().netId;
13833 
13834             final int timeout;
13835             final int type;
13836 
13837             if (!networkAgent.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_VPN)) {
13838                 // Do not track VPN network.
13839                 return false;
13840             } else if (networkAgent.networkCapabilities.hasTransport(
13841                     NetworkCapabilities.TRANSPORT_CELLULAR)) {
13842                 timeout = Settings.Global.getInt(mContext.getContentResolver(),
13843                         ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_MOBILE,
13844                         mDefaultCellularDataInactivityTimeout);
13845                 type = NetworkCapabilities.TRANSPORT_CELLULAR;
13846             } else if (networkAgent.networkCapabilities.hasTransport(
13847                     NetworkCapabilities.TRANSPORT_WIFI)) {
13848                 timeout = Settings.Global.getInt(mContext.getContentResolver(),
13849                         ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_WIFI,
13850                         mDefaultWifiDataInactivityTimeout);
13851                 type = NetworkCapabilities.TRANSPORT_WIFI;
13852             } else {
13853                 return false; // do not track any other networks
13854             }
13855 
13856             final boolean hasIdleTimer = maybeCreateIdleTimer(iface, netId, timeout, type);
13857             if (hasIdleTimer || !mTrackMultiNetworkActivities) {
13858                 // If trackMultiNetwork is disabled, NetworkActivityTracker updates radio power
13859                 // state in all cases. If trackMultiNetwork is enabled, it updates radio power
13860                 // state only about a network that has an idletimer.
13861                 maybeUpdateRadioPowerState(netId, type, true /* isActive */, NO_UID);
13862             }
13863             return hasIdleTimer;
13864         }
13865 
13866         /**
13867          * Remove data activity tracking when network disconnects.
13868          */
13869         public void removeDataActivityTracking(NetworkAgentInfo networkAgent) {
13870             ensureRunningOnConnectivityServiceThread();
13871             final String iface = networkAgent.linkProperties.getInterfaceName();
13872             final int netId = networkAgent.network().netId;
13873             final NetworkCapabilities caps = networkAgent.networkCapabilities;
13874 
13875             if (iface == null) return;
13876 
13877             final int type;
13878             if (!networkAgent.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_VPN)) {
13879                 // Do not track VPN network.
13880                 return;
13881             } else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
13882                 type = NetworkCapabilities.TRANSPORT_CELLULAR;
13883             } else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
13884                 type = NetworkCapabilities.TRANSPORT_WIFI;
13885             } else {
13886                 return; // do not track any other networks
13887             }
13888 
13889             try {
13890                 maybeUpdateRadioPowerState(netId, type, false /* isActive */, NO_UID);
13891                 final IdleTimerParams params = mActiveIdleTimers.get(netId);
13892                 if (params == null) {
13893                     // IdleTimer is not added if the configured timeout is 0 or negative value
13894                     return;
13895                 }
13896                 mActiveIdleTimers.remove(netId);
13897                 final String label = Integer.toString(getIdleTimerLabel(
13898                         mTrackMultiNetworkActivities, netId, params.transportType));
13899                         // The call fails silently if no idle timer setup for this interface
13900                 mNetd.idletimerRemoveInterface(iface, params.timeout, label);
13901             } catch (Exception e) {
13902                 // You shall not crash!
13903                 loge("Exception in removeDataActivityTracking " + e);
13904             }
13905         }
13906 
13907         private void updateDefaultNetworkActivity(NetworkAgentInfo defaultNetwork,
13908                 boolean hasIdleTimer) {
13909             if (defaultNetwork != null) {
13910                 mDefaultNetwork = defaultNetwork.network();
13911                 mIsDefaultNetworkActive = true;
13912                 // If only the default network is tracked, callbacks are called only when the
13913                 // network has the idle timer.
13914                 if (mTrackMultiNetworkActivities || hasIdleTimer) {
13915                     reportNetworkActive();
13916                 }
13917             } else {
13918                 mDefaultNetwork = null;
13919                 // If there is no default network, default network is considered active to keep the
13920                 // existing behavior.
13921                 mIsDefaultNetworkActive = true;
13922             }
13923         }
13924 
13925         /**
13926          * Update the default network this class tracks the activity of.
13927          */
13928         public void updateDefaultNetwork(NetworkAgentInfo newNetwork,
13929                 NetworkAgentInfo oldNetwork) {
13930             ensureRunningOnConnectivityServiceThread();
13931             // If TrackMultiNetworkActivities is enabled, devices add idleTimer when the network is
13932             // first connected and remove when the network is disconnected.
13933             // If TrackMultiNetworkActivities is disabled, devices add idleTimer when the network
13934             // becomes the default network and remove when the network becomes no longer the default
13935             // network.
13936             boolean hasIdleTimer = false;
13937             if (!mTrackMultiNetworkActivities && newNetwork != null) {
13938                 hasIdleTimer = setupDataActivityTracking(newNetwork);
13939             }
13940             updateDefaultNetworkActivity(newNetwork, hasIdleTimer);
13941             if (!mTrackMultiNetworkActivities && oldNetwork != null) {
13942                 removeDataActivityTracking(oldNetwork);
13943             }
13944         }
13945 
13946         private void updateRadioPowerState(boolean isActive, int transportType, int uid) {
13947             final BatteryStatsManager bs = mContext.getSystemService(BatteryStatsManager.class);
13948             switch (transportType) {
13949                 case NetworkCapabilities.TRANSPORT_CELLULAR:
13950                     bs.reportMobileRadioPowerState(isActive, uid);
13951                     break;
13952                 case NetworkCapabilities.TRANSPORT_WIFI:
13953                     bs.reportWifiRadioPowerState(isActive, uid);
13954                     break;
13955                 default:
13956                     logw("Untracked transport type:" + transportType);
13957             }
13958         }
13959 
13960         public boolean isDefaultNetworkActive() {
13961             return mIsDefaultNetworkActive;
13962         }
13963 
13964         public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
13965             mNetworkActivityListeners.register(l);
13966         }
13967 
13968         public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
13969             mNetworkActivityListeners.unregister(l);
13970         }
13971 
13972         public void dump(IndentingPrintWriter pw) {
13973             pw.print("mTrackMultiNetworkActivities="); pw.println(mTrackMultiNetworkActivities);
13974 
13975             pw.print("mDefaultCellularDataInactivityTimeout=");
13976             pw.println(mDefaultCellularDataInactivityTimeout);
13977             pw.print("mDefaultWifiDataInactivityTimeout=");
13978             pw.println(mDefaultWifiDataInactivityTimeout);
13979 
13980             pw.print("mIsDefaultNetworkActive="); pw.println(mIsDefaultNetworkActive);
13981             pw.print("mDefaultNetwork="); pw.println(mDefaultNetwork);
13982             pw.println("Idle timers:");
13983             try {
13984                 for (int i = 0; i < mActiveIdleTimers.size(); i++) {
13985                     pw.print("  "); pw.print(mActiveIdleTimers.keyAt(i)); pw.println(":");
13986                     final IdleTimerParams params = mActiveIdleTimers.valueAt(i);
13987                     pw.print("    timeout="); pw.print(params.timeout);
13988                     pw.print(" type="); pw.println(params.transportType);
13989                 }
13990                 pw.println("WiFi active networks: " + mActiveWifiNetworks);
13991                 pw.println("Cellular active networks: " + mActiveCellularNetworks);
13992             } catch (Exception e) {
13993                 // mActiveIdleTimers, mActiveWifiNetworks, and mActiveCellularNetworks should only
13994                 // be accessed from handler thread, except dump(). As dump() is never called in
13995                 // normal usage, it would be needlessly expensive to lock the collection only for
13996                 // its benefit. Also, they are not expected to be updated frequently.
13997                 // So catching the exception and logging.
13998                 pw.println("Failed to dump NetworkActivityTracker: " + e);
13999             }
14000         }
14001     }
14002 
14003     /**
14004      * Registers {@link QosSocketFilter} with {@link IQosCallback}.
14005      *
14006      * @param socketInfo the socket information
14007      * @param callback the callback to register
14008      */
14009     @Override
14010     public void registerQosSocketCallback(@NonNull final QosSocketInfo socketInfo,
14011             @NonNull final IQosCallback callback) {
14012         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(socketInfo.getNetwork());
14013         if (nai == null || nai.networkCapabilities == null) {
14014             try {
14015                 callback.onError(QosCallbackException.EX_TYPE_FILTER_NETWORK_RELEASED);
14016             } catch (final RemoteException ex) {
14017                 loge("registerQosCallbackInternal: RemoteException", ex);
14018             }
14019             return;
14020         }
14021         registerQosCallbackInternal(new QosSocketFilter(socketInfo), callback, nai);
14022     }
14023 
14024     /**
14025      * Register a {@link IQosCallback} with base {@link QosFilter}.
14026      *
14027      * @param filter the filter to register
14028      * @param callback the callback to register
14029      * @param nai the agent information related to the filter's network
14030      */
14031     @VisibleForTesting
14032     public void registerQosCallbackInternal(@NonNull final QosFilter filter,
14033             @NonNull final IQosCallback callback, @NonNull final NetworkAgentInfo nai) {
14034         Objects.requireNonNull(filter, "filter must be non-null");
14035         Objects.requireNonNull(callback, "callback must be non-null");
14036 
14037         if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
14038             // TODO: Check allowed list here and ensure that either a) any QoS callback registered
14039             //  on this network is unregistered when the app loses permission or b) no QoS
14040             //  callbacks are sent for restricted networks unless the app currently has permission
14041             //  to access restricted networks.
14042             enforceConnectivityRestrictedNetworksPermission(false /* checkUidsAllowedList */);
14043         }
14044         mQosCallbackTracker.registerCallback(callback, filter, nai);
14045     }
14046 
14047     /**
14048      * Unregisters the given callback.
14049      *
14050      * @param callback the callback to unregister
14051      */
14052     @Override
14053     public void unregisterQosCallback(@NonNull final IQosCallback callback) {
14054         Objects.requireNonNull(callback, "callback must be non-null");
14055         mQosCallbackTracker.unregisterCallback(callback);
14056     }
14057 
14058     private boolean isNetworkPreferenceAllowedForProfile(@NonNull UserHandle profile) {
14059         // UserManager.isManagedProfile returns true for all apps in managed user profiles.
14060         // Enterprise device can be fully managed like device owner and such use case
14061         // also should be supported. Calling app check for work profile and fully managed device
14062         // is already done in DevicePolicyManager.
14063         // This check is an extra caution to be sure device is fully managed or not.
14064         final UserManager um = mContext.getSystemService(UserManager.class);
14065         final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
14066         if (um.isManagedProfile(profile.getIdentifier())) {
14067             return true;
14068         }
14069 
14070         return mDeps.isAtLeastT() && dpm.getDeviceOwnerComponentOnAnyUser() != null;
14071     }
14072 
14073     /**
14074      * Set a list of default network selection policies for a user profile or device owner.
14075      *
14076      * See the documentation for the individual preferences for a description of the supported
14077      * behaviors.
14078      *
14079      * @param profile If the device owner is set, any profile is allowed.
14080               Otherwise, the given profile can only be managed profile.
14081      * @param preferences the list of profile network preferences for the
14082      *        provided profile.
14083      * @param listener an optional listener to listen for completion of the operation.
14084      */
14085     @Override
14086     public void setProfileNetworkPreferences(
14087             @NonNull final UserHandle profile,
14088             @NonNull List<ProfileNetworkPreference> preferences,
14089             @Nullable final IOnCompleteListener listener) {
14090         Objects.requireNonNull(preferences);
14091         Objects.requireNonNull(profile);
14092 
14093         if (preferences.size() == 0) {
14094             final ProfileNetworkPreference pref = new ProfileNetworkPreference.Builder()
14095                     .setPreference(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT)
14096                     .build();
14097             preferences.add(pref);
14098         }
14099 
14100         enforceNetworkStackPermission(mContext);
14101         if (DBG) {
14102             log("setProfileNetworkPreferences " + profile + " to " + preferences);
14103         }
14104         if (profile.getIdentifier() < 0) {
14105             throw new IllegalArgumentException("Must explicitly specify a user handle ("
14106                     + "UserHandle.CURRENT not supported)");
14107         }
14108         if (!isNetworkPreferenceAllowedForProfile(profile)) {
14109             throw new IllegalArgumentException("Profile must be a managed profile "
14110                     + "or the device owner must be set. ");
14111         }
14112 
14113         final List<ProfileNetworkPreferenceInfo> preferenceList = new ArrayList<>();
14114         boolean hasDefaultPreference = false;
14115         for (final ProfileNetworkPreference preference : preferences) {
14116             final NetworkCapabilities nc;
14117             boolean allowFallback = true;
14118             boolean blockingNonEnterprise = false;
14119             switch (preference.getPreference()) {
14120                 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT:
14121                     nc = null;
14122                     hasDefaultPreference = true;
14123                     if (preference.getPreferenceEnterpriseId() != 0) {
14124                         throw new IllegalArgumentException(
14125                                 "Invalid enterprise identifier in setProfileNetworkPreferences");
14126                     }
14127                     break;
14128                 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING:
14129                     blockingNonEnterprise = true;
14130                     // continue to process the enterprise preference.
14131                 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK:
14132                     allowFallback = false;
14133                     // continue to process the enterprise preference.
14134                 case ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE:
14135                     // This code is needed even though there is a check later on,
14136                     // because isRangeAlreadyInPreferenceList assumes that every preference
14137                     // has a UID list.
14138                     if (hasDefaultPreference) {
14139                         throw new IllegalArgumentException(
14140                                 "Default profile preference should not be set along with other "
14141                                         + "preference");
14142                     }
14143                     if (!isEnterpriseIdentifierValid(preference.getPreferenceEnterpriseId())) {
14144                         throw new IllegalArgumentException(
14145                                 "Invalid enterprise identifier in setProfileNetworkPreferences");
14146                     }
14147                     final Set<UidRange> uidRangeSet =
14148                             getUidListToBeAppliedForNetworkPreference(profile, preference);
14149                     if (!isRangeAlreadyInPreferenceList(preferenceList, uidRangeSet)) {
14150                         nc = createDefaultNetworkCapabilitiesForUidRangeSet(uidRangeSet);
14151                     } else {
14152                         throw new IllegalArgumentException(
14153                                 "Overlapping uid range in setProfileNetworkPreferences");
14154                     }
14155                     nc.addCapability(NET_CAPABILITY_ENTERPRISE);
14156                     nc.addEnterpriseId(
14157                             preference.getPreferenceEnterpriseId());
14158                     nc.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
14159                     break;
14160                 default:
14161                     throw new IllegalArgumentException(
14162                             "Invalid preference in setProfileNetworkPreferences");
14163             }
14164             preferenceList.add(new ProfileNetworkPreferenceInfo(
14165                     profile, nc, allowFallback, blockingNonEnterprise));
14166             if (hasDefaultPreference && preferenceList.size() > 1) {
14167                 throw new IllegalArgumentException(
14168                         "Default profile preference should not be set along with other preference");
14169             }
14170         }
14171         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_PROFILE_NETWORK_PREFERENCE,
14172                 new Pair<>(preferenceList, listener)));
14173     }
14174 
14175     private Set<UidRange> getUidListToBeAppliedForNetworkPreference(
14176             @NonNull final UserHandle profile,
14177             @NonNull final ProfileNetworkPreference profileNetworkPreference) {
14178         final UidRange profileUids = UidRange.createForUser(profile);
14179         Set<UidRange> uidRangeSet = UidRangeUtils.convertArrayToUidRange(
14180                         profileNetworkPreference.getIncludedUids());
14181 
14182         if (uidRangeSet.size() > 0) {
14183             if (!UidRangeUtils.isRangeSetInUidRange(profileUids, uidRangeSet)) {
14184                 throw new IllegalArgumentException(
14185                         "Allow uid range is outside the uid range of profile.");
14186             }
14187         } else {
14188             ArraySet<UidRange> disallowUidRangeSet = UidRangeUtils.convertArrayToUidRange(
14189                     profileNetworkPreference.getExcludedUids());
14190             if (disallowUidRangeSet.size() > 0) {
14191                 if (!UidRangeUtils.isRangeSetInUidRange(profileUids, disallowUidRangeSet)) {
14192                     throw new IllegalArgumentException(
14193                             "disallow uid range is outside the uid range of profile.");
14194                 }
14195                 uidRangeSet = UidRangeUtils.removeRangeSetFromUidRange(profileUids,
14196                         disallowUidRangeSet);
14197             } else {
14198                 uidRangeSet = new ArraySet<>();
14199                 uidRangeSet.add(profileUids);
14200             }
14201         }
14202         return uidRangeSet;
14203     }
14204 
14205     private boolean isEnterpriseIdentifierValid(
14206             @NetworkCapabilities.EnterpriseId int identifier) {
14207         if ((identifier >= NET_ENTERPRISE_ID_1) && (identifier <= NET_ENTERPRISE_ID_5)) {
14208             return true;
14209         }
14210         return false;
14211     }
14212 
14213     private ArraySet<NetworkRequestInfo> createNrisFromProfileNetworkPreferences(
14214             @NonNull final NetworkPreferenceList<UserHandle, ProfileNetworkPreferenceInfo> prefs) {
14215         final ArraySet<NetworkRequestInfo> result = new ArraySet<>();
14216         for (final ProfileNetworkPreferenceInfo pref : prefs) {
14217             // The NRI for a user should contain the request for capabilities.
14218             // If fallback to default network is needed then NRI should include
14219             // the request for the default network. Create an image of it to
14220             // have the correct UIDs in it (also a request can only be part of one NRI, because
14221             // of lookups in 1:1 associations like mNetworkRequests).
14222             final ArrayList<NetworkRequest> nrs = new ArrayList<>();
14223             nrs.add(createNetworkRequest(NetworkRequest.Type.REQUEST, pref.capabilities));
14224             if (pref.allowFallback) {
14225                 nrs.add(createDefaultInternetRequestForTransport(
14226                         TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
14227             }
14228             if (VDBG) {
14229                 loge("pref.capabilities.getUids():" + UidRange.fromIntRanges(
14230                         pref.capabilities.getUids()));
14231             }
14232 
14233             setNetworkRequestUids(nrs, UidRange.fromIntRanges(pref.capabilities.getUids()));
14234             final NetworkRequestInfo nri = new NetworkRequestInfo(Process.myUid(), nrs,
14235                     PREFERENCE_ORDER_PROFILE);
14236             result.add(nri);
14237         }
14238         return result;
14239     }
14240 
14241     /**
14242      * Compare if the given UID range sets have the same UIDs.
14243      *
14244      */
14245     private boolean isRangeAlreadyInPreferenceList(
14246             @NonNull List<ProfileNetworkPreferenceInfo> preferenceList,
14247             @NonNull Set<UidRange> uidRangeSet) {
14248         if (uidRangeSet.size() == 0 || preferenceList.size() == 0) {
14249             return false;
14250         }
14251         for (ProfileNetworkPreferenceInfo pref : preferenceList) {
14252             if (UidRangeUtils.doesRangeSetOverlap(
14253                     UidRange.fromIntRanges(pref.capabilities.getUids()), uidRangeSet)) {
14254                 return true;
14255             }
14256         }
14257         return false;
14258     }
14259 
14260     private void handleSetProfileNetworkPreference(
14261             @NonNull final List<ProfileNetworkPreferenceInfo> preferenceList,
14262             @Nullable final IOnCompleteListener listener) {
14263         /*
14264          * handleSetProfileNetworkPreference is always called for single user.
14265          * preferenceList only contains preferences for different uids within the same user
14266          * (enforced by getUidListToBeAppliedForNetworkPreference).
14267          * Clear all the existing preferences for the user before applying new preferences.
14268          *
14269          */
14270         mProfileNetworkPreferences = mProfileNetworkPreferences.minus(preferenceList.get(0).user);
14271         for (final ProfileNetworkPreferenceInfo preference : preferenceList) {
14272             mProfileNetworkPreferences = mProfileNetworkPreferences.plus(preference);
14273         }
14274 
14275         removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_PROFILE);
14276         addPerAppDefaultNetworkRequests(
14277                 createNrisFromProfileNetworkPreferences(mProfileNetworkPreferences));
14278         updateProfileAllowedNetworks();
14279 
14280         // Finally, rematch.
14281         rematchAllNetworksAndRequests();
14282 
14283         if (null != listener) {
14284             try {
14285                 listener.onComplete();
14286             } catch (RemoteException e) {
14287                 loge("Listener for setProfileNetworkPreference has died");
14288             }
14289         }
14290     }
14291 
14292     @VisibleForTesting
14293     @NonNull
14294     ArraySet<NetworkRequestInfo> createNrisForPreferenceOrder(@NonNull final Set<Integer> uids,
14295             @NonNull final List<NetworkRequest> requests,
14296             final int preferenceOrder) {
14297         final ArraySet<NetworkRequestInfo> nris = new ArraySet<>();
14298         if (uids.size() == 0) {
14299             // Should not create NetworkRequestInfo if no preferences. Without uid range in
14300             // NetworkRequestInfo, makeDefaultForApps() would treat it as a illegal NRI.
14301             return nris;
14302         }
14303 
14304         final Set<UidRange> ranges = new ArraySet<>();
14305         for (final int uid : uids) {
14306             ranges.add(new UidRange(uid, uid));
14307         }
14308         setNetworkRequestUids(requests, ranges);
14309         nris.add(new NetworkRequestInfo(Process.myUid(), requests, preferenceOrder));
14310         return nris;
14311     }
14312 
14313     ArraySet<NetworkRequestInfo> createNrisFromMobileDataPreferredUids(
14314             @NonNull final Set<Integer> uids) {
14315         final List<NetworkRequest> requests = new ArrayList<>();
14316         // The NRI should be comprised of two layers:
14317         // - The request for the mobile network preferred.
14318         // - The request for the default network, for fallback.
14319         requests.add(createDefaultInternetRequestForTransport(
14320                 TRANSPORT_CELLULAR, NetworkRequest.Type.REQUEST));
14321         requests.add(createDefaultInternetRequestForTransport(
14322                 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
14323         return createNrisForPreferenceOrder(uids, requests, PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED
14324         );
14325     }
14326 
14327     ArraySet<NetworkRequestInfo> createMultiLayerNrisFromSatelliteNetworkFallbackUids(
14328             @NonNull final Set<Integer> uids) {
14329         final List<NetworkRequest> requests = new ArrayList<>();
14330 
14331         // request: track default(unrestricted internet network)
14332         requests.add(createDefaultInternetRequestForTransport(
14333                 TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
14334 
14335         // request: Satellite internet, satellite network could be restricted or constrained
14336         final NetworkCapabilities cap = new NetworkCapabilities.Builder()
14337                 .addCapability(NET_CAPABILITY_INTERNET)
14338                 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
14339                 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
14340                 .removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)
14341                 .addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE)
14342                 .build();
14343         requests.add(createNetworkRequest(NetworkRequest.Type.REQUEST, cap));
14344 
14345         return createNrisForPreferenceOrder(uids, requests, PREFERENCE_ORDER_SATELLITE_FALLBACK);
14346     }
14347 
14348     private void handleMobileDataPreferredUidsChanged() {
14349         mMobileDataPreferredUids = ConnectivitySettingsManager.getMobileDataPreferredUids(mContext);
14350         removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED);
14351         addPerAppDefaultNetworkRequests(
14352                 createNrisFromMobileDataPreferredUids(mMobileDataPreferredUids));
14353         // Finally, rematch.
14354         rematchAllNetworksAndRequests();
14355     }
14356 
14357     private void handleSetSatelliteNetworkPreference(
14358             @NonNull final Set<Integer> satelliteNetworkPreferredUids) {
14359         removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_SATELLITE_FALLBACK);
14360         addPerAppDefaultNetworkRequests(
14361                 createMultiLayerNrisFromSatelliteNetworkFallbackUids(satelliteNetworkPreferredUids)
14362         );
14363         // Finally, rematch.
14364         rematchAllNetworksAndRequests();
14365     }
14366 
14367     private void handleIngressRateLimitChanged() {
14368         final long oldIngressRateLimit = mIngressRateLimit;
14369         mIngressRateLimit = ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond(
14370                 mContext);
14371         forEachNetworkAgentInfo(networkAgent -> {
14372             if (canNetworkBeRateLimited(networkAgent)) {
14373                 // If rate limit has previously been enabled, remove the old limit first.
14374                 if (oldIngressRateLimit >= 0) {
14375                     mDeps.disableIngressRateLimit(networkAgent.linkProperties.getInterfaceName());
14376                 }
14377                 if (mIngressRateLimit >= 0) {
14378                     mDeps.enableIngressRateLimit(networkAgent.linkProperties.getInterfaceName(),
14379                             mIngressRateLimit);
14380                 }
14381             }
14382         });
14383     }
14384 
14385     private boolean canNetworkBeRateLimited(@NonNull final NetworkAgentInfo networkAgent) {
14386         // Rate-limiting cannot run correctly before T because the BPF program is not loaded.
14387         if (!mDeps.isAtLeastT()) return false;
14388 
14389         final NetworkCapabilities agentCaps = networkAgent.networkCapabilities;
14390         // Only test networks (they cannot hold NET_CAPABILITY_INTERNET) and networks that provide
14391         // internet connectivity can be rate limited.
14392         if (!agentCaps.hasCapability(NET_CAPABILITY_INTERNET) && !agentCaps.hasTransport(
14393                 TRANSPORT_TEST)) {
14394             return false;
14395         }
14396 
14397         final String iface = networkAgent.linkProperties.getInterfaceName();
14398         if (iface == null) {
14399             // This may happen in tests, but if there is no interface then there is nothing that
14400             // can be rate limited.
14401             loge("canNetworkBeRateLimited: LinkProperties#getInterfaceName returns null");
14402             return false;
14403         }
14404         return true;
14405     }
14406 
14407     private void enforceAutomotiveDevice() {
14408         PermissionUtils.enforceSystemFeature(mContext, PackageManager.FEATURE_AUTOMOTIVE,
14409                 "setOemNetworkPreference() is only available on automotive devices.");
14410     }
14411 
14412     /**
14413      * Used by automotive devices to set the network preferences used to direct traffic at an
14414      * application level as per the given OemNetworkPreferences. An example use-case would be an
14415      * automotive OEM wanting to provide connectivity for applications critical to the usage of a
14416      * vehicle via a particular network.
14417      *
14418      * Calling this will overwrite the existing preference.
14419      *
14420      * @param preference {@link OemNetworkPreferences} The application network preference to be set.
14421      * @param listener {@link ConnectivityManager.OnCompleteListener} Listener used
14422      * to communicate completion of setOemNetworkPreference();
14423      */
14424     @Override
14425     public void setOemNetworkPreference(
14426             @NonNull final OemNetworkPreferences preference,
14427             @Nullable final IOnCompleteListener listener) {
14428 
14429         Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
14430         // Only bypass the permission/device checks if this is a valid test request.
14431         if (isValidTestOemNetworkPreference(preference)) {
14432             enforceManageTestNetworksPermission();
14433         } else {
14434             enforceAutomotiveDevice();
14435             enforceOemNetworkPreferencesPermission();
14436             validateOemNetworkPreferences(preference);
14437         }
14438 
14439         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_OEM_NETWORK_PREFERENCE,
14440                 new Pair<>(preference, listener)));
14441     }
14442 
14443     /**
14444      * Sets the specified UIDs to get/receive the VPN as the only default network.
14445      *
14446      * Calling this will overwrite the existing network preference for this session, and the
14447      * specified UIDs won't get any default network when no VPN is connected.
14448      *
14449      * @param session The VPN session which manages the passed UIDs.
14450      * @param ranges The uid ranges which will treat VPN as the only preferred network. Clear the
14451      *               setting for this session if the array is empty. Null is not allowed, the
14452      *               method will use {@link Objects#requireNonNull(Object)} to check this variable.
14453      * @hide
14454      */
14455     @Override
14456     public void setVpnNetworkPreference(String session, UidRange[] ranges) {
14457         Objects.requireNonNull(ranges);
14458         enforceNetworkStackOrSettingsPermission();
14459         final UidRange[] sortedRanges = UidRangeUtils.sortRangesByStartUid(ranges);
14460         if (UidRangeUtils.sortedRangesContainOverlap(sortedRanges)) {
14461             throw new IllegalArgumentException(
14462                     "setVpnNetworkPreference: Passed UID ranges overlap");
14463         }
14464 
14465         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_VPN_NETWORK_PREFERENCE,
14466                 new VpnNetworkPreferenceInfo(session,
14467                         new ArraySet<UidRange>(Arrays.asList(ranges)))));
14468     }
14469 
14470     private void handleSetVpnNetworkPreference(VpnNetworkPreferenceInfo preferenceInfo) {
14471         Log.d(TAG, "handleSetVpnNetworkPreference: preferenceInfo = " + preferenceInfo);
14472 
14473         mVpnNetworkPreferences = mVpnNetworkPreferences.minus(preferenceInfo.getKey());
14474         mVpnNetworkPreferences = mVpnNetworkPreferences.plus(preferenceInfo);
14475 
14476         removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_VPN);
14477         addPerAppDefaultNetworkRequests(createNrisForVpnNetworkPreference(mVpnNetworkPreferences));
14478         // Finally, rematch.
14479         rematchAllNetworksAndRequests();
14480     }
14481 
14482     private ArraySet<NetworkRequestInfo> createNrisForVpnNetworkPreference(
14483             @NonNull NetworkPreferenceList<String, VpnNetworkPreferenceInfo> preferenceList) {
14484         final ArraySet<NetworkRequestInfo> nris = new ArraySet<>();
14485         for (VpnNetworkPreferenceInfo preferenceInfo : preferenceList) {
14486             final List<NetworkRequest> requests = new ArrayList<>();
14487             // Request VPN only, so other networks won't be the fallback options when VPN is not
14488             // connected temporarily.
14489             requests.add(createVpnRequest());
14490             final Set<UidRange> uidRanges = new ArraySet(preferenceInfo.getUidRangesNoCopy());
14491             setNetworkRequestUids(requests, uidRanges);
14492             nris.add(new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_ORDER_VPN));
14493         }
14494         return nris;
14495     }
14496 
14497     /**
14498      * Check the validity of an OEM network preference to be used for testing purposes.
14499      * @param preference the preference to validate
14500      * @return true if this is a valid OEM network preference test request.
14501      */
14502     private boolean isValidTestOemNetworkPreference(
14503             @NonNull final OemNetworkPreferences preference) {
14504         // Allow for clearing of an existing OemNetworkPreference used for testing.
14505         // This isn't called on the handler thread so it is possible that mOemNetworkPreferences
14506         // changes after this check is complete. This is an unlikely scenario as calling of this API
14507         // is controlled by the OEM therefore the added complexity is not worth adding given those
14508         // circumstances. That said, it is an edge case to be aware of hence this comment.
14509         final boolean isValidTestClearPref = preference.getNetworkPreferences().size() == 0
14510                 && isTestOemNetworkPreference(mOemNetworkPreferences);
14511         return isTestOemNetworkPreference(preference) || isValidTestClearPref;
14512     }
14513 
14514     private boolean isTestOemNetworkPreference(@NonNull final OemNetworkPreferences preference) {
14515         final Map<String, Integer> prefMap = preference.getNetworkPreferences();
14516         return prefMap.size() == 1
14517                 && (prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST)
14518                 || prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST_ONLY));
14519     }
14520 
14521     private void validateOemNetworkPreferences(@NonNull OemNetworkPreferences preference) {
14522         for (@OemNetworkPreferences.OemNetworkPreference final int pref
14523                 : preference.getNetworkPreferences().values()) {
14524             if (pref <= 0 || OemNetworkPreferences.OEM_NETWORK_PREFERENCE_MAX < pref) {
14525                 throw new IllegalArgumentException(
14526                         OemNetworkPreferences.oemNetworkPreferenceToString(pref)
14527                                 + " is an invalid value.");
14528             }
14529         }
14530     }
14531 
14532     private void handleSetOemNetworkPreference(
14533             @NonNull final OemNetworkPreferences preference,
14534             @Nullable final IOnCompleteListener listener) {
14535         Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
14536         if (DBG) {
14537             log("set OEM network preferences :" + preference.toString());
14538         }
14539 
14540         mOemNetworkPreferencesLogs.log("UPDATE INITIATED: " + preference);
14541         removeDefaultNetworkRequestsForPreference(PREFERENCE_ORDER_OEM);
14542         addPerAppDefaultNetworkRequests(new OemNetworkRequestFactory()
14543                 .createNrisFromOemNetworkPreferences(preference));
14544         mOemNetworkPreferences = preference;
14545 
14546         if (null != listener) {
14547             try {
14548                 listener.onComplete();
14549             } catch (RemoteException e) {
14550                 loge("Can't send onComplete in handleSetOemNetworkPreference", e);
14551             }
14552         }
14553     }
14554 
14555     private void removeDefaultNetworkRequestsForPreference(final int preferenceOrder) {
14556         // Skip the requests which are set by other network preference. Because the uid range rules
14557         // should stay in netd.
14558         final Set<NetworkRequestInfo> requests = new ArraySet<>(mDefaultNetworkRequests);
14559         requests.removeIf(request -> request.mPreferenceOrder != preferenceOrder);
14560         handleRemoveNetworkRequests(requests);
14561     }
14562 
14563     private void addPerAppDefaultNetworkRequests(@NonNull final Set<NetworkRequestInfo> nris) {
14564         ensureRunningOnConnectivityServiceThread();
14565         mDefaultNetworkRequests.addAll(nris);
14566         final ArraySet<NetworkRequestInfo> perAppCallbackRequestsToUpdate =
14567                 getPerAppCallbackRequestsToUpdate();
14568         final ArraySet<NetworkRequestInfo> nrisToRegister = new ArraySet<>(nris);
14569         // This method does not need to modify perUidCounter and mBlockedStatusTrackingUids because:
14570         // - |nris| only contains per-app network requests created by ConnectivityService which
14571         //    are internal requests and have no messenger and are not associated with any callbacks,
14572         //    and so do not need to be tracked in perUidCounter and mBlockedStatusTrackingUids.
14573         // - The requests in perAppCallbackRequestsToUpdate are removed, modified, and re-added,
14574         //   but the same number of requests is removed and re-added, and none of the requests
14575         //   changes mUid and mAsUid, so the perUidCounter and mBlockedStatusTrackingUids before
14576         //   and after this method remains the same. Re-adding the requests does not modify
14577         //   perUidCounter and mBlockedStatusTrackingUids (that is done when the app registers the
14578         //   request), so removing them must not modify perUidCounter and mBlockedStatusTrackingUids
14579         //   either.
14580         // TODO(b/341228979): Modify nris in place instead of removing them and re-adding them
14581         handleRemoveNetworkRequests(perAppCallbackRequestsToUpdate,
14582                 false /* untrackUids */);
14583         nrisToRegister.addAll(
14584                 createPerAppCallbackRequestsToRegister(perAppCallbackRequestsToUpdate));
14585         handleRegisterNetworkRequests(nrisToRegister);
14586     }
14587 
14588     /**
14589      * All current requests that are tracking the default network need to be assessed as to whether
14590      * or not the current set of per-application default requests will be changing their default
14591      * network. If so, those requests will need to be updated so that they will send callbacks for
14592      * default network changes at the appropriate time. Additionally, those requests tracking the
14593      * default that were previously updated by this flow will need to be reassessed.
14594      * @return the nris which will need to be updated.
14595      */
14596     private ArraySet<NetworkRequestInfo> getPerAppCallbackRequestsToUpdate() {
14597         final ArraySet<NetworkRequestInfo> defaultCallbackRequests = new ArraySet<>();
14598         // Get the distinct nris to check since for multilayer requests, it is possible to have the
14599         // same nri in the map's values for each of its NetworkRequest objects.
14600         final ArraySet<NetworkRequestInfo> nris = new ArraySet<>(mNetworkRequests.values());
14601         for (final NetworkRequestInfo nri : nris) {
14602             // Include this nri if it is currently being tracked.
14603             if (isPerAppTrackedNri(nri)) {
14604                 defaultCallbackRequests.add(nri);
14605                 continue;
14606             }
14607             // We only track callbacks for requests tracking the default.
14608             if (NetworkRequest.Type.TRACK_DEFAULT != nri.mRequests.get(0).type) {
14609                 continue;
14610             }
14611             // Include this nri if it will be tracked by the new per-app default requests.
14612             final boolean isNriGoingToBeTracked =
14613                     getDefaultRequestTrackingUid(nri.mAsUid) != mDefaultRequest;
14614             if (isNriGoingToBeTracked) {
14615                 defaultCallbackRequests.add(nri);
14616             }
14617         }
14618         return defaultCallbackRequests;
14619     }
14620 
14621     /**
14622      * Create nris for those network requests that are currently tracking the default network that
14623      * are being controlled by a per-application default.
14624      * @param perAppCallbackRequestsForUpdate the baseline network requests to be used as the
14625      * foundation when creating the nri. Important items include the calling uid's original
14626      * NetworkRequest to be used when mapping callbacks as well as the caller's uid and name. These
14627      * requests are assumed to have already been validated as needing to be updated.
14628      * @return the Set of nris to use when registering network requests.
14629      */
14630     private ArraySet<NetworkRequestInfo> createPerAppCallbackRequestsToRegister(
14631             @NonNull final ArraySet<NetworkRequestInfo> perAppCallbackRequestsForUpdate) {
14632         final ArraySet<NetworkRequestInfo> callbackRequestsToRegister = new ArraySet<>();
14633         for (final NetworkRequestInfo callbackRequest : perAppCallbackRequestsForUpdate) {
14634             final NetworkRequestInfo trackingNri =
14635                     getDefaultRequestTrackingUid(callbackRequest.mAsUid);
14636 
14637             // If this nri is not being tracked, then change it back to an untracked nri.
14638             if (trackingNri == mDefaultRequest) {
14639                 callbackRequestsToRegister.add(new NetworkRequestInfo(
14640                         callbackRequest,
14641                         Collections.singletonList(callbackRequest.getNetworkRequestForCallback())));
14642                 continue;
14643             }
14644 
14645             final NetworkRequest request = callbackRequest.mRequests.get(0);
14646             callbackRequestsToRegister.add(new NetworkRequestInfo(
14647                     callbackRequest,
14648                     copyNetworkRequestsForUid(
14649                             trackingNri.mRequests, callbackRequest.mAsUid,
14650                             callbackRequest.mUid, request.getRequestorPackageName())));
14651         }
14652         return callbackRequestsToRegister;
14653     }
14654 
14655     private static void setNetworkRequestUids(@NonNull final List<NetworkRequest> requests,
14656             @NonNull final Set<UidRange> uids) {
14657         for (final NetworkRequest req : requests) {
14658             req.networkCapabilities.setUids(UidRange.toIntRanges(uids));
14659         }
14660     }
14661 
14662     /**
14663      * Class used to generate {@link NetworkRequestInfo} based off of {@link OemNetworkPreferences}.
14664      */
14665     @VisibleForTesting
14666     final class OemNetworkRequestFactory {
14667         ArraySet<NetworkRequestInfo> createNrisFromOemNetworkPreferences(
14668                 @NonNull final OemNetworkPreferences preference) {
14669             final ArraySet<NetworkRequestInfo> nris = new ArraySet<>();
14670             final SparseArray<Set<Integer>> uids =
14671                     createUidsFromOemNetworkPreferences(preference);
14672             for (int i = 0; i < uids.size(); i++) {
14673                 final int key = uids.keyAt(i);
14674                 final Set<Integer> value = uids.valueAt(i);
14675                 final NetworkRequestInfo nri = createNriFromOemNetworkPreferences(key, value);
14676                 // No need to add an nri without any requests.
14677                 if (0 == nri.mRequests.size()) {
14678                     continue;
14679                 }
14680                 nris.add(nri);
14681             }
14682 
14683             return nris;
14684         }
14685 
14686         private SparseArray<Set<Integer>> createUidsFromOemNetworkPreferences(
14687                 @NonNull final OemNetworkPreferences preference) {
14688             final SparseArray<Set<Integer>> prefToUids = new SparseArray<>();
14689             final PackageManager pm = mContext.getPackageManager();
14690             final List<UserHandle> users =
14691                     mContext.getSystemService(UserManager.class).getUserHandles(true);
14692             if (null == users || users.size() == 0) {
14693                 if (VDBG || DDBG) {
14694                     log("No users currently available for setting the OEM network preference.");
14695                 }
14696                 return prefToUids;
14697             }
14698             for (final Map.Entry<String, Integer> entry :
14699                     preference.getNetworkPreferences().entrySet()) {
14700                 @OemNetworkPreferences.OemNetworkPreference final int pref = entry.getValue();
14701                 // Add the rules for all users as this policy is device wide.
14702                 for (final UserHandle user : users) {
14703                     try {
14704                         final int uid = pm.getApplicationInfoAsUser(entry.getKey(), 0, user).uid;
14705                         if (!prefToUids.contains(pref)) {
14706                             prefToUids.put(pref, new ArraySet<>());
14707                         }
14708                         prefToUids.get(pref).add(uid);
14709                     } catch (PackageManager.NameNotFoundException e) {
14710                         // Although this may seem like an error scenario, it is ok that uninstalled
14711                         // packages are sent on a network preference as the system will watch for
14712                         // package installations associated with this network preference and update
14713                         // accordingly. This is done to minimize race conditions on app install.
14714                         continue;
14715                     }
14716                 }
14717             }
14718             return prefToUids;
14719         }
14720 
14721         private NetworkRequestInfo createNriFromOemNetworkPreferences(
14722                 @OemNetworkPreferences.OemNetworkPreference final int preference,
14723                 @NonNull final Set<Integer> uids) {
14724             final List<NetworkRequest> requests = new ArrayList<>();
14725             // Requests will ultimately be evaluated by order of insertion therefore it matters.
14726             switch (preference) {
14727                 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID:
14728                     requests.add(createUnmeteredNetworkRequest());
14729                     requests.add(createOemPaidNetworkRequest());
14730                     requests.add(createDefaultInternetRequestForTransport(
14731                             TYPE_NONE, NetworkRequest.Type.TRACK_DEFAULT));
14732                     break;
14733                 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK:
14734                     requests.add(createUnmeteredNetworkRequest());
14735                     requests.add(createOemPaidNetworkRequest());
14736                     break;
14737                 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY:
14738                     requests.add(createOemPaidNetworkRequest());
14739                     break;
14740                 case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY:
14741                     requests.add(createOemPrivateNetworkRequest());
14742                     break;
14743                 case OEM_NETWORK_PREFERENCE_TEST:
14744                     requests.add(createUnmeteredNetworkRequest());
14745                     requests.add(createTestNetworkRequest());
14746                     requests.add(createDefaultRequest());
14747                     break;
14748                 case OEM_NETWORK_PREFERENCE_TEST_ONLY:
14749                     requests.add(createTestNetworkRequest());
14750                     break;
14751                 default:
14752                     // This should never happen.
14753                     throw new IllegalArgumentException("createNriFromOemNetworkPreferences()"
14754                             + " called with invalid preference of " + preference);
14755             }
14756 
14757             final ArraySet<UidRange> ranges = new ArraySet<>();
14758             for (final int uid : uids) {
14759                 ranges.add(new UidRange(uid, uid));
14760             }
14761             setNetworkRequestUids(requests, ranges);
14762             return new NetworkRequestInfo(Process.myUid(), requests, PREFERENCE_ORDER_OEM);
14763         }
14764 
14765         private NetworkRequest createUnmeteredNetworkRequest() {
14766             final NetworkCapabilities netcap = createDefaultPerAppNetCap()
14767                     .addCapability(NET_CAPABILITY_NOT_METERED)
14768                     .addCapability(NET_CAPABILITY_VALIDATED);
14769             return createNetworkRequest(NetworkRequest.Type.LISTEN, netcap);
14770         }
14771 
14772         private NetworkRequest createOemPaidNetworkRequest() {
14773             // NET_CAPABILITY_OEM_PAID is a restricted capability.
14774             final NetworkCapabilities netcap = createDefaultPerAppNetCap()
14775                     .addCapability(NET_CAPABILITY_OEM_PAID)
14776                     .removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
14777             return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
14778         }
14779 
14780         private NetworkRequest createOemPrivateNetworkRequest() {
14781             // NET_CAPABILITY_OEM_PRIVATE is a restricted capability.
14782             final NetworkCapabilities netcap = createDefaultPerAppNetCap()
14783                     .addCapability(NET_CAPABILITY_OEM_PRIVATE)
14784                     .removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
14785             return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
14786         }
14787 
14788         private NetworkCapabilities createDefaultPerAppNetCap() {
14789             final NetworkCapabilities netcap = new NetworkCapabilities();
14790             netcap.addCapability(NET_CAPABILITY_INTERNET);
14791             netcap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
14792             return netcap;
14793         }
14794 
14795         private NetworkRequest createTestNetworkRequest() {
14796             final NetworkCapabilities netcap = new NetworkCapabilities();
14797             netcap.clearAll();
14798             netcap.addTransportType(TRANSPORT_TEST);
14799             return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
14800         }
14801     }
14802 
14803     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
14804     @Override
14805     public void setDataSaverEnabled(final boolean enable) {
14806         enforceNetworkStackOrSettingsPermission();
14807         try {
14808             final boolean ret = mNetd.bandwidthEnableDataSaver(enable);
14809             if (!ret) {
14810                 throw new IllegalStateException("Error when changing iptables: " + enable);
14811             }
14812         } catch (RemoteException e) {
14813             // Lack of permission or binder errors.
14814             throw new IllegalStateException(e);
14815         }
14816 
14817         synchronized (mBlockedStatusTrackingUids) {
14818             try {
14819                 mBpfNetMaps.setDataSaverEnabled(enable);
14820             } catch (ServiceSpecificException | UnsupportedOperationException e) {
14821                 Log.e(TAG, "Failed to set data saver " + enable + " : " + e);
14822                 return;
14823             }
14824 
14825             if (shouldTrackUidsForBlockedStatusCallbacks()) {
14826                 updateTrackingUidsBlockedReasons();
14827             }
14828         }
14829     }
14830 
14831     private int setPackageFirewallRule(final int chain, final String packageName, final int rule)
14832             throws PackageManager.NameNotFoundException {
14833         final PackageManager pm = mContext.getPackageManager();
14834         final int appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0 /* flags */));
14835         if (appId < Process.FIRST_APPLICATION_UID) {
14836             throw new RuntimeException("Can't set package firewall rule for system app "
14837                     + packageName + " with appId " + appId);
14838         }
14839         for (final UserHandle uh : mUserManager.getUserHandles(false /* excludeDying */)) {
14840             final int uid = uh.getUid(appId);
14841             setUidFirewallRule(chain, uid, rule);
14842         }
14843         return appId;
14844     }
14845 
14846     @Override
14847     public void setUidFirewallRule(final int chain, final int uid, final int rule) {
14848         enforceNetworkStackOrSettingsPermission();
14849 
14850         if (chain == FIREWALL_CHAIN_BACKGROUND && !mBackgroundFirewallChainEnabled) {
14851             Log.i(TAG, "Ignoring operation setUidFirewallRule on the background chain because the"
14852                     + " feature is disabled.");
14853             return;
14854         }
14855 
14856         // There are only two type of firewall rule: FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY
14857         int firewallRule = getFirewallRuleType(chain, rule);
14858 
14859         if (firewallRule != FIREWALL_RULE_ALLOW && firewallRule != FIREWALL_RULE_DENY) {
14860             throw new IllegalArgumentException("setUidFirewallRule with invalid rule: " + rule);
14861         }
14862 
14863         synchronized (mBlockedStatusTrackingUids) {
14864             try {
14865                 mBpfNetMaps.setUidRule(chain, uid, firewallRule);
14866             } catch (ServiceSpecificException e) {
14867                 throw new IllegalStateException(e);
14868             }
14869             if (shouldTrackUidsForBlockedStatusCallbacks()
14870                     && mBlockedStatusTrackingUids.get(uid, 0) != 0) {
14871                 mHandler.sendMessage(mHandler.obtainMessage(EVENT_BLOCKED_REASONS_CHANGED,
14872                         List.of(new Pair<>(uid, mBpfNetMaps.getUidNetworkingBlockedReasons(uid)))));
14873             }
14874             if (shouldTrackFirewallDestroySocketReasons()) {
14875                 maybePostFirewallDestroySocketReasons(chain, Set.of(uid));
14876             }
14877         }
14878     }
14879 
14880     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
14881     private int getPackageFirewallRule(final int chain, final String packageName)
14882             throws PackageManager.NameNotFoundException {
14883         final PackageManager pm = mContext.getPackageManager();
14884         final int appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0 /* flags */));
14885         return getUidFirewallRule(chain, appId);
14886     }
14887 
14888     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
14889     @Override
14890     public int getUidFirewallRule(final int chain, final int uid) {
14891         enforceNetworkStackOrSettingsPermission();
14892         return mBpfNetMaps.getUidRule(chain, uid);
14893     }
14894 
14895     private int getFirewallRuleType(int chain, int rule) {
14896         final int defaultRule;
14897         switch (chain) {
14898             case ConnectivityManager.FIREWALL_CHAIN_STANDBY:
14899             case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1:
14900             case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_2:
14901             case ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3:
14902             case ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER:
14903             case ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN:
14904                 defaultRule = FIREWALL_RULE_ALLOW;
14905                 break;
14906             case ConnectivityManager.FIREWALL_CHAIN_DOZABLE:
14907             case ConnectivityManager.FIREWALL_CHAIN_POWERSAVE:
14908             case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED:
14909             case ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY:
14910             case ConnectivityManager.FIREWALL_CHAIN_BACKGROUND:
14911             case ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW:
14912                 defaultRule = FIREWALL_RULE_DENY;
14913                 break;
14914             default:
14915                 throw new IllegalArgumentException("Unsupported firewall chain: " + chain);
14916         }
14917         if (rule == FIREWALL_RULE_DEFAULT) rule = defaultRule;
14918 
14919         return rule;
14920     }
14921 
14922     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
14923     private Set<Integer> getUidsOnFirewallChain(final int chain) throws ErrnoException {
14924         if (BpfNetMapsUtils.isFirewallAllowList(chain)) {
14925             return mBpfNetMaps.getUidsWithAllowRuleOnAllowListChain(chain);
14926         } else {
14927             return mBpfNetMaps.getUidsWithDenyRuleOnDenyListChain(chain);
14928         }
14929     }
14930 
14931     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
14932     private void closeSocketsForFirewallChainLocked(final int chain)
14933             throws ErrnoException, SocketException, InterruptedIOException {
14934         final Set<Integer> uidsOnChain = getUidsOnFirewallChain(chain);
14935         if (BpfNetMapsUtils.isFirewallAllowList(chain)) {
14936             // Allowlist means the firewall denies all by default, uids must be explicitly allowed
14937             // So, close all non-system socket owned by uids that are not explicitly allowed
14938             Set<Range<Integer>> ranges = new ArraySet<>();
14939             ranges.add(new Range<>(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE));
14940             mDeps.destroyLiveTcpSockets(ranges, uidsOnChain /* exemptUids */);
14941         } else {
14942             // Denylist means the firewall allows all by default, uids must be explicitly denied
14943             // So, close socket owned by uids that are explicitly denied
14944             mDeps.destroyLiveTcpSocketsByOwnerUids(uidsOnChain /* ownerUids */);
14945         }
14946     }
14947 
14948     private void maybePostClearFirewallDestroySocketReasons(int chain) {
14949         if (chain != FIREWALL_CHAIN_BACKGROUND) {
14950             // TODO (b/300681644): Support other firewall chains
14951             return;
14952         }
14953         mHandler.sendMessage(mHandler.obtainMessage(EVENT_CLEAR_FIREWALL_DESTROY_SOCKET_REASONS,
14954                 DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND, 0 /* arg2 */));
14955     }
14956 
14957     @Override
14958     public void setFirewallChainEnabled(final int chain, final boolean enable) {
14959         enforceNetworkStackOrSettingsPermission();
14960 
14961         if (chain == FIREWALL_CHAIN_BACKGROUND && !mBackgroundFirewallChainEnabled) {
14962             Log.i(TAG, "Ignoring operation setFirewallChainEnabled on the background chain because"
14963                     + " the feature is disabled.");
14964             return;
14965         }
14966         if (METERED_ALLOW_CHAINS.contains(chain) || METERED_DENY_CHAINS.contains(chain)) {
14967             // Metered chains are used from a separate bpf program that is triggered by iptables
14968             // and can not be controlled by setFirewallChainEnabled.
14969             throw new UnsupportedOperationException(
14970                     "Chain (" + chain + ") can not be controlled by setFirewallChainEnabled");
14971         }
14972 
14973         synchronized (mBlockedStatusTrackingUids) {
14974             try {
14975                 mBpfNetMaps.setChildChain(chain, enable);
14976             } catch (ServiceSpecificException e) {
14977                 throw new IllegalStateException(e);
14978             }
14979             if (shouldTrackUidsForBlockedStatusCallbacks()) {
14980                 updateTrackingUidsBlockedReasons();
14981             }
14982             if (shouldTrackFirewallDestroySocketReasons() && !enable) {
14983                 // Clear destroy socket reasons so that CS does not destroy sockets of apps that
14984                 // have network access.
14985                 maybePostClearFirewallDestroySocketReasons(chain);
14986             }
14987         }
14988 
14989         if (mDeps.isAtLeastU() && enable) {
14990             try {
14991                 closeSocketsForFirewallChainLocked(chain);
14992             } catch (ErrnoException | SocketException | InterruptedIOException e) {
14993                 Log.e(TAG, "Failed to close sockets after enabling chain (" + chain + "): " + e);
14994             }
14995         }
14996     }
14997 
14998     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
14999     @GuardedBy("mBlockedStatusTrackingUids")
15000     private void updateTrackingUidsBlockedReasons() {
15001         if (mBlockedStatusTrackingUids.size() == 0) {
15002             return;
15003         }
15004         final ArrayList<Pair<Integer, Integer>> uidBlockedReasonsList = new ArrayList<>();
15005         for (int i = 0; i < mBlockedStatusTrackingUids.size(); i++) {
15006             final int uid = mBlockedStatusTrackingUids.keyAt(i);
15007             uidBlockedReasonsList.add(
15008                     new Pair<>(uid, mBpfNetMaps.getUidNetworkingBlockedReasons(uid)));
15009         }
15010         mHandler.sendMessage(mHandler.obtainMessage(EVENT_BLOCKED_REASONS_CHANGED,
15011                 uidBlockedReasonsList));
15012     }
15013 
15014     private int getFirewallDestroySocketReasons(final int blockedReasons) {
15015         int destroySocketReasons = DESTROY_SOCKET_REASON_NONE;
15016         if ((blockedReasons & BLOCKED_REASON_APP_BACKGROUND) != BLOCKED_REASON_NONE) {
15017             destroySocketReasons |= DESTROY_SOCKET_REASON_FIREWALL_BACKGROUND;
15018         }
15019         return destroySocketReasons;
15020     }
15021 
15022     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
15023     @GuardedBy("mBlockedStatusTrackingUids")
15024     private void maybePostFirewallDestroySocketReasons(int chain, Set<Integer> uids) {
15025         if (chain != FIREWALL_CHAIN_BACKGROUND) {
15026             // TODO (b/300681644): Support other firewall chains
15027             return;
15028         }
15029         final ArrayList<Pair<Integer, Integer>> reasonsList = new ArrayList<>();
15030         for (int uid: uids) {
15031             final int blockedReasons = mBpfNetMaps.getUidNetworkingBlockedReasons(uid);
15032             final int destroySocketReaons = getFirewallDestroySocketReasons(blockedReasons);
15033             reasonsList.add(new Pair<>(uid, destroySocketReaons));
15034         }
15035         mHandler.sendMessage(mHandler.obtainMessage(EVENT_UPDATE_FIREWALL_DESTROY_SOCKET_REASONS,
15036                 reasonsList));
15037     }
15038 
15039     @Override
15040     public boolean getFirewallChainEnabled(final int chain) {
15041         enforceNetworkStackOrSettingsPermission();
15042 
15043         if (METERED_ALLOW_CHAINS.contains(chain) || METERED_DENY_CHAINS.contains(chain)) {
15044             // Metered chains are used from a separate bpf program that is triggered by iptables
15045             // and can not be controlled by setFirewallChainEnabled.
15046             throw new UnsupportedOperationException(
15047                     "getFirewallChainEnabled can not return status of chain (" + chain + ")");
15048         }
15049 
15050         return mBpfNetMaps.isChainEnabled(chain);
15051     }
15052 
15053     @Override
15054     public void replaceFirewallChain(final int chain, final int[] uids) {
15055         enforceNetworkStackOrSettingsPermission();
15056 
15057         if (chain == FIREWALL_CHAIN_BACKGROUND && !mBackgroundFirewallChainEnabled) {
15058             Log.i(TAG, "Ignoring operation replaceFirewallChain on the background chain because"
15059                     + " the feature is disabled.");
15060             return;
15061         }
15062 
15063         synchronized (mBlockedStatusTrackingUids) {
15064             // replaceFirewallChain removes uids that are currently on the chain and put |uids| on
15065             // the chain.
15066             // So this method could change blocked reasons of uids that are currently on chain +
15067             // |uids|.
15068             final Set<Integer> affectedUids = new ArraySet<>();
15069             if (shouldTrackFirewallDestroySocketReasons()) {
15070                 try {
15071                     affectedUids.addAll(getUidsOnFirewallChain(chain));
15072                 } catch (ErrnoException e) {
15073                     Log.e(TAG, "Failed to get uids on chain(" + chain + "): " + e);
15074                 }
15075                 for (final int uid: uids) {
15076                     affectedUids.add(uid);
15077                 }
15078             }
15079 
15080             mBpfNetMaps.replaceUidChain(chain, uids);
15081             if (shouldTrackUidsForBlockedStatusCallbacks()) {
15082                 updateTrackingUidsBlockedReasons();
15083             }
15084             if (shouldTrackFirewallDestroySocketReasons()) {
15085                 maybePostFirewallDestroySocketReasons(chain, affectedUids);
15086             }
15087         }
15088     }
15089 
15090     @Override
15091     public IBinder getCompanionDeviceManagerProxyService() {
15092         enforceNetworkStackPermission(mContext);
15093         return mCdmps;
15094     }
15095 
15096     @Override
15097     public IBinder getRoutingCoordinatorService() {
15098         enforceNetworkStackPermission(mContext);
15099         return mRoutingCoordinatorService;
15100     }
15101 
15102     @Override
15103     public long getEnabledConnectivityManagerFeatures() {
15104         long features = 0;
15105         // The bitmask must be built based on final properties initialized in the constructor, to
15106         // ensure that it does not change over time and is always consistent between
15107         // ConnectivityManager and ConnectivityService.
15108         if (mUseDeclaredMethodsForCallbacksEnabled) {
15109             features |= ConnectivityManager.FEATURE_USE_DECLARED_METHODS_FOR_CALLBACKS;
15110         }
15111         if (mQueueNetworkAgentEventsInSystemServer) {
15112             features |= ConnectivityManager.FEATURE_QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER;
15113         }
15114         return features;
15115     }
15116 
15117     @Override
15118     public boolean isConnectivityServiceFeatureEnabledForTesting(String featureFlag) {
15119         switch (featureFlag) {
15120             case INGRESS_TO_VPN_ADDRESS_FILTERING:
15121                 return mIngressToVpnAddressFiltering;
15122             case QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER:
15123                 return mQueueNetworkAgentEventsInSystemServer;
15124             default:
15125                 throw new IllegalArgumentException("Unknown flag: " + featureFlag);
15126         }
15127     }
15128 }
15129