1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server;
18 
19 import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
20 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
22 import static android.net.ConnectivityManager.NETID_UNSET;
23 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
24 import static android.net.ConnectivityManager.TYPE_ETHERNET;
25 import static android.net.ConnectivityManager.TYPE_NONE;
26 import static android.net.ConnectivityManager.TYPE_VPN;
27 import static android.net.ConnectivityManager.getNetworkTypeName;
28 import static android.net.ConnectivityManager.isNetworkTypeValid;
29 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
30 import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
31 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
32 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
33 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
34 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
35 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
36 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
37 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
38 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
39 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
40 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
41 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
42 import static android.net.NetworkPolicyManager.RULE_NONE;
43 import static android.net.NetworkPolicyManager.uidRulesToString;
44 import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired;
45 import static android.os.Process.INVALID_UID;
46 import static android.system.OsConstants.IPPROTO_TCP;
47 import static android.system.OsConstants.IPPROTO_UDP;
48 
49 import static com.android.internal.util.Preconditions.checkNotNull;
50 
51 import android.annotation.NonNull;
52 import android.annotation.Nullable;
53 import android.app.BroadcastOptions;
54 import android.app.NotificationManager;
55 import android.app.PendingIntent;
56 import android.content.BroadcastReceiver;
57 import android.content.ContentResolver;
58 import android.content.Context;
59 import android.content.Intent;
60 import android.content.IntentFilter;
61 import android.content.res.Configuration;
62 import android.database.ContentObserver;
63 import android.net.CaptivePortal;
64 import android.net.ConnectionInfo;
65 import android.net.ConnectivityManager;
66 import android.net.ICaptivePortal;
67 import android.net.IConnectivityManager;
68 import android.net.IDnsResolver;
69 import android.net.IIpConnectivityMetrics;
70 import android.net.INetd;
71 import android.net.INetdEventCallback;
72 import android.net.INetworkManagementEventObserver;
73 import android.net.INetworkMonitor;
74 import android.net.INetworkMonitorCallbacks;
75 import android.net.INetworkPolicyListener;
76 import android.net.INetworkPolicyManager;
77 import android.net.INetworkStatsService;
78 import android.net.ISocketKeepaliveCallback;
79 import android.net.ITetheringEventCallback;
80 import android.net.InetAddresses;
81 import android.net.IpMemoryStore;
82 import android.net.IpPrefix;
83 import android.net.LinkProperties;
84 import android.net.LinkProperties.CompareResult;
85 import android.net.MatchAllNetworkSpecifier;
86 import android.net.NattSocketKeepalive;
87 import android.net.Network;
88 import android.net.NetworkAgent;
89 import android.net.NetworkCapabilities;
90 import android.net.NetworkConfig;
91 import android.net.NetworkFactory;
92 import android.net.NetworkInfo;
93 import android.net.NetworkInfo.DetailedState;
94 import android.net.NetworkMisc;
95 import android.net.NetworkMonitorManager;
96 import android.net.NetworkPolicyManager;
97 import android.net.NetworkQuotaInfo;
98 import android.net.NetworkRequest;
99 import android.net.NetworkSpecifier;
100 import android.net.NetworkStack;
101 import android.net.NetworkStackClient;
102 import android.net.NetworkState;
103 import android.net.NetworkUtils;
104 import android.net.NetworkWatchlistManager;
105 import android.net.PrivateDnsConfigParcel;
106 import android.net.ProxyInfo;
107 import android.net.RouteInfo;
108 import android.net.SocketKeepalive;
109 import android.net.UidRange;
110 import android.net.Uri;
111 import android.net.VpnService;
112 import android.net.metrics.IpConnectivityLog;
113 import android.net.metrics.NetworkEvent;
114 import android.net.netlink.InetDiagMessage;
115 import android.net.shared.PrivateDnsConfig;
116 import android.net.util.MultinetworkPolicyTracker;
117 import android.net.util.NetdService;
118 import android.os.Binder;
119 import android.os.Build;
120 import android.os.Bundle;
121 import android.os.Handler;
122 import android.os.HandlerThread;
123 import android.os.IBinder;
124 import android.os.INetworkManagementService;
125 import android.os.Looper;
126 import android.os.Message;
127 import android.os.Messenger;
128 import android.os.ParcelFileDescriptor;
129 import android.os.Parcelable;
130 import android.os.PowerManager;
131 import android.os.Process;
132 import android.os.RemoteException;
133 import android.os.ResultReceiver;
134 import android.os.ServiceManager;
135 import android.os.ServiceSpecificException;
136 import android.os.ShellCallback;
137 import android.os.ShellCommand;
138 import android.os.SystemClock;
139 import android.os.SystemProperties;
140 import android.os.UserHandle;
141 import android.os.UserManager;
142 import android.provider.Settings;
143 import android.security.Credentials;
144 import android.security.KeyStore;
145 import android.telephony.TelephonyManager;
146 import android.text.TextUtils;
147 import android.util.ArraySet;
148 import android.util.LocalLog;
149 import android.util.Log;
150 import android.util.Pair;
151 import android.util.Slog;
152 import android.util.SparseArray;
153 import android.util.SparseBooleanArray;
154 import android.util.SparseIntArray;
155 import android.util.Xml;
156 
157 import com.android.internal.R;
158 import com.android.internal.annotations.GuardedBy;
159 import com.android.internal.annotations.VisibleForTesting;
160 import com.android.internal.app.IBatteryStats;
161 import com.android.internal.logging.MetricsLogger;
162 import com.android.internal.net.LegacyVpnInfo;
163 import com.android.internal.net.VpnConfig;
164 import com.android.internal.net.VpnInfo;
165 import com.android.internal.net.VpnProfile;
166 import com.android.internal.util.ArrayUtils;
167 import com.android.internal.util.AsyncChannel;
168 import com.android.internal.util.DumpUtils;
169 import com.android.internal.util.IndentingPrintWriter;
170 import com.android.internal.util.MessageUtils;
171 import com.android.internal.util.WakeupMessage;
172 import com.android.internal.util.XmlUtils;
173 import com.android.server.am.BatteryStatsService;
174 import com.android.server.connectivity.AutodestructReference;
175 import com.android.server.connectivity.DataConnectionStats;
176 import com.android.server.connectivity.DnsManager;
177 import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
178 import com.android.server.connectivity.IpConnectivityMetrics;
179 import com.android.server.connectivity.KeepaliveTracker;
180 import com.android.server.connectivity.LingerMonitor;
181 import com.android.server.connectivity.MockableSystemProperties;
182 import com.android.server.connectivity.MultipathPolicyTracker;
183 import com.android.server.connectivity.NetworkAgentInfo;
184 import com.android.server.connectivity.NetworkDiagnostics;
185 import com.android.server.connectivity.NetworkNotificationManager;
186 import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
187 import com.android.server.connectivity.PermissionMonitor;
188 import com.android.server.connectivity.ProxyTracker;
189 import com.android.server.connectivity.Tethering;
190 import com.android.server.connectivity.Vpn;
191 import com.android.server.connectivity.tethering.TetheringDependencies;
192 import com.android.server.net.BaseNetdEventCallback;
193 import com.android.server.net.BaseNetworkObserver;
194 import com.android.server.net.LockdownVpnTracker;
195 import com.android.server.net.NetworkPolicyManagerInternal;
196 import com.android.server.utils.PriorityDump;
197 
198 import com.google.android.collect.Lists;
199 
200 import org.xmlpull.v1.XmlPullParser;
201 import org.xmlpull.v1.XmlPullParserException;
202 
203 import java.io.File;
204 import java.io.FileDescriptor;
205 import java.io.FileNotFoundException;
206 import java.io.FileReader;
207 import java.io.IOException;
208 import java.io.PrintWriter;
209 import java.net.Inet4Address;
210 import java.net.InetAddress;
211 import java.net.UnknownHostException;
212 import java.util.ArrayList;
213 import java.util.Arrays;
214 import java.util.Collection;
215 import java.util.Comparator;
216 import java.util.ConcurrentModificationException;
217 import java.util.HashMap;
218 import java.util.HashSet;
219 import java.util.List;
220 import java.util.Map;
221 import java.util.Objects;
222 import java.util.Set;
223 import java.util.SortedSet;
224 import java.util.TreeSet;
225 
226 /**
227  * @hide
228  */
229 public class ConnectivityService extends IConnectivityManager.Stub
230         implements PendingIntent.OnFinished {
231     private static final String TAG = ConnectivityService.class.getSimpleName();
232 
233     private static final String DIAG_ARG = "--diag";
234     public static final String SHORT_ARG = "--short";
235     private static final String TETHERING_ARG = "tethering";
236     private static final String NETWORK_ARG = "networks";
237     private static final String REQUEST_ARG = "requests";
238 
239     private static final boolean DBG = true;
240     private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG);
241     private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
242 
243     private static final boolean LOGD_BLOCKED_NETWORKINFO = true;
244 
245     /**
246      * Default URL to use for {@link #getCaptivePortalServerUrl()}. This should not be changed
247      * by OEMs for configuration purposes, as this value is overridden by
248      * Settings.Global.CAPTIVE_PORTAL_HTTP_URL.
249      * R.string.config_networkCaptivePortalServerUrl should be overridden instead for this purpose
250      * (preferably via runtime resource overlays).
251      */
252     private static final String DEFAULT_CAPTIVE_PORTAL_HTTP_URL =
253             "http://connectivitycheck.gstatic.com/generate_204";
254 
255     // TODO: create better separation between radio types and network types
256 
257     // how long to wait before switching back to a radio's default network
258     private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000;
259     // system property that can override the above value
260     private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
261             "android.telephony.apn-restore";
262 
263     // How long to wait before putting up a "This network doesn't have an Internet connection,
264     // connect anyway?" dialog after the user selects a network that doesn't validate.
265     private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000;
266 
267     // How long to dismiss network notification.
268     private static final int TIMEOUT_NOTIFICATION_DELAY_MS = 20 * 1000;
269 
270     // Default to 30s linger time-out. Modifiable only for testing.
271     private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger";
272     private static final int DEFAULT_LINGER_DELAY_MS = 30_000;
273     @VisibleForTesting
274     protected int mLingerDelayMs;  // Can't be final, or test subclass constructors can't change it.
275 
276     // How long to delay to removal of a pending intent based request.
277     // See Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS
278     private final int mReleasePendingIntentDelayMs;
279 
280     private MockableSystemProperties mSystemProperties;
281 
282     private Tethering mTethering;
283 
284     @VisibleForTesting
285     protected final PermissionMonitor mPermissionMonitor;
286 
287     private KeyStore mKeyStore;
288 
289     @VisibleForTesting
290     @GuardedBy("mVpns")
291     protected final SparseArray<Vpn> mVpns = new SparseArray<>();
292 
293     // TODO: investigate if mLockdownEnabled can be removed and replaced everywhere by
294     // a direct call to LockdownVpnTracker.isEnabled().
295     @GuardedBy("mVpns")
296     private boolean mLockdownEnabled;
297     @GuardedBy("mVpns")
298     private LockdownVpnTracker mLockdownTracker;
299 
300     /**
301      * Stale copy of uid rules provided by NPMS. As long as they are accessed only in internal
302      * handler thread, they don't need a lock.
303      */
304     private SparseIntArray mUidRules = new SparseIntArray();
305     /** Flag indicating if background data is restricted. */
306     private boolean mRestrictBackground;
307 
308     final private Context mContext;
309     // 0 is full bad, 100 is full good
310     private int mDefaultInetConditionPublished = 0;
311 
312     private INetworkManagementService mNMS;
313     @VisibleForTesting
314     protected IDnsResolver mDnsResolver;
315     @VisibleForTesting
316     protected INetd mNetd;
317     private INetworkStatsService mStatsService;
318     private INetworkPolicyManager mPolicyManager;
319     private NetworkPolicyManagerInternal mPolicyManagerInternal;
320 
321     /**
322      * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple
323      * instances.
324      */
325     @GuardedBy("mTNSLock")
326     private TestNetworkService mTNS;
327 
328     private final Object mTNSLock = new Object();
329 
330     private String mCurrentTcpBufferSizes;
331 
332     private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(
333             new Class[] { AsyncChannel.class, ConnectivityService.class, NetworkAgent.class,
334                     NetworkAgentInfo.class });
335 
336     private enum ReapUnvalidatedNetworks {
337         // Tear down networks that have no chance (e.g. even if validated) of becoming
338         // the highest scoring network satisfying a NetworkRequest.  This should be passed when
339         // all networks have been rematched against all NetworkRequests.
340         REAP,
341         // Don't reap networks.  This should be passed when some networks have not yet been
342         // rematched against all NetworkRequests.
343         DONT_REAP
344     }
345 
346     private enum UnneededFor {
347         LINGER,    // Determine whether this network is unneeded and should be lingered.
348         TEARDOWN,  // Determine whether this network is unneeded and should be torn down.
349     }
350 
351     /**
352      * used internally to clear a wakelock when transitioning
353      * from one net to another.  Clear happens when we get a new
354      * network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens
355      * after a timeout if no network is found (typically 1 min).
356      */
357     private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8;
358 
359     /**
360      * used internally to reload global proxy settings
361      */
362     private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9;
363 
364     /**
365      * PAC manager has received new port.
366      */
367     private static final int EVENT_PROXY_HAS_CHANGED = 16;
368 
369     /**
370      * used internally when registering NetworkFactories
371      * obj = NetworkFactoryInfo
372      */
373     private static final int EVENT_REGISTER_NETWORK_FACTORY = 17;
374 
375     /**
376      * used internally when registering NetworkAgents
377      * obj = Messenger
378      */
379     private static final int EVENT_REGISTER_NETWORK_AGENT = 18;
380 
381     /**
382      * used to add a network request
383      * includes a NetworkRequestInfo
384      */
385     private static final int EVENT_REGISTER_NETWORK_REQUEST = 19;
386 
387     /**
388      * indicates a timeout period is over - check if we had a network yet or not
389      * and if not, call the timeout callback (but leave the request live until they
390      * cancel it.
391      * includes a NetworkRequestInfo
392      */
393     private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20;
394 
395     /**
396      * used to add a network listener - no request
397      * includes a NetworkRequestInfo
398      */
399     private static final int EVENT_REGISTER_NETWORK_LISTENER = 21;
400 
401     /**
402      * used to remove a network request, either a listener or a real request
403      * arg1 = UID of caller
404      * obj  = NetworkRequest
405      */
406     private static final int EVENT_RELEASE_NETWORK_REQUEST = 22;
407 
408     /**
409      * used internally when registering NetworkFactories
410      * obj = Messenger
411      */
412     private static final int EVENT_UNREGISTER_NETWORK_FACTORY = 23;
413 
414     /**
415      * used internally to expire a wakelock when transitioning
416      * from one net to another.  Expire happens when we fail to find
417      * a new network (typically after 1 minute) -
418      * EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found
419      * a replacement network.
420      */
421     private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24;
422 
423     /**
424      * Used internally to indicate the system is ready.
425      */
426     private static final int EVENT_SYSTEM_READY = 25;
427 
428     /**
429      * used to add a network request with a pending intent
430      * obj = NetworkRequestInfo
431      */
432     private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26;
433 
434     /**
435      * used to remove a pending intent and its associated network request.
436      * arg1 = UID of caller
437      * obj  = PendingIntent
438      */
439     private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27;
440 
441     /**
442      * used to specify whether a network should be used even if unvalidated.
443      * arg1 = whether to accept the network if it's unvalidated (1 or 0)
444      * arg2 = whether to remember this choice in the future (1 or 0)
445      * obj  = network
446      */
447     private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28;
448 
449     /**
450      * used to ask the user to confirm a connection to an unvalidated network.
451      * obj  = network
452      */
453     private static final int EVENT_PROMPT_UNVALIDATED = 29;
454 
455     /**
456      * used internally to (re)configure always-on networks.
457      */
458     private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30;
459 
460     /**
461      * used to add a network listener with a pending intent
462      * obj = NetworkRequestInfo
463      */
464     private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
465 
466     /**
467      * used to specify whether a network should not be penalized when it becomes unvalidated.
468      */
469     private static final int EVENT_SET_AVOID_UNVALIDATED = 35;
470 
471     /**
472      * used to trigger revalidation of a network.
473      */
474     private static final int EVENT_REVALIDATE_NETWORK = 36;
475 
476     // Handle changes in Private DNS settings.
477     private static final int EVENT_PRIVATE_DNS_SETTINGS_CHANGED = 37;
478 
479     // Handle private DNS validation status updates.
480     private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
481 
482     /**
483      * Used to handle onUidRulesChanged event from NetworkPolicyManagerService.
484      */
485     private static final int EVENT_UID_RULES_CHANGED = 39;
486 
487     /**
488      * Used to handle onRestrictBackgroundChanged event from NetworkPolicyManagerService.
489      */
490     private static final int EVENT_DATA_SAVER_CHANGED = 40;
491 
492      /**
493       * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the network has
494       * been tested.
495       * obj = String representing URL that Internet probe was redirect to, if it was redirected.
496       * arg1 = One of the NETWORK_TESTED_RESULT_* constants.
497       * arg2 = NetID.
498       */
499     public static final int EVENT_NETWORK_TESTED = 41;
500 
501     /**
502      * Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the private DNS
503      * config was resolved.
504      * obj = PrivateDnsConfig
505      * arg2 = netid
506      */
507     public static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42;
508 
509     /**
510      * Request ConnectivityService display provisioning notification.
511      * arg1    = Whether to make the notification visible.
512      * arg2    = NetID.
513      * obj     = Intent to be launched when notification selected by user, null if !arg1.
514      */
515     public static final int EVENT_PROVISIONING_NOTIFICATION = 43;
516 
517     /**
518      * This event can handle dismissing notification by given network id.
519      */
520     public static final int EVENT_TIMEOUT_NOTIFICATION = 44;
521 
522     /**
523      * Used to specify whether a network should be used even if connectivity is partial.
524      * arg1 = whether to accept the network if its connectivity is partial (1 for true or 0 for
525      * false)
526      * arg2 = whether to remember this choice in the future (1 for true or 0 for false)
527      * obj  = network
528      */
529     private static final int EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY = 45;
530 
531     /**
532      * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
533      * should be shown.
534      */
535     public static final int PROVISIONING_NOTIFICATION_SHOW = 1;
536 
537     /**
538      * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
539      * should be hidden.
540      */
541     public static final int PROVISIONING_NOTIFICATION_HIDE = 0;
542 
eventName(int what)543     private static String eventName(int what) {
544         return sMagicDecoderRing.get(what, Integer.toString(what));
545     }
546 
getDnsResolver()547     private static IDnsResolver getDnsResolver() {
548         return IDnsResolver.Stub
549                 .asInterface(ServiceManager.getService("dnsresolver"));
550     }
551 
552     /** Handler thread used for both of the handlers below. */
553     @VisibleForTesting
554     protected final HandlerThread mHandlerThread;
555     /** Handler used for internal events. */
556     final private InternalHandler mHandler;
557     /** Handler used for incoming {@link NetworkStateTracker} events. */
558     final private NetworkStateTrackerHandler mTrackerHandler;
559     private final DnsManager mDnsManager;
560 
561     private boolean mSystemReady;
562     private Intent mInitialBroadcast;
563 
564     private PowerManager.WakeLock mNetTransitionWakeLock;
565     private int mNetTransitionWakeLockTimeout;
566     private final PowerManager.WakeLock mPendingIntentWakeLock;
567 
568     // A helper object to track the current default HTTP proxy. ConnectivityService needs to tell
569     // the world when it changes.
570     @VisibleForTesting
571     protected final ProxyTracker mProxyTracker;
572 
573     final private SettingsObserver mSettingsObserver;
574 
575     private UserManager mUserManager;
576 
577     private NetworkConfig[] mNetConfigs;
578     private int mNetworksDefined;
579 
580     // the set of network types that can only be enabled by system/sig apps
581     private List mProtectedNetworks;
582 
583     private TelephonyManager mTelephonyManager;
584 
585     private KeepaliveTracker mKeepaliveTracker;
586     private NetworkNotificationManager mNotifier;
587     private LingerMonitor mLingerMonitor;
588 
589     // sequence number for Networks; keep in sync with system/netd/NetworkController.cpp
590     private static final int MIN_NET_ID = 100; // some reserved marks
591     private static final int MAX_NET_ID = 65535 - 0x0400; // Top 1024 bits reserved by IpSecService
592     private int mNextNetId = MIN_NET_ID;
593 
594     // sequence number of NetworkRequests
595     private int mNextNetworkRequestId = 1;
596 
597     // NetworkRequest activity String log entries.
598     private static final int MAX_NETWORK_REQUEST_LOGS = 20;
599     private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS);
600 
601     // NetworkInfo blocked and unblocked String log entries
602     private static final int MAX_NETWORK_INFO_LOGS = 40;
603     private final LocalLog mNetworkInfoBlockingLogs = new LocalLog(MAX_NETWORK_INFO_LOGS);
604 
605     private static final int MAX_WAKELOCK_LOGS = 20;
606     private final LocalLog mWakelockLogs = new LocalLog(MAX_WAKELOCK_LOGS);
607     private int mTotalWakelockAcquisitions = 0;
608     private int mTotalWakelockReleases = 0;
609     private long mTotalWakelockDurationMs = 0;
610     private long mMaxWakelockDurationMs = 0;
611     private long mLastWakeLockAcquireTimestamp = 0;
612 
613     private final IpConnectivityLog mMetricsLog;
614 
615     @GuardedBy("mBandwidthRequests")
616     private final SparseArray<Integer> mBandwidthRequests = new SparseArray(10);
617 
618     @VisibleForTesting
619     final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
620 
621     @VisibleForTesting
622     final MultipathPolicyTracker mMultipathPolicyTracker;
623 
624     /**
625      * Implements support for the legacy "one network per network type" model.
626      *
627      * We used to have a static array of NetworkStateTrackers, one for each
628      * network type, but that doesn't work any more now that we can have,
629      * for example, more that one wifi network. This class stores all the
630      * NetworkAgentInfo objects that support a given type, but the legacy
631      * API will only see the first one.
632      *
633      * It serves two main purposes:
634      *
635      * 1. Provide information about "the network for a given type" (since this
636      *    API only supports one).
637      * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if
638      *    the first network for a given type changes, or if the default network
639      *    changes.
640      */
641     @VisibleForTesting
642     static class LegacyTypeTracker {
643 
644         private static final boolean DBG = true;
645         private static final boolean VDBG = false;
646 
647         /**
648          * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS).
649          * Each list holds references to all NetworkAgentInfos that are used to
650          * satisfy requests for that network type.
651          *
652          * This array is built out at startup such that an unsupported network
653          * doesn't get an ArrayList instance, making this a tristate:
654          * unsupported, supported but not active and active.
655          *
656          * The actual lists are populated when we scan the network types that
657          * are supported on this device.
658          *
659          * Threading model:
660          *  - addSupportedType() is only called in the constructor
661          *  - add(), update(), remove() are only called from the ConnectivityService handler thread.
662          *    They are therefore not thread-safe with respect to each other.
663          *  - getNetworkForType() can be called at any time on binder threads. It is synchronized
664          *    on mTypeLists to be thread-safe with respect to a concurrent remove call.
665          *  - dump is thread-safe with respect to concurrent add and remove calls.
666          */
667         private final ArrayList<NetworkAgentInfo> mTypeLists[];
668         @NonNull
669         private final ConnectivityService mService;
670 
LegacyTypeTracker(@onNull ConnectivityService service)671         LegacyTypeTracker(@NonNull ConnectivityService service) {
672             mService = service;
673             mTypeLists = new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
674         }
675 
addSupportedType(int type)676         public void addSupportedType(int type) {
677             if (mTypeLists[type] != null) {
678                 throw new IllegalStateException(
679                         "legacy list for type " + type + "already initialized");
680             }
681             mTypeLists[type] = new ArrayList<>();
682         }
683 
isTypeSupported(int type)684         public boolean isTypeSupported(int type) {
685             return isNetworkTypeValid(type) && mTypeLists[type] != null;
686         }
687 
getNetworkForType(int type)688         public NetworkAgentInfo getNetworkForType(int type) {
689             synchronized (mTypeLists) {
690                 if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) {
691                     return mTypeLists[type].get(0);
692                 }
693             }
694             return null;
695         }
696 
maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, boolean isDefaultNetwork)697         private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type,
698                 boolean isDefaultNetwork) {
699             if (DBG) {
700                 log("Sending " + state +
701                         " broadcast for type " + type + " " + nai.name() +
702                         " isDefaultNetwork=" + isDefaultNetwork);
703             }
704         }
705 
706         /** Adds the given network to the specified legacy type list. */
add(int type, NetworkAgentInfo nai)707         public void add(int type, NetworkAgentInfo nai) {
708             if (!isTypeSupported(type)) {
709                 return;  // Invalid network type.
710             }
711             if (VDBG) log("Adding agent " + nai + " for legacy network type " + type);
712 
713             ArrayList<NetworkAgentInfo> list = mTypeLists[type];
714             if (list.contains(nai)) {
715                 return;
716             }
717             synchronized (mTypeLists) {
718                 list.add(nai);
719             }
720 
721             // Send a broadcast if this is the first network of its type or if it's the default.
722             final boolean isDefaultNetwork = mService.isDefaultNetwork(nai);
723             if ((list.size() == 1) || isDefaultNetwork) {
724                 maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isDefaultNetwork);
725                 mService.sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type);
726             }
727         }
728 
729         /** Removes the given network from the specified legacy type list. */
remove(int type, NetworkAgentInfo nai, boolean wasDefault)730         public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) {
731             ArrayList<NetworkAgentInfo> list = mTypeLists[type];
732             if (list == null || list.isEmpty()) {
733                 return;
734             }
735             final boolean wasFirstNetwork = list.get(0).equals(nai);
736 
737             synchronized (mTypeLists) {
738                 if (!list.remove(nai)) {
739                     return;
740                 }
741             }
742 
743             if (wasFirstNetwork || wasDefault) {
744                 maybeLogBroadcast(nai, DetailedState.DISCONNECTED, type, wasDefault);
745                 mService.sendLegacyNetworkBroadcast(nai, DetailedState.DISCONNECTED, type);
746             }
747 
748             if (!list.isEmpty() && wasFirstNetwork) {
749                 if (DBG) log("Other network available for type " + type +
750                               ", sending connected broadcast");
751                 final NetworkAgentInfo replacement = list.get(0);
752                 maybeLogBroadcast(replacement, DetailedState.CONNECTED, type,
753                         mService.isDefaultNetwork(replacement));
754                 mService.sendLegacyNetworkBroadcast(replacement, DetailedState.CONNECTED, type);
755             }
756         }
757 
758         /** Removes the given network from all legacy type lists. */
remove(NetworkAgentInfo nai, boolean wasDefault)759         public void remove(NetworkAgentInfo nai, boolean wasDefault) {
760             if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault);
761             for (int type = 0; type < mTypeLists.length; type++) {
762                 remove(type, nai, wasDefault);
763             }
764         }
765 
766         // send out another legacy broadcast - currently only used for suspend/unsuspend
767         // toggle
update(NetworkAgentInfo nai)768         public void update(NetworkAgentInfo nai) {
769             final boolean isDefault = mService.isDefaultNetwork(nai);
770             final DetailedState state = nai.networkInfo.getDetailedState();
771             for (int type = 0; type < mTypeLists.length; type++) {
772                 final ArrayList<NetworkAgentInfo> list = mTypeLists[type];
773                 final boolean contains = (list != null && list.contains(nai));
774                 final boolean isFirst = contains && (nai == list.get(0));
775                 if (isFirst || contains && isDefault) {
776                     maybeLogBroadcast(nai, state, type, isDefault);
777                     mService.sendLegacyNetworkBroadcast(nai, state, type);
778                 }
779             }
780         }
781 
naiToString(NetworkAgentInfo nai)782         private String naiToString(NetworkAgentInfo nai) {
783             String name = nai.name();
784             String state = (nai.networkInfo != null) ?
785                     nai.networkInfo.getState() + "/" + nai.networkInfo.getDetailedState() :
786                     "???/???";
787             return name + " " + state;
788         }
789 
dump(IndentingPrintWriter pw)790         public void dump(IndentingPrintWriter pw) {
791             pw.println("mLegacyTypeTracker:");
792             pw.increaseIndent();
793             pw.print("Supported types:");
794             for (int type = 0; type < mTypeLists.length; type++) {
795                 if (mTypeLists[type] != null) pw.print(" " + type);
796             }
797             pw.println();
798             pw.println("Current state:");
799             pw.increaseIndent();
800             synchronized (mTypeLists) {
801                 for (int type = 0; type < mTypeLists.length; type++) {
802                     if (mTypeLists[type] == null || mTypeLists[type].isEmpty()) continue;
803                     for (NetworkAgentInfo nai : mTypeLists[type]) {
804                         pw.println(type + " " + naiToString(nai));
805                     }
806                 }
807             }
808             pw.decreaseIndent();
809             pw.decreaseIndent();
810             pw.println();
811         }
812     }
813     private final LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker(this);
814 
815     /**
816      * Helper class which parses out priority arguments and dumps sections according to their
817      * priority. If priority arguments are omitted, function calls the legacy dump command.
818      */
819     private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
820         @Override
821         public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
822             doDump(fd, pw, new String[] {DIAG_ARG}, asProto);
823             doDump(fd, pw, new String[] {SHORT_ARG}, asProto);
824         }
825 
826         @Override
827         public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
828             doDump(fd, pw, args, asProto);
829         }
830 
831         @Override
832         public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
833            doDump(fd, pw, args, asProto);
834         }
835     };
836 
ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager)837     public ConnectivityService(Context context, INetworkManagementService netManager,
838             INetworkStatsService statsService, INetworkPolicyManager policyManager) {
839         this(context, netManager, statsService, policyManager,
840             getDnsResolver(), new IpConnectivityLog(), NetdService.getInstance());
841     }
842 
843     @VisibleForTesting
ConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager, IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd)844     protected ConnectivityService(Context context, INetworkManagementService netManager,
845             INetworkStatsService statsService, INetworkPolicyManager policyManager,
846             IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd) {
847         if (DBG) log("ConnectivityService starting up");
848 
849         mSystemProperties = getSystemProperties();
850 
851         mMetricsLog = logger;
852         mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST);
853         NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest, new Binder());
854         mNetworkRequests.put(mDefaultRequest, defaultNRI);
855         mNetworkRequestInfoLogs.log("REGISTER " + defaultNRI);
856 
857         mDefaultMobileDataRequest = createDefaultInternetRequestForTransport(
858                 NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST);
859 
860         // The default WiFi request is a background request so that apps using WiFi are
861         // migrated to a better network (typically ethernet) when one comes up, instead
862         // of staying on WiFi forever.
863         mDefaultWifiRequest = createDefaultInternetRequestForTransport(
864                 NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST);
865 
866         mHandlerThread = new HandlerThread("ConnectivityServiceThread");
867         mHandlerThread.start();
868         mHandler = new InternalHandler(mHandlerThread.getLooper());
869         mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper());
870 
871         mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(),
872                 Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000);
873 
874         mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
875 
876         mContext = checkNotNull(context, "missing Context");
877         mNMS = checkNotNull(netManager, "missing INetworkManagementService");
878         mStatsService = checkNotNull(statsService, "missing INetworkStatsService");
879         mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
880         mPolicyManagerInternal = checkNotNull(
881                 LocalServices.getService(NetworkPolicyManagerInternal.class),
882                 "missing NetworkPolicyManagerInternal");
883         mDnsResolver = checkNotNull(dnsresolver, "missing IDnsResolver");
884         mProxyTracker = makeProxyTracker();
885 
886         mNetd = netd;
887         mKeyStore = KeyStore.getInstance();
888         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
889 
890         // To ensure uid rules are synchronized with Network Policy, register for
891         // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
892         // reading existing policy from disk.
893         try {
894             mPolicyManager.registerListener(mPolicyListener);
895         } catch (RemoteException e) {
896             // ouch, no rules updates means some processes may never get network
897             loge("unable to register INetworkPolicyListener" + e);
898         }
899 
900         final PowerManager powerManager = (PowerManager) context.getSystemService(
901                 Context.POWER_SERVICE);
902         mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
903         mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
904                 com.android.internal.R.integer.config_networkTransitionTimeout);
905         mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
906 
907         mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
908 
909         // TODO: What is the "correct" way to do determine if this is a wifi only device?
910         boolean wifiOnly = mSystemProperties.getBoolean("ro.radio.noril", false);
911         log("wifiOnly=" + wifiOnly);
912         String[] naStrings = context.getResources().getStringArray(
913                 com.android.internal.R.array.networkAttributes);
914         for (String naString : naStrings) {
915             try {
916                 NetworkConfig n = new NetworkConfig(naString);
917                 if (VDBG) log("naString=" + naString + " config=" + n);
918                 if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) {
919                     loge("Error in networkAttributes - ignoring attempt to define type " +
920                             n.type);
921                     continue;
922                 }
923                 if (wifiOnly && ConnectivityManager.isNetworkTypeMobile(n.type)) {
924                     log("networkAttributes - ignoring mobile as this dev is wifiOnly " +
925                             n.type);
926                     continue;
927                 }
928                 if (mNetConfigs[n.type] != null) {
929                     loge("Error in networkAttributes - ignoring attempt to redefine type " +
930                             n.type);
931                     continue;
932                 }
933                 mLegacyTypeTracker.addSupportedType(n.type);
934 
935                 mNetConfigs[n.type] = n;
936                 mNetworksDefined++;
937             } catch(Exception e) {
938                 // ignore it - leave the entry null
939             }
940         }
941 
942         // Forcibly add TYPE_VPN as a supported type, if it has not already been added via config.
943         if (mNetConfigs[TYPE_VPN] == null) {
944             // mNetConfigs is used only for "restore time", which isn't applicable to VPNs, so we
945             // don't need to add TYPE_VPN to mNetConfigs.
946             mLegacyTypeTracker.addSupportedType(TYPE_VPN);
947             mNetworksDefined++;  // used only in the log() statement below.
948         }
949 
950         // Do the same for Ethernet, since it's often not specified in the configs, although many
951         // devices can use it via USB host adapters.
952         if (mNetConfigs[TYPE_ETHERNET] == null && hasService(Context.ETHERNET_SERVICE)) {
953             mLegacyTypeTracker.addSupportedType(TYPE_ETHERNET);
954             mNetworksDefined++;
955         }
956 
957         if (VDBG) log("mNetworksDefined=" + mNetworksDefined);
958 
959         mProtectedNetworks = new ArrayList<Integer>();
960         int[] protectedNetworks = context.getResources().getIntArray(
961                 com.android.internal.R.array.config_protectedNetworks);
962         for (int p : protectedNetworks) {
963             if ((mNetConfigs[p] != null) && (mProtectedNetworks.contains(p) == false)) {
964                 mProtectedNetworks.add(p);
965             } else {
966                 if (DBG) loge("Ignoring protectedNetwork " + p);
967             }
968         }
969 
970         mTethering = makeTethering();
971 
972         mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
973 
974         // Set up the listener for user state for creating user VPNs.
975         // Should run on mHandler to avoid any races.
976         IntentFilter intentFilter = new IntentFilter();
977         intentFilter.addAction(Intent.ACTION_USER_STARTED);
978         intentFilter.addAction(Intent.ACTION_USER_STOPPED);
979         intentFilter.addAction(Intent.ACTION_USER_ADDED);
980         intentFilter.addAction(Intent.ACTION_USER_REMOVED);
981         intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
982         mContext.registerReceiverAsUser(
983                 mIntentReceiver,
984                 UserHandle.ALL,
985                 intentFilter,
986                 null /* broadcastPermission */,
987                 mHandler);
988         mContext.registerReceiverAsUser(mUserPresentReceiver, UserHandle.SYSTEM,
989                 new IntentFilter(Intent.ACTION_USER_PRESENT), null, null);
990 
991         // Listen to package add and removal events for all users.
992         intentFilter = new IntentFilter();
993         intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
994         intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
995         intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
996         intentFilter.addDataScheme("package");
997         mContext.registerReceiverAsUser(
998                 mIntentReceiver,
999                 UserHandle.ALL,
1000                 intentFilter,
1001                 null /* broadcastPermission */,
1002                 mHandler);
1003 
1004         try {
1005             mNMS.registerObserver(mTethering);
1006             mNMS.registerObserver(mDataActivityObserver);
1007         } catch (RemoteException e) {
1008             loge("Error registering observer :" + e);
1009         }
1010 
1011         mSettingsObserver = new SettingsObserver(mContext, mHandler);
1012         registerSettingsCallbacks();
1013 
1014         final DataConnectionStats dataConnectionStats = new DataConnectionStats(mContext);
1015         dataConnectionStats.startMonitoring();
1016 
1017         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
1018 
1019         mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler);
1020         mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager,
1021                 mContext.getSystemService(NotificationManager.class));
1022 
1023         final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(),
1024                 Settings.Global.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT,
1025                 LingerMonitor.DEFAULT_NOTIFICATION_DAILY_LIMIT);
1026         final long rateLimit = Settings.Global.getLong(mContext.getContentResolver(),
1027                 Settings.Global.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS,
1028                 LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS);
1029         mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit);
1030 
1031         mMultinetworkPolicyTracker = createMultinetworkPolicyTracker(
1032                 mContext, mHandler, () -> rematchForAvoidBadWifiUpdate());
1033         mMultinetworkPolicyTracker.start();
1034 
1035         mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
1036 
1037         mDnsManager = new DnsManager(mContext, mDnsResolver, mSystemProperties);
1038         registerPrivateDnsSettingsCallbacks();
1039     }
1040 
1041     @VisibleForTesting
makeTethering()1042     protected Tethering makeTethering() {
1043         // TODO: Move other elements into @Overridden getters.
1044         final TetheringDependencies deps = new TetheringDependencies() {
1045             @Override
1046             public boolean isTetheringSupported() {
1047                 return ConnectivityService.this.isTetheringSupported();
1048             }
1049             @Override
1050             public NetworkRequest getDefaultNetworkRequest() {
1051                 return mDefaultRequest;
1052             }
1053         };
1054         return new Tethering(mContext, mNMS, mStatsService, mPolicyManager,
1055                 IoThread.get().getLooper(), new MockableSystemProperties(),
1056                 deps);
1057     }
1058 
1059     @VisibleForTesting
makeProxyTracker()1060     protected ProxyTracker makeProxyTracker() {
1061         return new ProxyTracker(mContext, mHandler, EVENT_PROXY_HAS_CHANGED);
1062     }
1063 
createDefaultNetworkCapabilitiesForUid(int uid)1064     private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
1065         final NetworkCapabilities netCap = new NetworkCapabilities();
1066         netCap.addCapability(NET_CAPABILITY_INTERNET);
1067         netCap.addCapability(NET_CAPABILITY_NOT_RESTRICTED);
1068         netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
1069         netCap.setSingleUid(uid);
1070         return netCap;
1071     }
1072 
createDefaultInternetRequestForTransport( int transportType, NetworkRequest.Type type)1073     private NetworkRequest createDefaultInternetRequestForTransport(
1074             int transportType, NetworkRequest.Type type) {
1075         final NetworkCapabilities netCap = new NetworkCapabilities();
1076         netCap.addCapability(NET_CAPABILITY_INTERNET);
1077         netCap.addCapability(NET_CAPABILITY_NOT_RESTRICTED);
1078         if (transportType > -1) {
1079             netCap.addTransportType(transportType);
1080         }
1081         return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type);
1082     }
1083 
1084     // Used only for testing.
1085     // TODO: Delete this and either:
1086     // 1. Give FakeSettingsProvider the ability to send settings change notifications (requires
1087     //    changing ContentResolver to make registerContentObserver non-final).
1088     // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it
1089     //    by subclassing SettingsObserver.
1090     @VisibleForTesting
updateAlwaysOnNetworks()1091     void updateAlwaysOnNetworks() {
1092         mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
1093     }
1094 
1095     // See FakeSettingsProvider comment above.
1096     @VisibleForTesting
updatePrivateDnsSettings()1097     void updatePrivateDnsSettings() {
1098         mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
1099     }
1100 
handleAlwaysOnNetworkRequest( NetworkRequest networkRequest, String settingName, boolean defaultValue)1101     private void handleAlwaysOnNetworkRequest(
1102             NetworkRequest networkRequest, String settingName, boolean defaultValue) {
1103         final boolean enable = toBool(Settings.Global.getInt(
1104                 mContext.getContentResolver(), settingName, encodeBool(defaultValue)));
1105         final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null);
1106         if (enable == isEnabled) {
1107             return;  // Nothing to do.
1108         }
1109 
1110         if (enable) {
1111             handleRegisterNetworkRequest(new NetworkRequestInfo(
1112                     null, networkRequest, new Binder()));
1113         } else {
1114             handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID,
1115                     /* callOnUnavailable */ false);
1116         }
1117     }
1118 
handleConfigureAlwaysOnNetworks()1119     private void handleConfigureAlwaysOnNetworks() {
1120         handleAlwaysOnNetworkRequest(
1121                 mDefaultMobileDataRequest,Settings.Global.MOBILE_DATA_ALWAYS_ON, true);
1122         handleAlwaysOnNetworkRequest(mDefaultWifiRequest, Settings.Global.WIFI_ALWAYS_REQUESTED,
1123                 false);
1124     }
1125 
registerSettingsCallbacks()1126     private void registerSettingsCallbacks() {
1127         // Watch for global HTTP proxy changes.
1128         mSettingsObserver.observe(
1129                 Settings.Global.getUriFor(Settings.Global.HTTP_PROXY),
1130                 EVENT_APPLY_GLOBAL_HTTP_PROXY);
1131 
1132         // Watch for whether or not to keep mobile data always on.
1133         mSettingsObserver.observe(
1134                 Settings.Global.getUriFor(Settings.Global.MOBILE_DATA_ALWAYS_ON),
1135                 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
1136 
1137         // Watch for whether or not to keep wifi always on.
1138         mSettingsObserver.observe(
1139                 Settings.Global.getUriFor(Settings.Global.WIFI_ALWAYS_REQUESTED),
1140                 EVENT_CONFIGURE_ALWAYS_ON_NETWORKS);
1141     }
1142 
registerPrivateDnsSettingsCallbacks()1143     private void registerPrivateDnsSettingsCallbacks() {
1144         for (Uri uri : DnsManager.getPrivateDnsSettingsUris()) {
1145             mSettingsObserver.observe(uri, EVENT_PRIVATE_DNS_SETTINGS_CHANGED);
1146         }
1147     }
1148 
nextNetworkRequestId()1149     private synchronized int nextNetworkRequestId() {
1150         return mNextNetworkRequestId++;
1151     }
1152 
1153     @VisibleForTesting
reserveNetId()1154     protected int reserveNetId() {
1155         synchronized (mNetworkForNetId) {
1156             for (int i = MIN_NET_ID; i <= MAX_NET_ID; i++) {
1157                 int netId = mNextNetId;
1158                 if (++mNextNetId > MAX_NET_ID) mNextNetId = MIN_NET_ID;
1159                 // Make sure NetID unused.  http://b/16815182
1160                 if (!mNetIdInUse.get(netId)) {
1161                     mNetIdInUse.put(netId, true);
1162                     return netId;
1163                 }
1164             }
1165         }
1166         throw new IllegalStateException("No free netIds");
1167     }
1168 
getFilteredNetworkState(int networkType, int uid)1169     private NetworkState getFilteredNetworkState(int networkType, int uid) {
1170         if (mLegacyTypeTracker.isTypeSupported(networkType)) {
1171             final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
1172             final NetworkState state;
1173             if (nai != null) {
1174                 state = nai.getNetworkState();
1175                 state.networkInfo.setType(networkType);
1176             } else {
1177                 final NetworkInfo info = new NetworkInfo(networkType, 0,
1178                         getNetworkTypeName(networkType), "");
1179                 info.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
1180                 info.setIsAvailable(true);
1181                 final NetworkCapabilities capabilities = new NetworkCapabilities();
1182                 capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING,
1183                         !info.isRoaming());
1184                 state = new NetworkState(info, new LinkProperties(), capabilities,
1185                         null, null, null);
1186             }
1187             filterNetworkStateForUid(state, uid, false);
1188             return state;
1189         } else {
1190             return NetworkState.EMPTY;
1191         }
1192     }
1193 
1194     @VisibleForTesting
getNetworkAgentInfoForNetwork(Network network)1195     protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
1196         if (network == null) {
1197             return null;
1198         }
1199         return getNetworkAgentInfoForNetId(network.netId);
1200     }
1201 
getNetworkAgentInfoForNetId(int netId)1202     private NetworkAgentInfo getNetworkAgentInfoForNetId(int netId) {
1203         synchronized (mNetworkForNetId) {
1204             return mNetworkForNetId.get(netId);
1205         }
1206     }
1207 
getVpnUnderlyingNetworks(int uid)1208     private Network[] getVpnUnderlyingNetworks(int uid) {
1209         synchronized (mVpns) {
1210             if (!mLockdownEnabled) {
1211                 int user = UserHandle.getUserId(uid);
1212                 Vpn vpn = mVpns.get(user);
1213                 if (vpn != null && vpn.appliesToUid(uid)) {
1214                     return vpn.getUnderlyingNetworks();
1215                 }
1216             }
1217         }
1218         return null;
1219     }
1220 
getUnfilteredActiveNetworkState(int uid)1221     private NetworkState getUnfilteredActiveNetworkState(int uid) {
1222         NetworkAgentInfo nai = getDefaultNetwork();
1223 
1224         final Network[] networks = getVpnUnderlyingNetworks(uid);
1225         if (networks != null) {
1226             // getUnderlyingNetworks() returns:
1227             // null => there was no VPN, or the VPN didn't specify anything, so we use the default.
1228             // empty array => the VPN explicitly said "no default network".
1229             // non-empty array => the VPN specified one or more default networks; we use the
1230             //                    first one.
1231             if (networks.length > 0) {
1232                 nai = getNetworkAgentInfoForNetwork(networks[0]);
1233             } else {
1234                 nai = null;
1235             }
1236         }
1237 
1238         if (nai != null) {
1239             return nai.getNetworkState();
1240         } else {
1241             return NetworkState.EMPTY;
1242         }
1243     }
1244 
1245     /**
1246      * Check if UID should be blocked from using the network with the given LinkProperties.
1247      */
isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid, boolean ignoreBlocked)1248     private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid,
1249             boolean ignoreBlocked) {
1250         // Networks aren't blocked when ignoring blocked status
1251         if (ignoreBlocked) {
1252             return false;
1253         }
1254         synchronized (mVpns) {
1255             final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
1256             if (vpn != null && vpn.getLockdown() && vpn.isBlockingUid(uid)) {
1257                 return true;
1258             }
1259         }
1260         final String iface = (lp == null ? "" : lp.getInterfaceName());
1261         return mPolicyManagerInternal.isUidNetworkingBlocked(uid, iface);
1262     }
1263 
maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid)1264     private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) {
1265         if (ni == null || !LOGD_BLOCKED_NETWORKINFO) {
1266             return;
1267         }
1268         final boolean blocked;
1269         synchronized (mBlockedAppUids) {
1270             if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) {
1271                 blocked = true;
1272             } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) {
1273                 blocked = false;
1274             } else {
1275                 return;
1276             }
1277         }
1278         String action = blocked ? "BLOCKED" : "UNBLOCKED";
1279         log(String.format("Returning %s NetworkInfo to uid=%d", action, uid));
1280         mNetworkInfoBlockingLogs.log(action + " " + uid);
1281     }
1282 
maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net, boolean blocked)1283     private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net,
1284             boolean blocked) {
1285         if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) {
1286             return;
1287         }
1288         String action = blocked ? "BLOCKED" : "UNBLOCKED";
1289         log(String.format("Blocked status changed to %s for %d(%d) on netId %d", blocked,
1290                 nri.mUid, nri.request.requestId, net.netId));
1291         mNetworkInfoBlockingLogs.log(action + " " + nri.mUid);
1292     }
1293 
1294     /**
1295      * Apply any relevant filters to {@link NetworkState} for the given UID. For
1296      * example, this may mark the network as {@link DetailedState#BLOCKED} based
1297      * on {@link #isNetworkWithLinkPropertiesBlocked}.
1298      */
filterNetworkStateForUid(NetworkState state, int uid, boolean ignoreBlocked)1299     private void filterNetworkStateForUid(NetworkState state, int uid, boolean ignoreBlocked) {
1300         if (state == null || state.networkInfo == null || state.linkProperties == null) return;
1301 
1302         if (isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid, ignoreBlocked)) {
1303             state.networkInfo.setDetailedState(DetailedState.BLOCKED, null, null);
1304         }
1305         synchronized (mVpns) {
1306             if (mLockdownTracker != null) {
1307                 mLockdownTracker.augmentNetworkInfo(state.networkInfo);
1308             }
1309         }
1310     }
1311 
1312     /**
1313      * Return NetworkInfo for the active (i.e., connected) network interface.
1314      * It is assumed that at most one network is active at a time. If more
1315      * than one is active, it is indeterminate which will be returned.
1316      * @return the info for the active network, or {@code null} if none is
1317      * active
1318      */
1319     @Override
getActiveNetworkInfo()1320     public NetworkInfo getActiveNetworkInfo() {
1321         enforceAccessPermission();
1322         final int uid = Binder.getCallingUid();
1323         final NetworkState state = getUnfilteredActiveNetworkState(uid);
1324         filterNetworkStateForUid(state, uid, false);
1325         maybeLogBlockedNetworkInfo(state.networkInfo, uid);
1326         return state.networkInfo;
1327     }
1328 
1329     @Override
getActiveNetwork()1330     public Network getActiveNetwork() {
1331         enforceAccessPermission();
1332         return getActiveNetworkForUidInternal(Binder.getCallingUid(), false);
1333     }
1334 
1335     @Override
getActiveNetworkForUid(int uid, boolean ignoreBlocked)1336     public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
1337         enforceConnectivityInternalPermission();
1338         return getActiveNetworkForUidInternal(uid, ignoreBlocked);
1339     }
1340 
getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked)1341     private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) {
1342         final int user = UserHandle.getUserId(uid);
1343         int vpnNetId = NETID_UNSET;
1344         synchronized (mVpns) {
1345             final Vpn vpn = mVpns.get(user);
1346             // TODO : now that capabilities contain the UID, the appliesToUid test should
1347             // be removed as the satisfying test below should be enough.
1348             if (vpn != null && vpn.appliesToUid(uid)) vpnNetId = vpn.getNetId();
1349         }
1350         NetworkAgentInfo nai;
1351         if (vpnNetId != NETID_UNSET) {
1352             nai = getNetworkAgentInfoForNetId(vpnNetId);
1353             if (nai != null) {
1354                 final NetworkCapabilities requiredCaps =
1355                     createDefaultNetworkCapabilitiesForUid(uid);
1356                 if (requiredCaps.satisfiedByNetworkCapabilities(nai.networkCapabilities)) {
1357                     return nai.network;
1358                 }
1359             }
1360         }
1361         nai = getDefaultNetwork();
1362         if (nai != null
1363                 && isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid, ignoreBlocked)) {
1364             nai = null;
1365         }
1366         return nai != null ? nai.network : null;
1367     }
1368 
1369     // Public because it's used by mLockdownTracker.
getActiveNetworkInfoUnfiltered()1370     public NetworkInfo getActiveNetworkInfoUnfiltered() {
1371         enforceAccessPermission();
1372         final int uid = Binder.getCallingUid();
1373         NetworkState state = getUnfilteredActiveNetworkState(uid);
1374         return state.networkInfo;
1375     }
1376 
1377     @Override
getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked)1378     public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
1379         enforceConnectivityInternalPermission();
1380         final NetworkState state = getUnfilteredActiveNetworkState(uid);
1381         filterNetworkStateForUid(state, uid, ignoreBlocked);
1382         return state.networkInfo;
1383     }
1384 
1385     @Override
getNetworkInfo(int networkType)1386     public NetworkInfo getNetworkInfo(int networkType) {
1387         enforceAccessPermission();
1388         final int uid = Binder.getCallingUid();
1389         if (getVpnUnderlyingNetworks(uid) != null) {
1390             // A VPN is active, so we may need to return one of its underlying networks. This
1391             // information is not available in LegacyTypeTracker, so we have to get it from
1392             // getUnfilteredActiveNetworkState.
1393             final NetworkState state = getUnfilteredActiveNetworkState(uid);
1394             if (state.networkInfo != null && state.networkInfo.getType() == networkType) {
1395                 filterNetworkStateForUid(state, uid, false);
1396                 return state.networkInfo;
1397             }
1398         }
1399         final NetworkState state = getFilteredNetworkState(networkType, uid);
1400         return state.networkInfo;
1401     }
1402 
1403     @Override
getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked)1404     public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
1405         enforceAccessPermission();
1406         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
1407         if (nai != null) {
1408             final NetworkState state = nai.getNetworkState();
1409             filterNetworkStateForUid(state, uid, ignoreBlocked);
1410             return state.networkInfo;
1411         } else {
1412             return null;
1413         }
1414     }
1415 
1416     @Override
getAllNetworkInfo()1417     public NetworkInfo[] getAllNetworkInfo() {
1418         enforceAccessPermission();
1419         final ArrayList<NetworkInfo> result = Lists.newArrayList();
1420         for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE;
1421                 networkType++) {
1422             NetworkInfo info = getNetworkInfo(networkType);
1423             if (info != null) {
1424                 result.add(info);
1425             }
1426         }
1427         return result.toArray(new NetworkInfo[result.size()]);
1428     }
1429 
1430     @Override
getNetworkForType(int networkType)1431     public Network getNetworkForType(int networkType) {
1432         enforceAccessPermission();
1433         final int uid = Binder.getCallingUid();
1434         NetworkState state = getFilteredNetworkState(networkType, uid);
1435         if (!isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid, false)) {
1436             return state.network;
1437         }
1438         return null;
1439     }
1440 
1441     @Override
getAllNetworks()1442     public Network[] getAllNetworks() {
1443         enforceAccessPermission();
1444         synchronized (mNetworkForNetId) {
1445             final Network[] result = new Network[mNetworkForNetId.size()];
1446             for (int i = 0; i < mNetworkForNetId.size(); i++) {
1447                 result[i] = mNetworkForNetId.valueAt(i).network;
1448             }
1449             return result;
1450         }
1451     }
1452 
1453     @Override
getDefaultNetworkCapabilitiesForUser(int userId)1454     public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
1455         // The basic principle is: if an app's traffic could possibly go over a
1456         // network, without the app doing anything multinetwork-specific,
1457         // (hence, by "default"), then include that network's capabilities in
1458         // the array.
1459         //
1460         // In the normal case, app traffic only goes over the system's default
1461         // network connection, so that's the only network returned.
1462         //
1463         // With a VPN in force, some app traffic may go into the VPN, and thus
1464         // over whatever underlying networks the VPN specifies, while other app
1465         // traffic may go over the system default network (e.g.: a split-tunnel
1466         // VPN, or an app disallowed by the VPN), so the set of networks
1467         // returned includes the VPN's underlying networks and the system
1468         // default.
1469         enforceAccessPermission();
1470 
1471         HashMap<Network, NetworkCapabilities> result = new HashMap<>();
1472 
1473         NetworkAgentInfo nai = getDefaultNetwork();
1474         NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
1475         if (nc != null) {
1476             result.put(nai.network, nc);
1477         }
1478 
1479         synchronized (mVpns) {
1480             if (!mLockdownEnabled) {
1481                 Vpn vpn = mVpns.get(userId);
1482                 if (vpn != null) {
1483                     Network[] networks = vpn.getUnderlyingNetworks();
1484                     if (networks != null) {
1485                         for (Network network : networks) {
1486                             nai = getNetworkAgentInfoForNetwork(network);
1487                             nc = getNetworkCapabilitiesInternal(nai);
1488                             if (nc != null) {
1489                                 result.put(network, nc);
1490                             }
1491                         }
1492                     }
1493                 }
1494             }
1495         }
1496 
1497         NetworkCapabilities[] out = new NetworkCapabilities[result.size()];
1498         out = result.values().toArray(out);
1499         return out;
1500     }
1501 
1502     @Override
isNetworkSupported(int networkType)1503     public boolean isNetworkSupported(int networkType) {
1504         enforceAccessPermission();
1505         return mLegacyTypeTracker.isTypeSupported(networkType);
1506     }
1507 
1508     /**
1509      * Return LinkProperties for the active (i.e., connected) default
1510      * network interface.  It is assumed that at most one default network
1511      * is active at a time. If more than one is active, it is indeterminate
1512      * which will be returned.
1513      * @return the ip properties for the active network, or {@code null} if
1514      * none is active
1515      */
1516     @Override
getActiveLinkProperties()1517     public LinkProperties getActiveLinkProperties() {
1518         enforceAccessPermission();
1519         final int uid = Binder.getCallingUid();
1520         NetworkState state = getUnfilteredActiveNetworkState(uid);
1521         return state.linkProperties;
1522     }
1523 
1524     @Override
getLinkPropertiesForType(int networkType)1525     public LinkProperties getLinkPropertiesForType(int networkType) {
1526         enforceAccessPermission();
1527         NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
1528         if (nai != null) {
1529             synchronized (nai) {
1530                 return new LinkProperties(nai.linkProperties);
1531             }
1532         }
1533         return null;
1534     }
1535 
1536     // TODO - this should be ALL networks
1537     @Override
getLinkProperties(Network network)1538     public LinkProperties getLinkProperties(Network network) {
1539         enforceAccessPermission();
1540         return getLinkProperties(getNetworkAgentInfoForNetwork(network));
1541     }
1542 
getLinkProperties(NetworkAgentInfo nai)1543     private LinkProperties getLinkProperties(NetworkAgentInfo nai) {
1544         if (nai == null) {
1545             return null;
1546         }
1547         synchronized (nai) {
1548             return new LinkProperties(nai.linkProperties);
1549         }
1550     }
1551 
getNetworkCapabilitiesInternal(NetworkAgentInfo nai)1552     private NetworkCapabilities getNetworkCapabilitiesInternal(NetworkAgentInfo nai) {
1553         if (nai != null) {
1554             synchronized (nai) {
1555                 if (nai.networkCapabilities != null) {
1556                     return networkCapabilitiesRestrictedForCallerPermissions(
1557                             nai.networkCapabilities,
1558                             Binder.getCallingPid(), Binder.getCallingUid());
1559                 }
1560             }
1561         }
1562         return null;
1563     }
1564 
1565     @Override
getNetworkCapabilities(Network network)1566     public NetworkCapabilities getNetworkCapabilities(Network network) {
1567         enforceAccessPermission();
1568         return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
1569     }
1570 
networkCapabilitiesRestrictedForCallerPermissions( NetworkCapabilities nc, int callerPid, int callerUid)1571     private NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
1572             NetworkCapabilities nc, int callerPid, int callerUid) {
1573         final NetworkCapabilities newNc = new NetworkCapabilities(nc);
1574         if (!checkSettingsPermission(callerPid, callerUid)) {
1575             newNc.setUids(null);
1576             newNc.setSSID(null);
1577         }
1578         if (newNc.getNetworkSpecifier() != null) {
1579             newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact());
1580         }
1581         return newNc;
1582     }
1583 
restrictRequestUidsForCaller(NetworkCapabilities nc)1584     private void restrictRequestUidsForCaller(NetworkCapabilities nc) {
1585         if (!checkSettingsPermission()) {
1586             nc.setSingleUid(Binder.getCallingUid());
1587         }
1588     }
1589 
restrictBackgroundRequestForCaller(NetworkCapabilities nc)1590     private void restrictBackgroundRequestForCaller(NetworkCapabilities nc) {
1591         if (!mPermissionMonitor.hasUseBackgroundNetworksPermission(Binder.getCallingUid())) {
1592             nc.addCapability(NET_CAPABILITY_FOREGROUND);
1593         }
1594     }
1595 
1596     @Override
getAllNetworkState()1597     public NetworkState[] getAllNetworkState() {
1598         // Require internal since we're handing out IMSI details
1599         enforceConnectivityInternalPermission();
1600 
1601         final ArrayList<NetworkState> result = Lists.newArrayList();
1602         for (Network network : getAllNetworks()) {
1603             final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
1604             if (nai != null) {
1605                 // TODO (b/73321673) : NetworkState contains a copy of the
1606                 // NetworkCapabilities, which may contain UIDs of apps to which the
1607                 // network applies. Should the UIDs be cleared so as not to leak or
1608                 // interfere ?
1609                 result.add(nai.getNetworkState());
1610             }
1611         }
1612         return result.toArray(new NetworkState[result.size()]);
1613     }
1614 
1615     @Override
1616     @Deprecated
getActiveNetworkQuotaInfo()1617     public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
1618         Log.w(TAG, "Shame on UID " + Binder.getCallingUid()
1619                 + " for calling the hidden API getNetworkQuotaInfo(). Shame!");
1620         return new NetworkQuotaInfo();
1621     }
1622 
1623     @Override
isActiveNetworkMetered()1624     public boolean isActiveNetworkMetered() {
1625         enforceAccessPermission();
1626 
1627         final NetworkCapabilities caps = getNetworkCapabilities(getActiveNetwork());
1628         if (caps != null) {
1629             return !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
1630         } else {
1631             // Always return the most conservative value
1632             return true;
1633         }
1634     }
1635 
1636     private INetworkManagementEventObserver mDataActivityObserver = new BaseNetworkObserver() {
1637         @Override
1638         public void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos) {
1639             int deviceType = Integer.parseInt(label);
1640             sendDataActivityBroadcast(deviceType, active, tsNanos);
1641         }
1642     };
1643 
1644     /**
1645      * Ensures that the system cannot call a particular method.
1646      */
disallowedBecauseSystemCaller()1647     private boolean disallowedBecauseSystemCaller() {
1648         // TODO: start throwing a SecurityException when GnssLocationProvider stops calling
1649         // requestRouteToHost. In Q, GnssLocationProvider is changed to not call requestRouteToHost
1650         // for devices launched with Q and above. However, existing devices upgrading to Q and
1651         // above must continued to be supported for few more releases.
1652         if (isSystem(Binder.getCallingUid()) && SystemProperties.getInt(
1653                 "ro.product.first_api_level", 0) > Build.VERSION_CODES.P) {
1654             log("This method exists only for app backwards compatibility"
1655                     + " and must not be called by system services.");
1656             return true;
1657         }
1658         return false;
1659     }
1660 
1661     /**
1662      * Ensure that a network route exists to deliver traffic to the specified
1663      * host via the specified network interface.
1664      * @param networkType the type of the network over which traffic to the
1665      * specified host is to be routed
1666      * @param hostAddress the IP address of the host to which the route is
1667      * desired
1668      * @return {@code true} on success, {@code false} on failure
1669      */
1670     @Override
requestRouteToHostAddress(int networkType, byte[] hostAddress)1671     public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
1672         if (disallowedBecauseSystemCaller()) {
1673             return false;
1674         }
1675         enforceChangePermission();
1676         if (mProtectedNetworks.contains(networkType)) {
1677             enforceConnectivityInternalPermission();
1678         }
1679 
1680         InetAddress addr;
1681         try {
1682             addr = InetAddress.getByAddress(hostAddress);
1683         } catch (UnknownHostException e) {
1684             if (DBG) log("requestRouteToHostAddress got " + e.toString());
1685             return false;
1686         }
1687 
1688         if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
1689             if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
1690             return false;
1691         }
1692 
1693         NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
1694         if (nai == null) {
1695             if (mLegacyTypeTracker.isTypeSupported(networkType) == false) {
1696                 if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType);
1697             } else {
1698                 if (DBG) log("requestRouteToHostAddress on down network: " + networkType);
1699             }
1700             return false;
1701         }
1702 
1703         DetailedState netState;
1704         synchronized (nai) {
1705             netState = nai.networkInfo.getDetailedState();
1706         }
1707 
1708         if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) {
1709             if (VDBG) {
1710                 log("requestRouteToHostAddress on down network "
1711                         + "(" + networkType + ") - dropped"
1712                         + " netState=" + netState);
1713             }
1714             return false;
1715         }
1716 
1717         final int uid = Binder.getCallingUid();
1718         final long token = Binder.clearCallingIdentity();
1719         try {
1720             LinkProperties lp;
1721             int netId;
1722             synchronized (nai) {
1723                 lp = nai.linkProperties;
1724                 netId = nai.network.netId;
1725             }
1726             boolean ok = addLegacyRouteToHost(lp, addr, netId, uid);
1727             if (DBG) log("requestRouteToHostAddress ok=" + ok);
1728             return ok;
1729         } finally {
1730             Binder.restoreCallingIdentity(token);
1731         }
1732     }
1733 
addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid)1734     private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) {
1735         RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr);
1736         if (bestRoute == null) {
1737             bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName());
1738         } else {
1739             String iface = bestRoute.getInterface();
1740             if (bestRoute.getGateway().equals(addr)) {
1741                 // if there is no better route, add the implied hostroute for our gateway
1742                 bestRoute = RouteInfo.makeHostRoute(addr, iface);
1743             } else {
1744                 // if we will connect to this through another route, add a direct route
1745                 // to it's gateway
1746                 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface);
1747             }
1748         }
1749         if (DBG) log("Adding legacy route " + bestRoute +
1750                 " for UID/PID " + uid + "/" + Binder.getCallingPid());
1751         try {
1752             mNMS.addLegacyRouteForNetId(netId, bestRoute, uid);
1753         } catch (Exception e) {
1754             // never crash - catch them all
1755             if (DBG) loge("Exception trying to add a route: " + e);
1756             return false;
1757         }
1758         return true;
1759     }
1760 
1761     @VisibleForTesting
1762     protected final INetdEventCallback mNetdEventCallback = new BaseNetdEventCallback() {
1763         @Override
1764         public void onPrivateDnsValidationEvent(int netId, String ipAddress,
1765                 String hostname, boolean validated) {
1766             try {
1767                 mHandler.sendMessage(mHandler.obtainMessage(
1768                         EVENT_PRIVATE_DNS_VALIDATION_UPDATE,
1769                         new PrivateDnsValidationUpdate(netId,
1770                                 InetAddress.parseNumericAddress(ipAddress),
1771                                 hostname, validated)));
1772             } catch (IllegalArgumentException e) {
1773                 loge("Error parsing ip address in validation event");
1774             }
1775         }
1776 
1777         @Override
1778         public void onDnsEvent(int netId, int eventType, int returnCode, String hostname,
1779                 String[] ipAddresses, int ipAddressesCount, long timestamp, int uid) {
1780             NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
1781             // Netd event only allow registrants from system. Each NetworkMonitor thread is under
1782             // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd
1783             // event callback for certain nai. e.g. cellular. Register here to pass to
1784             // NetworkMonitor instead.
1785             // TODO: Move the Dns Event to NetworkMonitor. Use Binder.clearCallingIdentity() in
1786             // registerNetworkAgent to have NetworkMonitor created with system process as design
1787             // expectation. Also, NetdEventListenerService only allow one callback from each
1788             // caller type. Need to re-factor NetdEventListenerService to allow multiple
1789             // NetworkMonitor registrants.
1790             if (nai != null && nai.satisfies(mDefaultRequest)) {
1791                 nai.networkMonitor().notifyDnsResponse(returnCode);
1792             }
1793         }
1794 
1795         @Override
1796         public void onNat64PrefixEvent(int netId, boolean added,
1797                                        String prefixString, int prefixLength) {
1798             mHandler.post(() -> handleNat64PrefixEvent(netId, added, prefixString, prefixLength));
1799         }
1800     };
1801 
1802     @VisibleForTesting
registerNetdEventCallback()1803     protected void registerNetdEventCallback() {
1804         final IIpConnectivityMetrics ipConnectivityMetrics =
1805                 IIpConnectivityMetrics.Stub.asInterface(
1806                         ServiceManager.getService(IpConnectivityLog.SERVICE_NAME));
1807         if (ipConnectivityMetrics == null) {
1808             Slog.wtf(TAG, "Missing IIpConnectivityMetrics");
1809             return;
1810         }
1811 
1812         try {
1813             ipConnectivityMetrics.addNetdEventCallback(
1814                     INetdEventCallback.CALLBACK_CALLER_CONNECTIVITY_SERVICE,
1815                     mNetdEventCallback);
1816         } catch (Exception e) {
1817             loge("Error registering netd callback: " + e);
1818         }
1819     }
1820 
1821     private final INetworkPolicyListener mPolicyListener = new NetworkPolicyManager.Listener() {
1822         @Override
1823         public void onUidRulesChanged(int uid, int uidRules) {
1824             mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_RULES_CHANGED, uid, uidRules));
1825         }
1826         @Override
1827         public void onRestrictBackgroundChanged(boolean restrictBackground) {
1828             // caller is NPMS, since we only register with them
1829             if (LOGD_BLOCKED_NETWORKINFO) {
1830                 log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
1831             }
1832             mHandler.sendMessage(mHandler.obtainMessage(
1833                     EVENT_DATA_SAVER_CHANGED, restrictBackground ? 1 : 0, 0));
1834 
1835             // TODO: relocate this specific callback in Tethering.
1836             if (restrictBackground) {
1837                 log("onRestrictBackgroundChanged(true): disabling tethering");
1838                 mTethering.untetherAll();
1839             }
1840         }
1841     };
1842 
handleUidRulesChanged(int uid, int newRules)1843     void handleUidRulesChanged(int uid, int newRules) {
1844         // skip update when we've already applied rules
1845         final int oldRules = mUidRules.get(uid, RULE_NONE);
1846         if (oldRules == newRules) return;
1847 
1848         maybeNotifyNetworkBlockedForNewUidRules(uid, newRules);
1849 
1850         if (newRules == RULE_NONE) {
1851             mUidRules.delete(uid);
1852         } else {
1853             mUidRules.put(uid, newRules);
1854         }
1855     }
1856 
handleRestrictBackgroundChanged(boolean restrictBackground)1857     void handleRestrictBackgroundChanged(boolean restrictBackground) {
1858         if (mRestrictBackground == restrictBackground) return;
1859 
1860         for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
1861             final boolean curMetered = nai.networkCapabilities.isMetered();
1862             maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground,
1863                     restrictBackground);
1864         }
1865 
1866         mRestrictBackground = restrictBackground;
1867     }
1868 
isUidNetworkingWithVpnBlocked(int uid, int uidRules, boolean isNetworkMetered, boolean isBackgroundRestricted)1869     private boolean isUidNetworkingWithVpnBlocked(int uid, int uidRules, boolean isNetworkMetered,
1870             boolean isBackgroundRestricted) {
1871         synchronized (mVpns) {
1872             final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
1873             // Because the return value of this function depends on the list of UIDs the
1874             // always-on VPN blocks when in lockdown mode, when the always-on VPN changes that
1875             // list all state depending on the return value of this function has to be recomputed.
1876             // TODO: add a trigger when the always-on VPN sets its blocked UIDs to reevaluate and
1877             // send the necessary onBlockedStatusChanged callbacks.
1878             if (vpn != null && vpn.getLockdown() && vpn.isBlockingUid(uid)) {
1879                 return true;
1880             }
1881         }
1882 
1883         return mPolicyManagerInternal.isUidNetworkingBlocked(uid, uidRules,
1884                 isNetworkMetered, isBackgroundRestricted);
1885     }
1886 
1887     /**
1888      * Require that the caller is either in the same user or has appropriate permission to interact
1889      * across users.
1890      *
1891      * @param userId Target user for whatever operation the current IPC is supposed to perform.
1892      */
enforceCrossUserPermission(int userId)1893     private void enforceCrossUserPermission(int userId) {
1894         if (userId == UserHandle.getCallingUserId()) {
1895             // Not a cross-user call.
1896             return;
1897         }
1898         mContext.enforceCallingOrSelfPermission(
1899                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1900                 "ConnectivityService");
1901     }
1902 
checkAnyPermissionOf(String... permissions)1903     private boolean checkAnyPermissionOf(String... permissions) {
1904         for (String permission : permissions) {
1905             if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
1906                 return true;
1907             }
1908         }
1909         return false;
1910     }
1911 
checkAnyPermissionOf(int pid, int uid, String... permissions)1912     private boolean checkAnyPermissionOf(int pid, int uid, String... permissions) {
1913         for (String permission : permissions) {
1914             if (mContext.checkPermission(permission, pid, uid) == PERMISSION_GRANTED) {
1915                 return true;
1916             }
1917         }
1918         return false;
1919     }
1920 
enforceAnyPermissionOf(String... permissions)1921     private void enforceAnyPermissionOf(String... permissions) {
1922         if (!checkAnyPermissionOf(permissions)) {
1923             throw new SecurityException("Requires one of the following permissions: "
1924                     + String.join(", ", permissions) + ".");
1925         }
1926     }
1927 
enforceInternetPermission()1928     private void enforceInternetPermission() {
1929         mContext.enforceCallingOrSelfPermission(
1930                 android.Manifest.permission.INTERNET,
1931                 "ConnectivityService");
1932     }
1933 
enforceAccessPermission()1934     private void enforceAccessPermission() {
1935         mContext.enforceCallingOrSelfPermission(
1936                 android.Manifest.permission.ACCESS_NETWORK_STATE,
1937                 "ConnectivityService");
1938     }
1939 
enforceChangePermission()1940     private void enforceChangePermission() {
1941         ConnectivityManager.enforceChangePermission(mContext);
1942     }
1943 
enforceSettingsPermission()1944     private void enforceSettingsPermission() {
1945         enforceAnyPermissionOf(
1946                 android.Manifest.permission.NETWORK_SETTINGS,
1947                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
1948     }
1949 
checkSettingsPermission()1950     private boolean checkSettingsPermission() {
1951         return checkAnyPermissionOf(
1952                 android.Manifest.permission.NETWORK_SETTINGS,
1953                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
1954     }
1955 
checkSettingsPermission(int pid, int uid)1956     private boolean checkSettingsPermission(int pid, int uid) {
1957         return PERMISSION_GRANTED == mContext.checkPermission(
1958                 android.Manifest.permission.NETWORK_SETTINGS, pid, uid)
1959                 || PERMISSION_GRANTED == mContext.checkPermission(
1960                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid);
1961     }
1962 
enforceTetherAccessPermission()1963     private void enforceTetherAccessPermission() {
1964         mContext.enforceCallingOrSelfPermission(
1965                 android.Manifest.permission.ACCESS_NETWORK_STATE,
1966                 "ConnectivityService");
1967     }
1968 
enforceConnectivityInternalPermission()1969     private void enforceConnectivityInternalPermission() {
1970         enforceAnyPermissionOf(
1971                 android.Manifest.permission.CONNECTIVITY_INTERNAL,
1972                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
1973     }
1974 
enforceControlAlwaysOnVpnPermission()1975     private void enforceControlAlwaysOnVpnPermission() {
1976         mContext.enforceCallingOrSelfPermission(
1977                 android.Manifest.permission.CONTROL_ALWAYS_ON_VPN,
1978                 "ConnectivityService");
1979     }
1980 
enforceNetworkStackSettingsOrSetup()1981     private void enforceNetworkStackSettingsOrSetup() {
1982         enforceAnyPermissionOf(
1983                 android.Manifest.permission.NETWORK_SETTINGS,
1984                 android.Manifest.permission.NETWORK_SETUP_WIZARD,
1985                 android.Manifest.permission.NETWORK_STACK,
1986                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
1987     }
1988 
checkNetworkStackPermission()1989     private boolean checkNetworkStackPermission() {
1990         return checkAnyPermissionOf(
1991                 android.Manifest.permission.NETWORK_STACK,
1992                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
1993     }
1994 
checkNetworkSignalStrengthWakeupPermission(int pid, int uid)1995     private boolean checkNetworkSignalStrengthWakeupPermission(int pid, int uid) {
1996         return checkAnyPermissionOf(pid, uid,
1997                 android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP,
1998                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
1999     }
2000 
enforceConnectivityRestrictedNetworksPermission()2001     private void enforceConnectivityRestrictedNetworksPermission() {
2002         try {
2003             mContext.enforceCallingOrSelfPermission(
2004                     android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS,
2005                     "ConnectivityService");
2006             return;
2007         } catch (SecurityException e) { /* fallback to ConnectivityInternalPermission */ }
2008         enforceConnectivityInternalPermission();
2009     }
2010 
enforceKeepalivePermission()2011     private void enforceKeepalivePermission() {
2012         mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
2013     }
2014 
2015     // Public because it's used by mLockdownTracker.
sendConnectedBroadcast(NetworkInfo info)2016     public void sendConnectedBroadcast(NetworkInfo info) {
2017         enforceConnectivityInternalPermission();
2018         sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
2019     }
2020 
sendInetConditionBroadcast(NetworkInfo info)2021     private void sendInetConditionBroadcast(NetworkInfo info) {
2022         sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
2023     }
2024 
makeGeneralIntent(NetworkInfo info, String bcastType)2025     private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
2026         synchronized (mVpns) {
2027             if (mLockdownTracker != null) {
2028                 info = new NetworkInfo(info);
2029                 mLockdownTracker.augmentNetworkInfo(info);
2030             }
2031         }
2032 
2033         Intent intent = new Intent(bcastType);
2034         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info));
2035         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
2036         if (info.isFailover()) {
2037             intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
2038             info.setFailover(false);
2039         }
2040         if (info.getReason() != null) {
2041             intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
2042         }
2043         if (info.getExtraInfo() != null) {
2044             intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
2045                     info.getExtraInfo());
2046         }
2047         intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
2048         return intent;
2049     }
2050 
sendGeneralBroadcast(NetworkInfo info, String bcastType)2051     private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
2052         sendStickyBroadcast(makeGeneralIntent(info, bcastType));
2053     }
2054 
sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos)2055     private void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) {
2056         Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE);
2057         intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType);
2058         intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active);
2059         intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos);
2060         final long ident = Binder.clearCallingIdentity();
2061         try {
2062             mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL,
2063                     RECEIVE_DATA_ACTIVITY_CHANGE, null, null, 0, null, null);
2064         } finally {
2065             Binder.restoreCallingIdentity(ident);
2066         }
2067     }
2068 
sendStickyBroadcast(Intent intent)2069     private void sendStickyBroadcast(Intent intent) {
2070         synchronized (this) {
2071             if (!mSystemReady
2072                     && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
2073                 mInitialBroadcast = new Intent(intent);
2074             }
2075             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
2076             if (VDBG) {
2077                 log("sendStickyBroadcast: action=" + intent.getAction());
2078             }
2079 
2080             Bundle options = null;
2081             final long ident = Binder.clearCallingIdentity();
2082             if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
2083                 final NetworkInfo ni = intent.getParcelableExtra(
2084                         ConnectivityManager.EXTRA_NETWORK_INFO);
2085                 if (ni.getType() == ConnectivityManager.TYPE_MOBILE_SUPL) {
2086                     intent.setAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL);
2087                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
2088                 } else {
2089                     BroadcastOptions opts = BroadcastOptions.makeBasic();
2090                     opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M);
2091                     options = opts.toBundle();
2092                 }
2093                 final IBatteryStats bs = BatteryStatsService.getService();
2094                 try {
2095                     bs.noteConnectivityChanged(intent.getIntExtra(
2096                             ConnectivityManager.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_NONE),
2097                             ni.getState().toString());
2098                 } catch (RemoteException e) {
2099                 }
2100                 intent.addFlags(Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
2101             }
2102             try {
2103                 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL, options);
2104             } finally {
2105                 Binder.restoreCallingIdentity(ident);
2106             }
2107         }
2108     }
2109 
systemReady()2110     void systemReady() {
2111         mProxyTracker.loadGlobalProxy();
2112         registerNetdEventCallback();
2113         mTethering.systemReady();
2114 
2115         synchronized (this) {
2116             mSystemReady = true;
2117             if (mInitialBroadcast != null) {
2118                 mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL);
2119                 mInitialBroadcast = null;
2120             }
2121         }
2122 
2123         // Try bringing up tracker, but KeyStore won't be ready yet for secondary users so wait
2124         // for user to unlock device too.
2125         updateLockdownVpn();
2126 
2127         // Create network requests for always-on networks.
2128         mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS));
2129 
2130         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_READY));
2131 
2132         mPermissionMonitor.startMonitoring();
2133     }
2134 
2135     /**
2136      * Setup data activity tracking for the given network.
2137      *
2138      * Every {@code setupDataActivityTracking} should be paired with a
2139      * {@link #removeDataActivityTracking} for cleanup.
2140      */
setupDataActivityTracking(NetworkAgentInfo networkAgent)2141     private void setupDataActivityTracking(NetworkAgentInfo networkAgent) {
2142         final String iface = networkAgent.linkProperties.getInterfaceName();
2143 
2144         final int timeout;
2145         int type = ConnectivityManager.TYPE_NONE;
2146 
2147         if (networkAgent.networkCapabilities.hasTransport(
2148                 NetworkCapabilities.TRANSPORT_CELLULAR)) {
2149             timeout = Settings.Global.getInt(mContext.getContentResolver(),
2150                                              Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE,
2151                                              10);
2152             type = ConnectivityManager.TYPE_MOBILE;
2153         } else if (networkAgent.networkCapabilities.hasTransport(
2154                 NetworkCapabilities.TRANSPORT_WIFI)) {
2155             timeout = Settings.Global.getInt(mContext.getContentResolver(),
2156                                              Settings.Global.DATA_ACTIVITY_TIMEOUT_WIFI,
2157                                              15);
2158             type = ConnectivityManager.TYPE_WIFI;
2159         } else {
2160             // do not track any other networks
2161             timeout = 0;
2162         }
2163 
2164         if (timeout > 0 && iface != null && type != ConnectivityManager.TYPE_NONE) {
2165             try {
2166                 mNMS.addIdleTimer(iface, timeout, type);
2167             } catch (Exception e) {
2168                 // You shall not crash!
2169                 loge("Exception in setupDataActivityTracking " + e);
2170             }
2171         }
2172     }
2173 
2174     /**
2175      * Remove data activity tracking when network disconnects.
2176      */
removeDataActivityTracking(NetworkAgentInfo networkAgent)2177     private void removeDataActivityTracking(NetworkAgentInfo networkAgent) {
2178         final String iface = networkAgent.linkProperties.getInterfaceName();
2179         final NetworkCapabilities caps = networkAgent.networkCapabilities;
2180 
2181         if (iface != null && (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
2182                               caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))) {
2183             try {
2184                 // the call fails silently if no idle timer setup for this interface
2185                 mNMS.removeIdleTimer(iface);
2186             } catch (Exception e) {
2187                 loge("Exception in removeDataActivityTracking " + e);
2188             }
2189         }
2190     }
2191 
2192     /**
2193      * Update data activity tracking when network state is updated.
2194      */
updateDataActivityTracking(NetworkAgentInfo newNetwork, NetworkAgentInfo oldNetwork)2195     private void updateDataActivityTracking(NetworkAgentInfo newNetwork,
2196             NetworkAgentInfo oldNetwork) {
2197         if (newNetwork != null) {
2198             setupDataActivityTracking(newNetwork);
2199         }
2200         if (oldNetwork != null) {
2201             removeDataActivityTracking(oldNetwork);
2202         }
2203     }
2204     /**
2205      * Reads the network specific MTU size from resources.
2206      * and set it on it's iface.
2207      */
updateMtu(LinkProperties newLp, LinkProperties oldLp)2208     private void updateMtu(LinkProperties newLp, LinkProperties oldLp) {
2209         final String iface = newLp.getInterfaceName();
2210         final int mtu = newLp.getMtu();
2211         if (oldLp == null && mtu == 0) {
2212             // Silently ignore unset MTU value.
2213             return;
2214         }
2215         if (oldLp != null && newLp.isIdenticalMtu(oldLp)) {
2216             if (VDBG) log("identical MTU - not setting");
2217             return;
2218         }
2219         if (!LinkProperties.isValidMtu(mtu, newLp.hasGlobalIpv6Address())) {
2220             if (mtu != 0) loge("Unexpected mtu value: " + mtu + ", " + iface);
2221             return;
2222         }
2223 
2224         // Cannot set MTU without interface name
2225         if (TextUtils.isEmpty(iface)) {
2226             loge("Setting MTU size with null iface.");
2227             return;
2228         }
2229 
2230         try {
2231             if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu);
2232             mNMS.setMtu(iface, mtu);
2233         } catch (Exception e) {
2234             Slog.e(TAG, "exception in setMtu()" + e);
2235         }
2236     }
2237 
2238     @VisibleForTesting
2239     protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208";
2240     private static final String DEFAULT_TCP_RWND_KEY = "net.tcp.default_init_rwnd";
2241 
2242     // Overridden for testing purposes to avoid writing to SystemProperties.
2243     @VisibleForTesting
getSystemProperties()2244     protected MockableSystemProperties getSystemProperties() {
2245         return new MockableSystemProperties();
2246     }
2247 
updateTcpBufferSizes(String tcpBufferSizes)2248     private void updateTcpBufferSizes(String tcpBufferSizes) {
2249         String[] values = null;
2250         if (tcpBufferSizes != null) {
2251             values = tcpBufferSizes.split(",");
2252         }
2253 
2254         if (values == null || values.length != 6) {
2255             if (DBG) log("Invalid tcpBufferSizes string: " + tcpBufferSizes +", using defaults");
2256             tcpBufferSizes = DEFAULT_TCP_BUFFER_SIZES;
2257             values = tcpBufferSizes.split(",");
2258         }
2259 
2260         if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return;
2261 
2262         try {
2263             if (VDBG || DDBG) Slog.d(TAG, "Setting tx/rx TCP buffers to " + tcpBufferSizes);
2264 
2265             String rmemValues = String.join(" ", values[0], values[1], values[2]);
2266             String wmemValues = String.join(" ", values[3], values[4], values[5]);
2267             mNetd.setTcpRWmemorySize(rmemValues, wmemValues);
2268             mCurrentTcpBufferSizes = tcpBufferSizes;
2269         } catch (RemoteException | ServiceSpecificException e) {
2270             loge("Can't set TCP buffer sizes:" + e);
2271         }
2272 
2273         Integer rwndValue = Settings.Global.getInt(mContext.getContentResolver(),
2274             Settings.Global.TCP_DEFAULT_INIT_RWND,
2275                     mSystemProperties.getInt("net.tcp.default_init_rwnd", 0));
2276         final String sysctlKey = "sys.sysctl.tcp_def_init_rwnd";
2277         if (rwndValue != 0) {
2278             mSystemProperties.set(sysctlKey, rwndValue.toString());
2279         }
2280     }
2281 
2282     @Override
getRestoreDefaultNetworkDelay(int networkType)2283     public int getRestoreDefaultNetworkDelay(int networkType) {
2284         String restoreDefaultNetworkDelayStr = mSystemProperties.get(
2285                 NETWORK_RESTORE_DELAY_PROP_NAME);
2286         if(restoreDefaultNetworkDelayStr != null &&
2287                 restoreDefaultNetworkDelayStr.length() != 0) {
2288             try {
2289                 return Integer.parseInt(restoreDefaultNetworkDelayStr);
2290             } catch (NumberFormatException e) {
2291             }
2292         }
2293         // if the system property isn't set, use the value for the apn type
2294         int ret = RESTORE_DEFAULT_NETWORK_DELAY;
2295 
2296         if ((networkType <= ConnectivityManager.MAX_NETWORK_TYPE) &&
2297                 (mNetConfigs[networkType] != null)) {
2298             ret = mNetConfigs[networkType].restoreTime;
2299         }
2300         return ret;
2301     }
2302 
dumpNetworkDiagnostics(IndentingPrintWriter pw)2303     private void dumpNetworkDiagnostics(IndentingPrintWriter pw) {
2304         final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>();
2305         final long DIAG_TIME_MS = 5000;
2306         for (NetworkAgentInfo nai : networksSortedById()) {
2307             // Start gathering diagnostic information.
2308             netDiags.add(new NetworkDiagnostics(
2309                     nai.network,
2310                     new LinkProperties(nai.linkProperties),  // Must be a copy.
2311                     DIAG_TIME_MS));
2312         }
2313 
2314         for (NetworkDiagnostics netDiag : netDiags) {
2315             pw.println();
2316             netDiag.waitForMeasurements();
2317             netDiag.dump(pw);
2318         }
2319     }
2320 
2321     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)2322     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
2323         PriorityDump.dump(mPriorityDumper, fd, writer, args);
2324     }
2325 
doDump(FileDescriptor fd, PrintWriter writer, String[] args, boolean asProto)2326     private void doDump(FileDescriptor fd, PrintWriter writer, String[] args, boolean asProto) {
2327         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
2328         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
2329         if (asProto) return;
2330 
2331         if (ArrayUtils.contains(args, DIAG_ARG)) {
2332             dumpNetworkDiagnostics(pw);
2333             return;
2334         } else if (ArrayUtils.contains(args, TETHERING_ARG)) {
2335             mTethering.dump(fd, pw, args);
2336             return;
2337         } else if (ArrayUtils.contains(args, NETWORK_ARG)) {
2338             dumpNetworks(pw);
2339             return;
2340         } else if (ArrayUtils.contains(args, REQUEST_ARG)) {
2341             dumpNetworkRequests(pw);
2342             return;
2343         }
2344 
2345         pw.print("NetworkFactories for:");
2346         for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
2347             pw.print(" " + nfi.name);
2348         }
2349         pw.println();
2350         pw.println();
2351 
2352         final NetworkAgentInfo defaultNai = getDefaultNetwork();
2353         pw.print("Active default network: ");
2354         if (defaultNai == null) {
2355             pw.println("none");
2356         } else {
2357             pw.println(defaultNai.network.netId);
2358         }
2359         pw.println();
2360 
2361         pw.println("Current Networks:");
2362         pw.increaseIndent();
2363         dumpNetworks(pw);
2364         pw.decreaseIndent();
2365         pw.println();
2366 
2367         pw.print("Restrict background: ");
2368         pw.println(mRestrictBackground);
2369         pw.println();
2370 
2371         pw.println("Status for known UIDs:");
2372         pw.increaseIndent();
2373         final int size = mUidRules.size();
2374         for (int i = 0; i < size; i++) {
2375             // Don't crash if the array is modified while dumping in bugreports.
2376             try {
2377                 final int uid = mUidRules.keyAt(i);
2378                 final int uidRules = mUidRules.get(uid, RULE_NONE);
2379                 pw.println("UID=" + uid + " rules=" + uidRulesToString(uidRules));
2380             } catch (ArrayIndexOutOfBoundsException e) {
2381                 pw.println("  ArrayIndexOutOfBoundsException");
2382             } catch (ConcurrentModificationException e) {
2383                 pw.println("  ConcurrentModificationException");
2384             }
2385         }
2386         pw.println();
2387         pw.decreaseIndent();
2388 
2389         pw.println("Network Requests:");
2390         pw.increaseIndent();
2391         dumpNetworkRequests(pw);
2392         pw.decreaseIndent();
2393         pw.println();
2394 
2395         mLegacyTypeTracker.dump(pw);
2396 
2397         pw.println();
2398         mTethering.dump(fd, pw, args);
2399 
2400         pw.println();
2401         mKeepaliveTracker.dump(pw);
2402 
2403         pw.println();
2404         dumpAvoidBadWifiSettings(pw);
2405 
2406         pw.println();
2407         mMultipathPolicyTracker.dump(pw);
2408 
2409         if (ArrayUtils.contains(args, SHORT_ARG) == false) {
2410             pw.println();
2411             pw.println("mNetworkRequestInfoLogs (most recent first):");
2412             pw.increaseIndent();
2413             mNetworkRequestInfoLogs.reverseDump(fd, pw, args);
2414             pw.decreaseIndent();
2415 
2416             pw.println();
2417             pw.println("mNetworkInfoBlockingLogs (most recent first):");
2418             pw.increaseIndent();
2419             mNetworkInfoBlockingLogs.reverseDump(fd, pw, args);
2420             pw.decreaseIndent();
2421 
2422             pw.println();
2423             pw.println("NetTransition WakeLock activity (most recent first):");
2424             pw.increaseIndent();
2425             pw.println("total acquisitions: " + mTotalWakelockAcquisitions);
2426             pw.println("total releases: " + mTotalWakelockReleases);
2427             pw.println("cumulative duration: " + (mTotalWakelockDurationMs / 1000) + "s");
2428             pw.println("longest duration: " + (mMaxWakelockDurationMs / 1000) + "s");
2429             if (mTotalWakelockAcquisitions > mTotalWakelockReleases) {
2430                 long duration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
2431                 pw.println("currently holding WakeLock for: " + (duration / 1000) + "s");
2432             }
2433             mWakelockLogs.reverseDump(fd, pw, args);
2434 
2435             pw.println();
2436             pw.println("bandwidth update requests (by uid):");
2437             pw.increaseIndent();
2438             synchronized (mBandwidthRequests) {
2439                 for (int i = 0; i < mBandwidthRequests.size(); i++) {
2440                     pw.println("[" + mBandwidthRequests.keyAt(i)
2441                             + "]: " + mBandwidthRequests.valueAt(i));
2442                 }
2443             }
2444             pw.decreaseIndent();
2445 
2446             pw.decreaseIndent();
2447         }
2448 
2449         pw.println();
2450         pw.println("NetworkStackClient logs:");
2451         pw.increaseIndent();
2452         NetworkStackClient.getInstance().dump(pw);
2453         pw.decreaseIndent();
2454 
2455         pw.println();
2456         pw.println("Permission Monitor:");
2457         pw.increaseIndent();
2458         mPermissionMonitor.dump(pw);
2459         pw.decreaseIndent();
2460     }
2461 
dumpNetworks(IndentingPrintWriter pw)2462     private void dumpNetworks(IndentingPrintWriter pw) {
2463         for (NetworkAgentInfo nai : networksSortedById()) {
2464             pw.println(nai.toString());
2465             pw.increaseIndent();
2466             pw.println(String.format(
2467                     "Requests: REQUEST:%d LISTEN:%d BACKGROUND_REQUEST:%d total:%d",
2468                     nai.numForegroundNetworkRequests(),
2469                     nai.numNetworkRequests() - nai.numRequestNetworkRequests(),
2470                     nai.numBackgroundNetworkRequests(),
2471                     nai.numNetworkRequests()));
2472             pw.increaseIndent();
2473             for (int i = 0; i < nai.numNetworkRequests(); i++) {
2474                 pw.println(nai.requestAt(i).toString());
2475             }
2476             pw.decreaseIndent();
2477             pw.println("Lingered:");
2478             pw.increaseIndent();
2479             nai.dumpLingerTimers(pw);
2480             pw.decreaseIndent();
2481             pw.decreaseIndent();
2482         }
2483     }
2484 
dumpNetworkRequests(IndentingPrintWriter pw)2485     private void dumpNetworkRequests(IndentingPrintWriter pw) {
2486         for (NetworkRequestInfo nri : requestsSortedById()) {
2487             pw.println(nri.toString());
2488         }
2489     }
2490 
2491     /**
2492      * Return an array of all current NetworkAgentInfos sorted by network id.
2493      */
networksSortedById()2494     private NetworkAgentInfo[] networksSortedById() {
2495         NetworkAgentInfo[] networks = new NetworkAgentInfo[0];
2496         networks = mNetworkAgentInfos.values().toArray(networks);
2497         Arrays.sort(networks, Comparator.comparingInt(nai -> nai.network.netId));
2498         return networks;
2499     }
2500 
2501     /**
2502      * Return an array of all current NetworkRequest sorted by request id.
2503      */
requestsSortedById()2504     private NetworkRequestInfo[] requestsSortedById() {
2505         NetworkRequestInfo[] requests = new NetworkRequestInfo[0];
2506         requests = mNetworkRequests.values().toArray(requests);
2507         Arrays.sort(requests, Comparator.comparingInt(nri -> nri.request.requestId));
2508         return requests;
2509     }
2510 
isLiveNetworkAgent(NetworkAgentInfo nai, int what)2511     private boolean isLiveNetworkAgent(NetworkAgentInfo nai, int what) {
2512         if (nai.network == null) return false;
2513         final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network);
2514         if (officialNai != null && officialNai.equals(nai)) return true;
2515         if (officialNai != null || VDBG) {
2516             loge(eventName(what) + " - isLiveNetworkAgent found mismatched netId: " + officialNai +
2517                 " - " + nai);
2518         }
2519         return false;
2520     }
2521 
2522     // must be stateless - things change under us.
2523     private class NetworkStateTrackerHandler extends Handler {
NetworkStateTrackerHandler(Looper looper)2524         public NetworkStateTrackerHandler(Looper looper) {
2525             super(looper);
2526         }
2527 
maybeHandleAsyncChannelMessage(Message msg)2528         private boolean maybeHandleAsyncChannelMessage(Message msg) {
2529             switch (msg.what) {
2530                 default:
2531                     return false;
2532                 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
2533                     handleAsyncChannelHalfConnect(msg);
2534                     break;
2535                 }
2536                 case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
2537                     NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
2538                     if (nai != null) nai.asyncChannel.disconnect();
2539                     break;
2540                 }
2541                 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
2542                     handleAsyncChannelDisconnected(msg);
2543                     break;
2544                 }
2545             }
2546             return true;
2547         }
2548 
maybeHandleNetworkAgentMessage(Message msg)2549         private void maybeHandleNetworkAgentMessage(Message msg) {
2550             NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
2551             if (nai == null) {
2552                 if (VDBG) {
2553                     log(String.format("%s from unknown NetworkAgent", eventName(msg.what)));
2554                 }
2555                 return;
2556             }
2557 
2558             switch (msg.what) {
2559                 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
2560                     final NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj;
2561                     if (networkCapabilities.hasConnectivityManagedCapability()) {
2562                         Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
2563                     }
2564                     updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
2565                     break;
2566                 }
2567                 case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: {
2568                     handleUpdateLinkProperties(nai, (LinkProperties) msg.obj);
2569                     break;
2570                 }
2571                 case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {
2572                     NetworkInfo info = (NetworkInfo) msg.obj;
2573                     updateNetworkInfo(nai, info);
2574                     break;
2575                 }
2576                 case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
2577                     updateNetworkScore(nai, msg.arg1);
2578                     break;
2579                 }
2580                 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
2581                     if (nai.everConnected) {
2582                         loge("ERROR: cannot call explicitlySelected on already-connected network");
2583                     }
2584                     nai.networkMisc.explicitlySelected = (msg.arg1 == 1);
2585                     nai.networkMisc.acceptUnvalidated = (msg.arg1 == 1) && (msg.arg2 == 1);
2586                     // Mark the network as temporarily accepting partial connectivity so that it
2587                     // will be validated (and possibly become default) even if it only provides
2588                     // partial internet access. Note that if user connects to partial connectivity
2589                     // and choose "don't ask again", then wifi disconnected by some reasons(maybe
2590                     // out of wifi coverage) and if the same wifi is available again, the device
2591                     // will auto connect to this wifi even though the wifi has "no internet".
2592                     // TODO: Evaluate using a separate setting in IpMemoryStore.
2593                     nai.networkMisc.acceptPartialConnectivity = (msg.arg2 == 1);
2594                     break;
2595                 }
2596                 case NetworkAgent.EVENT_SOCKET_KEEPALIVE: {
2597                     mKeepaliveTracker.handleEventSocketKeepalive(nai, msg);
2598                     break;
2599                 }
2600             }
2601         }
2602 
maybeHandleNetworkMonitorMessage(Message msg)2603         private boolean maybeHandleNetworkMonitorMessage(Message msg) {
2604             switch (msg.what) {
2605                 default:
2606                     return false;
2607                 case EVENT_NETWORK_TESTED: {
2608                     final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
2609                     if (nai == null) break;
2610 
2611                     final boolean wasPartial = nai.partialConnectivity;
2612                     nai.partialConnectivity = ((msg.arg1 & NETWORK_VALIDATION_RESULT_PARTIAL) != 0);
2613                     final boolean partialConnectivityChanged =
2614                             (wasPartial != nai.partialConnectivity);
2615 
2616                     final boolean valid = ((msg.arg1 & NETWORK_VALIDATION_RESULT_VALID) != 0);
2617                     final boolean wasValidated = nai.lastValidated;
2618                     final boolean wasDefault = isDefaultNetwork(nai);
2619                     // Only show a connected notification if the network is pending validation
2620                     // after the captive portal app was open, and it has now validated.
2621                     if (nai.captivePortalValidationPending && valid) {
2622                         // User is now logged in, network validated.
2623                         nai.captivePortalValidationPending = false;
2624                         showNetworkNotification(nai, NotificationType.LOGGED_IN);
2625                     }
2626 
2627                     final String redirectUrl = (msg.obj instanceof String) ? (String) msg.obj : "";
2628 
2629                     if (DBG) {
2630                         final String logMsg = !TextUtils.isEmpty(redirectUrl)
2631                                  ? " with redirect to " + redirectUrl
2632                                  : "";
2633                         log(nai.name() + " validation " + (valid ? "passed" : "failed") + logMsg);
2634                     }
2635                     if (valid != nai.lastValidated) {
2636                         if (wasDefault) {
2637                             metricsLogger().defaultNetworkMetrics().logDefaultNetworkValidity(
2638                                     SystemClock.elapsedRealtime(), valid);
2639                         }
2640                         final int oldScore = nai.getCurrentScore();
2641                         nai.lastValidated = valid;
2642                         nai.everValidated |= valid;
2643                         updateCapabilities(oldScore, nai, nai.networkCapabilities);
2644                         // If score has changed, rebroadcast to NetworkFactories. b/17726566
2645                         if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai);
2646                         if (valid) {
2647                             handleFreshlyValidatedNetwork(nai);
2648                             // Clear NO_INTERNET, PARTIAL_CONNECTIVITY and LOST_INTERNET
2649                             // notifications if network becomes valid.
2650                             mNotifier.clearNotification(nai.network.netId,
2651                                     NotificationType.NO_INTERNET);
2652                             mNotifier.clearNotification(nai.network.netId,
2653                                     NotificationType.LOST_INTERNET);
2654                             mNotifier.clearNotification(nai.network.netId,
2655                                     NotificationType.PARTIAL_CONNECTIVITY);
2656                         }
2657                     } else if (partialConnectivityChanged) {
2658                         updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
2659                     }
2660                     updateInetCondition(nai);
2661                     // Let the NetworkAgent know the state of its network
2662                     Bundle redirectUrlBundle = new Bundle();
2663                     redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, redirectUrl);
2664                     // TODO: Evaluate to update partial connectivity to status to NetworkAgent.
2665                     nai.asyncChannel.sendMessage(
2666                             NetworkAgent.CMD_REPORT_NETWORK_STATUS,
2667                             (valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK),
2668                             0, redirectUrlBundle);
2669 
2670                     // If NetworkMonitor detects partial connectivity before
2671                     // EVENT_PROMPT_UNVALIDATED arrives, show the partial connectivity notification
2672                     // immediately. Re-notify partial connectivity silently if no internet
2673                     // notification already there.
2674                     if (!wasPartial && nai.partialConnectivity) {
2675                         // Remove delayed message if there is a pending message.
2676                         mHandler.removeMessages(EVENT_PROMPT_UNVALIDATED, nai.network);
2677                         handlePromptUnvalidated(nai.network);
2678                     }
2679 
2680                     if (wasValidated && !nai.lastValidated) {
2681                         handleNetworkUnvalidated(nai);
2682                     }
2683                     break;
2684                 }
2685                 case EVENT_PROVISIONING_NOTIFICATION: {
2686                     final int netId = msg.arg2;
2687                     final boolean visible = toBool(msg.arg1);
2688                     final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
2689                     // If captive portal status has changed, update capabilities or disconnect.
2690                     if (nai != null && (visible != nai.lastCaptivePortalDetected)) {
2691                         final int oldScore = nai.getCurrentScore();
2692                         nai.lastCaptivePortalDetected = visible;
2693                         nai.everCaptivePortalDetected |= visible;
2694                         if (nai.lastCaptivePortalDetected &&
2695                             Settings.Global.CAPTIVE_PORTAL_MODE_AVOID == getCaptivePortalMode()) {
2696                             if (DBG) log("Avoiding captive portal network: " + nai.name());
2697                             nai.asyncChannel.sendMessage(
2698                                     NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
2699                             teardownUnneededNetwork(nai);
2700                             break;
2701                         }
2702                         updateCapabilities(oldScore, nai, nai.networkCapabilities);
2703                     }
2704                     if (!visible) {
2705                         // Only clear SIGN_IN and NETWORK_SWITCH notifications here, or else other
2706                         // notifications belong to the same network may be cleared unexpectedly.
2707                         mNotifier.clearNotification(netId, NotificationType.SIGN_IN);
2708                         mNotifier.clearNotification(netId, NotificationType.NETWORK_SWITCH);
2709                     } else {
2710                         if (nai == null) {
2711                             loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
2712                             break;
2713                         }
2714                         if (!nai.networkMisc.provisioningNotificationDisabled) {
2715                             mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai, null,
2716                                     (PendingIntent) msg.obj, nai.networkMisc.explicitlySelected);
2717                         }
2718                     }
2719                     break;
2720                 }
2721                 case EVENT_PRIVATE_DNS_CONFIG_RESOLVED: {
2722                     final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
2723                     if (nai == null) break;
2724 
2725                     updatePrivateDns(nai, (PrivateDnsConfig) msg.obj);
2726                     break;
2727                 }
2728             }
2729             return true;
2730         }
2731 
getCaptivePortalMode()2732         private int getCaptivePortalMode() {
2733             return Settings.Global.getInt(mContext.getContentResolver(),
2734                     Settings.Global.CAPTIVE_PORTAL_MODE,
2735                     Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
2736         }
2737 
maybeHandleNetworkAgentInfoMessage(Message msg)2738         private boolean maybeHandleNetworkAgentInfoMessage(Message msg) {
2739             switch (msg.what) {
2740                 default:
2741                     return false;
2742                 case NetworkAgentInfo.EVENT_NETWORK_LINGER_COMPLETE: {
2743                     NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
2744                     if (nai != null && isLiveNetworkAgent(nai, msg.what)) {
2745                         handleLingerComplete(nai);
2746                     }
2747                     break;
2748                 }
2749             }
2750             return true;
2751         }
2752 
maybeHandleNetworkFactoryMessage(Message msg)2753         private boolean maybeHandleNetworkFactoryMessage(Message msg) {
2754             switch (msg.what) {
2755                 default:
2756                     return false;
2757                 case NetworkFactory.EVENT_UNFULFILLABLE_REQUEST: {
2758                     handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.sendingUid,
2759                             /* callOnUnavailable */ true);
2760                     break;
2761                 }
2762             }
2763             return true;
2764         }
2765 
2766         @Override
handleMessage(Message msg)2767         public void handleMessage(Message msg) {
2768             if (!maybeHandleAsyncChannelMessage(msg)
2769                     && !maybeHandleNetworkMonitorMessage(msg)
2770                     && !maybeHandleNetworkAgentInfoMessage(msg)
2771                     && !maybeHandleNetworkFactoryMessage(msg)) {
2772                 maybeHandleNetworkAgentMessage(msg);
2773             }
2774         }
2775     }
2776 
2777     private class NetworkMonitorCallbacks extends INetworkMonitorCallbacks.Stub {
2778         private final int mNetId;
2779         private final AutodestructReference<NetworkAgentInfo> mNai;
2780 
NetworkMonitorCallbacks(NetworkAgentInfo nai)2781         private NetworkMonitorCallbacks(NetworkAgentInfo nai) {
2782             mNetId = nai.network.netId;
2783             mNai = new AutodestructReference(nai);
2784         }
2785 
2786         @Override
onNetworkMonitorCreated(INetworkMonitor networkMonitor)2787         public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) {
2788             mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT,
2789                     new Pair<>(mNai.getAndDestroy(), networkMonitor)));
2790         }
2791 
2792         @Override
notifyNetworkTested(int testResult, @Nullable String redirectUrl)2793         public void notifyNetworkTested(int testResult, @Nullable String redirectUrl) {
2794             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(EVENT_NETWORK_TESTED,
2795                     testResult, mNetId, redirectUrl));
2796         }
2797 
2798         @Override
notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config)2799         public void notifyPrivateDnsConfigResolved(PrivateDnsConfigParcel config) {
2800             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
2801                     EVENT_PRIVATE_DNS_CONFIG_RESOLVED,
2802                     0, mNetId, PrivateDnsConfig.fromParcel(config)));
2803         }
2804 
2805         @Override
showProvisioningNotification(String action, String packageName)2806         public void showProvisioningNotification(String action, String packageName) {
2807             final Intent intent = new Intent(action);
2808             intent.setPackage(packageName);
2809 
2810             final PendingIntent pendingIntent;
2811             // Only the system server can register notifications with package "android"
2812             final long token = Binder.clearCallingIdentity();
2813             try {
2814                 pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
2815             } finally {
2816                 Binder.restoreCallingIdentity(token);
2817             }
2818             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
2819                     EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_SHOW,
2820                     mNetId, pendingIntent));
2821         }
2822 
2823         @Override
hideProvisioningNotification()2824         public void hideProvisioningNotification() {
2825             mTrackerHandler.sendMessage(mTrackerHandler.obtainMessage(
2826                     EVENT_PROVISIONING_NOTIFICATION, PROVISIONING_NOTIFICATION_HIDE, mNetId));
2827         }
2828 
2829         @Override
getInterfaceVersion()2830         public int getInterfaceVersion() {
2831             return this.VERSION;
2832         }
2833     }
2834 
networkRequiresPrivateDnsValidation(NetworkAgentInfo nai)2835     private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) {
2836         return isPrivateDnsValidationRequired(nai.networkCapabilities);
2837     }
2838 
handleFreshlyValidatedNetwork(NetworkAgentInfo nai)2839     private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) {
2840         if (nai == null) return;
2841         // If the Private DNS mode is opportunistic, reprogram the DNS servers
2842         // in order to restart a validation pass from within netd.
2843         final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
2844         if (cfg.useTls && TextUtils.isEmpty(cfg.hostname)) {
2845             updateDnses(nai.linkProperties, null, nai.network.netId);
2846         }
2847     }
2848 
handlePrivateDnsSettingsChanged()2849     private void handlePrivateDnsSettingsChanged() {
2850         final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
2851 
2852         for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
2853             handlePerNetworkPrivateDnsConfig(nai, cfg);
2854             if (networkRequiresPrivateDnsValidation(nai)) {
2855                 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
2856             }
2857         }
2858     }
2859 
handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg)2860     private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) {
2861         // Private DNS only ever applies to networks that might provide
2862         // Internet access and therefore also require validation.
2863         if (!networkRequiresPrivateDnsValidation(nai)) return;
2864 
2865         // Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or
2866         // schedule DNS resolutions. If a DNS resolution is required the
2867         // result will be sent back to us.
2868         nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel());
2869 
2870         // With Private DNS bypass support, we can proceed to update the
2871         // Private DNS config immediately, even if we're in strict mode
2872         // and have not yet resolved the provider name into a set of IPs.
2873         updatePrivateDns(nai, cfg);
2874     }
2875 
updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg)2876     private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) {
2877         mDnsManager.updatePrivateDns(nai.network, newCfg);
2878         updateDnses(nai.linkProperties, null, nai.network.netId);
2879     }
2880 
handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update)2881     private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) {
2882         NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId);
2883         if (nai == null) {
2884             return;
2885         }
2886         mDnsManager.updatePrivateDnsValidation(update);
2887         handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
2888     }
2889 
handleNat64PrefixEvent(int netId, boolean added, String prefixString, int prefixLength)2890     private void handleNat64PrefixEvent(int netId, boolean added, String prefixString,
2891             int prefixLength) {
2892         NetworkAgentInfo nai = mNetworkForNetId.get(netId);
2893         if (nai == null) return;
2894 
2895         log(String.format("NAT64 prefix %s on netId %d: %s/%d",
2896                           (added ? "added" : "removed"), netId, prefixString, prefixLength));
2897 
2898         IpPrefix prefix = null;
2899         if (added) {
2900             try {
2901                 prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixString),
2902                         prefixLength);
2903             } catch (IllegalArgumentException e) {
2904                 loge("Invalid NAT64 prefix " + prefixString + "/" + prefixLength);
2905                 return;
2906             }
2907         }
2908 
2909         nai.clatd.setNat64Prefix(prefix);
2910         handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
2911     }
2912 
updateLingerState(NetworkAgentInfo nai, long now)2913     private void updateLingerState(NetworkAgentInfo nai, long now) {
2914         // 1. Update the linger timer. If it's changed, reschedule or cancel the alarm.
2915         // 2. If the network was lingering and there are now requests, unlinger it.
2916         // 3. If this network is unneeded (which implies it is not lingering), and there is at least
2917         //    one lingered request, start lingering.
2918         nai.updateLingerTimer();
2919         if (nai.isLingering() && nai.numForegroundNetworkRequests() > 0) {
2920             if (DBG) log("Unlingering " + nai.name());
2921             nai.unlinger();
2922             logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER);
2923         } else if (unneeded(nai, UnneededFor.LINGER) && nai.getLingerExpiry() > 0) {
2924             int lingerTime = (int) (nai.getLingerExpiry() - now);
2925             if (DBG) log("Lingering " + nai.name() + " for " + lingerTime + "ms");
2926             nai.linger();
2927             logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER);
2928             notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime);
2929         }
2930     }
2931 
handleAsyncChannelHalfConnect(Message msg)2932     private void handleAsyncChannelHalfConnect(Message msg) {
2933         AsyncChannel ac = (AsyncChannel) msg.obj;
2934         if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {
2935             if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
2936                 if (VDBG) log("NetworkFactory connected");
2937                 // Finish setting up the full connection
2938                 mNetworkFactoryInfos.get(msg.replyTo).asyncChannel.sendMessage(
2939                         AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
2940                 // A network factory has connected.  Send it all current NetworkRequests.
2941                 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
2942                     if (nri.request.isListen()) continue;
2943                     NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId);
2944                     final int score;
2945                     final int serial;
2946                     if (nai != null) {
2947                         score = nai.getCurrentScore();
2948                         serial = nai.factorySerialNumber;
2949                     } else {
2950                         score = 0;
2951                         serial = NetworkFactory.SerialNumber.NONE;
2952                     }
2953                     ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, serial,
2954                             nri.request);
2955                 }
2956             } else {
2957                 loge("Error connecting NetworkFactory");
2958                 mNetworkFactoryInfos.remove(msg.obj);
2959             }
2960         } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) {
2961             if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
2962                 if (VDBG) log("NetworkAgent connected");
2963                 // A network agent has requested a connection.  Establish the connection.
2964                 mNetworkAgentInfos.get(msg.replyTo).asyncChannel.
2965                         sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
2966             } else {
2967                 loge("Error connecting NetworkAgent");
2968                 NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo);
2969                 if (nai != null) {
2970                     final boolean wasDefault = isDefaultNetwork(nai);
2971                     synchronized (mNetworkForNetId) {
2972                         mNetworkForNetId.remove(nai.network.netId);
2973                         mNetIdInUse.delete(nai.network.netId);
2974                     }
2975                     // Just in case.
2976                     mLegacyTypeTracker.remove(nai, wasDefault);
2977                 }
2978             }
2979         }
2980     }
2981 
2982     // This is a no-op if it's called with a message designating a network that has
2983     // already been destroyed, because its reference will not be found in the relevant
2984     // maps.
handleAsyncChannelDisconnected(Message msg)2985     private void handleAsyncChannelDisconnected(Message msg) {
2986         NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
2987         if (nai != null) {
2988             disconnectAndDestroyNetwork(nai);
2989         } else {
2990             NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo);
2991             if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name);
2992         }
2993     }
2994 
2995     // Destroys a network, remove references to it from the internal state managed by
2996     // ConnectivityService, free its interfaces and clean up.
2997     // Must be called on the Handler thread.
disconnectAndDestroyNetwork(NetworkAgentInfo nai)2998     private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) {
2999         if (DBG) {
3000             log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests());
3001         }
3002         // Clear all notifications of this network.
3003         mNotifier.clearNotification(nai.network.netId);
3004         // A network agent has disconnected.
3005         // TODO - if we move the logic to the network agent (have them disconnect
3006         // because they lost all their requests or because their score isn't good)
3007         // then they would disconnect organically, report their new state and then
3008         // disconnect the channel.
3009         if (nai.networkInfo.isConnected()) {
3010             nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
3011                     null, null);
3012         }
3013         final boolean wasDefault = isDefaultNetwork(nai);
3014         if (wasDefault) {
3015             mDefaultInetConditionPublished = 0;
3016             // Log default network disconnection before required book-keeping.
3017             // Let rematchAllNetworksAndRequests() below record a new default network event
3018             // if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence
3019             // whose timestamps tell how long it takes to recover a default network.
3020             long now = SystemClock.elapsedRealtime();
3021             metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai);
3022         }
3023         notifyIfacesChangedForNetworkStats();
3024         // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
3025         // by other networks that are already connected. Perhaps that can be done by
3026         // sending all CALLBACK_LOST messages (for requests, not listens) at the end
3027         // of rematchAllNetworksAndRequests
3028         notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
3029         mKeepaliveTracker.handleStopAllKeepalives(nai, SocketKeepalive.ERROR_INVALID_NETWORK);
3030         for (String iface : nai.linkProperties.getAllInterfaceNames()) {
3031             // Disable wakeup packet monitoring for each interface.
3032             wakeupModifyInterface(iface, nai.networkCapabilities, false);
3033         }
3034         nai.networkMonitor().notifyNetworkDisconnected();
3035         mNetworkAgentInfos.remove(nai.messenger);
3036         nai.clatd.update();
3037         synchronized (mNetworkForNetId) {
3038             // Remove the NetworkAgent, but don't mark the netId as
3039             // available until we've told netd to delete it below.
3040             mNetworkForNetId.remove(nai.network.netId);
3041         }
3042         // Remove all previously satisfied requests.
3043         for (int i = 0; i < nai.numNetworkRequests(); i++) {
3044             NetworkRequest request = nai.requestAt(i);
3045             NetworkAgentInfo currentNetwork = getNetworkForRequest(request.requestId);
3046             if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
3047                 clearNetworkForRequest(request.requestId);
3048                 sendUpdatedScoreToFactories(request, null);
3049             }
3050         }
3051         nai.clearLingerState();
3052         if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
3053             updateDataActivityTracking(null /* newNetwork */, nai);
3054             notifyLockdownVpn(nai);
3055             ensureNetworkTransitionWakelock(nai.name());
3056         }
3057         mLegacyTypeTracker.remove(nai, wasDefault);
3058         if (!nai.networkCapabilities.hasTransport(TRANSPORT_VPN)) {
3059             updateAllVpnsCapabilities();
3060         }
3061         rematchAllNetworksAndRequests(null, 0);
3062         mLingerMonitor.noteDisconnect(nai);
3063         if (nai.created) {
3064             // Tell netd to clean up the configuration for this network
3065             // (routing rules, DNS, etc).
3066             // This may be slow as it requires a lot of netd shelling out to ip and
3067             // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it
3068             // after we've rematched networks with requests which should make a potential
3069             // fallback network the default or requested a new network from the
3070             // NetworkFactories, so network traffic isn't interrupted for an unnecessarily
3071             // long time.
3072             destroyNativeNetwork(nai);
3073             mDnsManager.removeNetwork(nai.network);
3074         }
3075         synchronized (mNetworkForNetId) {
3076             mNetIdInUse.delete(nai.network.netId);
3077         }
3078     }
3079 
createNativeNetwork(@onNull NetworkAgentInfo networkAgent)3080     private boolean createNativeNetwork(@NonNull NetworkAgentInfo networkAgent) {
3081         try {
3082             // This should never fail.  Specifying an already in use NetID will cause failure.
3083             if (networkAgent.isVPN()) {
3084                 mNetd.networkCreateVpn(networkAgent.network.netId,
3085                         (networkAgent.networkMisc == null
3086                                 || !networkAgent.networkMisc.allowBypass));
3087             } else {
3088                 mNetd.networkCreatePhysical(networkAgent.network.netId,
3089                         getNetworkPermission(networkAgent.networkCapabilities));
3090             }
3091             mDnsResolver.createNetworkCache(networkAgent.network.netId);
3092             return true;
3093         } catch (RemoteException | ServiceSpecificException e) {
3094             loge("Error creating network " + networkAgent.network.netId + ": "
3095                     + e.getMessage());
3096             return false;
3097         }
3098     }
3099 
destroyNativeNetwork(@onNull NetworkAgentInfo networkAgent)3100     private void destroyNativeNetwork(@NonNull NetworkAgentInfo networkAgent) {
3101         try {
3102             mNetd.networkDestroy(networkAgent.network.netId);
3103             mDnsResolver.destroyNetworkCache(networkAgent.network.netId);
3104         } catch (RemoteException | ServiceSpecificException e) {
3105             loge("Exception destroying network: " + e);
3106         }
3107     }
3108 
3109     // If this method proves to be too slow then we can maintain a separate
3110     // pendingIntent => NetworkRequestInfo map.
3111     // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo.
findExistingNetworkRequestInfo(PendingIntent pendingIntent)3112     private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) {
3113         Intent intent = pendingIntent.getIntent();
3114         for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) {
3115             PendingIntent existingPendingIntent = entry.getValue().mPendingIntent;
3116             if (existingPendingIntent != null &&
3117                     existingPendingIntent.getIntent().filterEquals(intent)) {
3118                 return entry.getValue();
3119             }
3120         }
3121         return null;
3122     }
3123 
handleRegisterNetworkRequestWithIntent(Message msg)3124     private void handleRegisterNetworkRequestWithIntent(Message msg) {
3125         final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
3126 
3127         NetworkRequestInfo existingRequest = findExistingNetworkRequestInfo(nri.mPendingIntent);
3128         if (existingRequest != null) { // remove the existing request.
3129             if (DBG) log("Replacing " + existingRequest.request + " with "
3130                     + nri.request + " because their intents matched.");
3131             handleReleaseNetworkRequest(existingRequest.request, getCallingUid(),
3132                     /* callOnUnavailable */ false);
3133         }
3134         handleRegisterNetworkRequest(nri);
3135     }
3136 
handleRegisterNetworkRequest(NetworkRequestInfo nri)3137     private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
3138         mNetworkRequests.put(nri.request, nri);
3139         mNetworkRequestInfoLogs.log("REGISTER " + nri);
3140         if (nri.request.isListen()) {
3141             for (NetworkAgentInfo network : mNetworkAgentInfos.values()) {
3142                 if (nri.request.networkCapabilities.hasSignalStrength() &&
3143                         network.satisfiesImmutableCapabilitiesOf(nri.request)) {
3144                     updateSignalStrengthThresholds(network, "REGISTER", nri.request);
3145                 }
3146             }
3147         }
3148         rematchAllNetworksAndRequests(null, 0);
3149         if (nri.request.isRequest() && getNetworkForRequest(nri.request.requestId) == null) {
3150             sendUpdatedScoreToFactories(nri.request, null);
3151         }
3152     }
3153 
handleReleaseNetworkRequestWithIntent(PendingIntent pendingIntent, int callingUid)3154     private void handleReleaseNetworkRequestWithIntent(PendingIntent pendingIntent,
3155             int callingUid) {
3156         NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent);
3157         if (nri != null) {
3158             handleReleaseNetworkRequest(nri.request, callingUid, /* callOnUnavailable */ false);
3159         }
3160     }
3161 
3162     // Determines whether the network is the best (or could become the best, if it validated), for
3163     // none of a particular type of NetworkRequests. The type of NetworkRequests considered depends
3164     // on the value of reason:
3165     //
3166     // - UnneededFor.TEARDOWN: non-listen NetworkRequests. If a network is unneeded for this reason,
3167     //   then it should be torn down.
3168     // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason,
3169     //   then it should be lingered.
unneeded(NetworkAgentInfo nai, UnneededFor reason)3170     private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
3171         final int numRequests;
3172         switch (reason) {
3173             case TEARDOWN:
3174                 numRequests = nai.numRequestNetworkRequests();
3175                 break;
3176             case LINGER:
3177                 numRequests = nai.numForegroundNetworkRequests();
3178                 break;
3179             default:
3180                 Slog.wtf(TAG, "Invalid reason. Cannot happen.");
3181                 return true;
3182         }
3183 
3184         if (!nai.everConnected || nai.isVPN() || nai.isLingering() || numRequests > 0) {
3185             return false;
3186         }
3187         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
3188             if (reason == UnneededFor.LINGER && nri.request.isBackgroundRequest()) {
3189                 // Background requests don't affect lingering.
3190                 continue;
3191             }
3192 
3193             // If this Network is already the highest scoring Network for a request, or if
3194             // there is hope for it to become one if it validated, then it is needed.
3195             if (nri.request.isRequest() && nai.satisfies(nri.request) &&
3196                     (nai.isSatisfyingRequest(nri.request.requestId) ||
3197                     // Note that this catches two important cases:
3198                     // 1. Unvalidated cellular will not be reaped when unvalidated WiFi
3199                     //    is currently satisfying the request.  This is desirable when
3200                     //    cellular ends up validating but WiFi does not.
3201                     // 2. Unvalidated WiFi will not be reaped when validated cellular
3202                     //    is currently satisfying the request.  This is desirable when
3203                     //    WiFi ends up validating and out scoring cellular.
3204                     getNetworkForRequest(nri.request.requestId).getCurrentScore() <
3205                             nai.getCurrentScoreAsValidated())) {
3206                 return false;
3207             }
3208         }
3209         return true;
3210     }
3211 
getNriForAppRequest( NetworkRequest request, int callingUid, String requestedOperation)3212     private NetworkRequestInfo getNriForAppRequest(
3213             NetworkRequest request, int callingUid, String requestedOperation) {
3214         final NetworkRequestInfo nri = mNetworkRequests.get(request);
3215 
3216         if (nri != null) {
3217             if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) {
3218                 log(String.format("UID %d attempted to %s for unowned request %s",
3219                         callingUid, requestedOperation, nri));
3220                 return null;
3221             }
3222         }
3223 
3224         return nri;
3225     }
3226 
handleTimedOutNetworkRequest(final NetworkRequestInfo nri)3227     private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) {
3228         if (mNetworkRequests.get(nri.request) == null) {
3229             return;
3230         }
3231         if (getNetworkForRequest(nri.request.requestId) != null) {
3232             return;
3233         }
3234         if (VDBG || (DBG && nri.request.isRequest())) {
3235             log("releasing " + nri.request + " (timeout)");
3236         }
3237         handleRemoveNetworkRequest(nri);
3238         callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
3239     }
3240 
handleReleaseNetworkRequest(NetworkRequest request, int callingUid, boolean callOnUnavailable)3241     private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid,
3242             boolean callOnUnavailable) {
3243         final NetworkRequestInfo nri =
3244                 getNriForAppRequest(request, callingUid, "release NetworkRequest");
3245         if (nri == null) {
3246             return;
3247         }
3248         if (VDBG || (DBG && nri.request.isRequest())) {
3249             log("releasing " + nri.request + " (release request)");
3250         }
3251         handleRemoveNetworkRequest(nri);
3252         if (callOnUnavailable) {
3253             callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
3254         }
3255     }
3256 
handleRemoveNetworkRequest(final NetworkRequestInfo nri)3257     private void handleRemoveNetworkRequest(final NetworkRequestInfo nri) {
3258         nri.unlinkDeathRecipient();
3259         mNetworkRequests.remove(nri.request);
3260 
3261         synchronized (mUidToNetworkRequestCount) {
3262             int requests = mUidToNetworkRequestCount.get(nri.mUid, 0);
3263             if (requests < 1) {
3264                 Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " +
3265                         nri.mUid);
3266             } else if (requests == 1) {
3267                 mUidToNetworkRequestCount.removeAt(
3268                         mUidToNetworkRequestCount.indexOfKey(nri.mUid));
3269             } else {
3270                 mUidToNetworkRequestCount.put(nri.mUid, requests - 1);
3271             }
3272         }
3273 
3274         mNetworkRequestInfoLogs.log("RELEASE " + nri);
3275         if (nri.request.isRequest()) {
3276             boolean wasKept = false;
3277             NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId);
3278             if (nai != null) {
3279                 boolean wasBackgroundNetwork = nai.isBackgroundNetwork();
3280                 nai.removeRequest(nri.request.requestId);
3281                 if (VDBG || DDBG) {
3282                     log(" Removing from current network " + nai.name() +
3283                             ", leaving " + nai.numNetworkRequests() + " requests.");
3284                 }
3285                 // If there are still lingered requests on this network, don't tear it down,
3286                 // but resume lingering instead.
3287                 updateLingerState(nai, SystemClock.elapsedRealtime());
3288                 if (unneeded(nai, UnneededFor.TEARDOWN)) {
3289                     if (DBG) log("no live requests for " + nai.name() + "; disconnecting");
3290                     teardownUnneededNetwork(nai);
3291                 } else {
3292                     wasKept = true;
3293                 }
3294                 clearNetworkForRequest(nri.request.requestId);
3295                 if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) {
3296                     // Went from foreground to background.
3297                     updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
3298                 }
3299             }
3300 
3301             // Maintain the illusion.  When this request arrived, we might have pretended
3302             // that a network connected to serve it, even though the network was already
3303             // connected.  Now that this request has gone away, we might have to pretend
3304             // that the network disconnected.  LegacyTypeTracker will generate that
3305             // phantom disconnect for this type.
3306             if (nri.request.legacyType != TYPE_NONE && nai != null) {
3307                 boolean doRemove = true;
3308                 if (wasKept) {
3309                     // check if any of the remaining requests for this network are for the
3310                     // same legacy type - if so, don't remove the nai
3311                     for (int i = 0; i < nai.numNetworkRequests(); i++) {
3312                         NetworkRequest otherRequest = nai.requestAt(i);
3313                         if (otherRequest.legacyType == nri.request.legacyType &&
3314                                 otherRequest.isRequest()) {
3315                             if (DBG) log(" still have other legacy request - leaving");
3316                             doRemove = false;
3317                         }
3318                     }
3319                 }
3320 
3321                 if (doRemove) {
3322                     mLegacyTypeTracker.remove(nri.request.legacyType, nai, false);
3323                 }
3324             }
3325 
3326             for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
3327                 nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST,
3328                         nri.request);
3329             }
3330         } else {
3331             // listens don't have a singular affectedNetwork.  Check all networks to see
3332             // if this listen request applies and remove it.
3333             for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
3334                 nai.removeRequest(nri.request.requestId);
3335                 if (nri.request.networkCapabilities.hasSignalStrength() &&
3336                         nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
3337                     updateSignalStrengthThresholds(nai, "RELEASE", nri.request);
3338                 }
3339             }
3340         }
3341     }
3342 
3343     @Override
setAcceptUnvalidated(Network network, boolean accept, boolean always)3344     public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
3345         enforceNetworkStackSettingsOrSetup();
3346         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED,
3347                 encodeBool(accept), encodeBool(always), network));
3348     }
3349 
3350     @Override
setAcceptPartialConnectivity(Network network, boolean accept, boolean always)3351     public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) {
3352         enforceNetworkStackSettingsOrSetup();
3353         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY,
3354                 encodeBool(accept), encodeBool(always), network));
3355     }
3356 
3357     @Override
setAvoidUnvalidated(Network network)3358     public void setAvoidUnvalidated(Network network) {
3359         enforceNetworkStackSettingsOrSetup();
3360         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network));
3361     }
3362 
handleSetAcceptUnvalidated(Network network, boolean accept, boolean always)3363     private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) {
3364         if (DBG) log("handleSetAcceptUnvalidated network=" + network +
3365                 " accept=" + accept + " always=" + always);
3366 
3367         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3368         if (nai == null) {
3369             // Nothing to do.
3370             return;
3371         }
3372 
3373         if (nai.everValidated) {
3374             // The network validated while the dialog box was up. Take no action.
3375             return;
3376         }
3377 
3378         if (!nai.networkMisc.explicitlySelected) {
3379             Slog.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network");
3380         }
3381 
3382         if (accept != nai.networkMisc.acceptUnvalidated) {
3383             int oldScore = nai.getCurrentScore();
3384             nai.networkMisc.acceptUnvalidated = accept;
3385             // If network becomes partial connectivity and user already accepted to use this
3386             // network, we should respect the user's option and don't need to popup the
3387             // PARTIAL_CONNECTIVITY notification to user again.
3388             nai.networkMisc.acceptPartialConnectivity = accept;
3389             rematchAllNetworksAndRequests(nai, oldScore);
3390             sendUpdatedScoreToFactories(nai);
3391         }
3392 
3393         if (always) {
3394             nai.asyncChannel.sendMessage(
3395                     NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED, encodeBool(accept));
3396         }
3397 
3398         if (!accept) {
3399             // Tell the NetworkAgent to not automatically reconnect to the network.
3400             nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
3401             // Teardown the network.
3402             teardownUnneededNetwork(nai);
3403         }
3404 
3405     }
3406 
handleSetAcceptPartialConnectivity(Network network, boolean accept, boolean always)3407     private void handleSetAcceptPartialConnectivity(Network network, boolean accept,
3408             boolean always) {
3409         if (DBG) {
3410             log("handleSetAcceptPartialConnectivity network=" + network + " accept=" + accept
3411                     + " always=" + always);
3412         }
3413 
3414         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3415         if (nai == null) {
3416             // Nothing to do.
3417             return;
3418         }
3419 
3420         if (nai.lastValidated) {
3421             // The network validated while the dialog box was up. Take no action.
3422             return;
3423         }
3424 
3425         if (accept != nai.networkMisc.acceptPartialConnectivity) {
3426             nai.networkMisc.acceptPartialConnectivity = accept;
3427         }
3428 
3429         // TODO: Use the current design or save the user choice into IpMemoryStore.
3430         if (always) {
3431             nai.asyncChannel.sendMessage(
3432                     NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED, encodeBool(accept));
3433         }
3434 
3435         if (!accept) {
3436             // Tell the NetworkAgent to not automatically reconnect to the network.
3437             nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
3438             // Tear down the network.
3439             teardownUnneededNetwork(nai);
3440         } else {
3441             // Inform NetworkMonitor that partial connectivity is acceptable. This will likely
3442             // result in a partial connectivity result which will be processed by
3443             // maybeHandleNetworkMonitorMessage.
3444             //
3445             // TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored
3446             // per network. Therefore, NetworkMonitor may still do https probe.
3447             nai.networkMonitor().setAcceptPartialConnectivity();
3448         }
3449     }
3450 
handleSetAvoidUnvalidated(Network network)3451     private void handleSetAvoidUnvalidated(Network network) {
3452         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3453         if (nai == null || nai.lastValidated) {
3454             // Nothing to do. The network either disconnected or revalidated.
3455             return;
3456         }
3457         if (!nai.avoidUnvalidated) {
3458             int oldScore = nai.getCurrentScore();
3459             nai.avoidUnvalidated = true;
3460             rematchAllNetworksAndRequests(nai, oldScore);
3461             sendUpdatedScoreToFactories(nai);
3462         }
3463     }
3464 
scheduleUnvalidatedPrompt(NetworkAgentInfo nai)3465     private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) {
3466         if (VDBG) log("scheduleUnvalidatedPrompt " + nai.network);
3467         mHandler.sendMessageDelayed(
3468                 mHandler.obtainMessage(EVENT_PROMPT_UNVALIDATED, nai.network),
3469                 PROMPT_UNVALIDATED_DELAY_MS);
3470     }
3471 
3472     @Override
startCaptivePortalApp(Network network)3473     public void startCaptivePortalApp(Network network) {
3474         enforceConnectivityInternalPermission();
3475         mHandler.post(() -> {
3476             NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3477             if (nai == null) return;
3478             if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return;
3479             nai.networkMonitor().launchCaptivePortalApp();
3480         });
3481     }
3482 
3483     /**
3484      * NetworkStack endpoint to start the captive portal app. The NetworkStack needs to use this
3485      * endpoint as it does not have INTERACT_ACROSS_USERS_FULL itself.
3486      * @param network Network on which the captive portal was detected.
3487      * @param appExtras Bundle to use as intent extras for the captive portal application.
3488      *                  Must be treated as opaque to avoid preventing the captive portal app to
3489      *                  update its arguments.
3490      */
3491     @Override
startCaptivePortalAppInternal(Network network, Bundle appExtras)3492     public void startCaptivePortalAppInternal(Network network, Bundle appExtras) {
3493         mContext.enforceCallingOrSelfPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
3494                 "ConnectivityService");
3495 
3496         final Intent appIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
3497         appIntent.putExtras(appExtras);
3498         appIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL,
3499                 new CaptivePortal(new CaptivePortalImpl(network).asBinder()));
3500         appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
3501 
3502         // This runs on a random binder thread, but getNetworkAgentInfoForNetwork is thread-safe,
3503         // and captivePortalValidationPending is volatile.
3504         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3505         if (nai != null) {
3506             nai.captivePortalValidationPending = true;
3507         }
3508         Binder.withCleanCallingIdentity(() ->
3509                 mContext.startActivityAsUser(appIntent, UserHandle.CURRENT));
3510     }
3511 
3512     private class CaptivePortalImpl extends ICaptivePortal.Stub {
3513         private final Network mNetwork;
3514 
CaptivePortalImpl(Network network)3515         private CaptivePortalImpl(Network network) {
3516             mNetwork = network;
3517         }
3518 
3519         @Override
appResponse(final int response)3520         public void appResponse(final int response) {
3521             if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) {
3522                 enforceSettingsPermission();
3523             }
3524 
3525             // getNetworkAgentInfoForNetwork is thread-safe
3526             final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(mNetwork);
3527             if (nai == null) return;
3528 
3529             // nai.networkMonitor() is thread-safe
3530             final NetworkMonitorManager nm = nai.networkMonitor();
3531             if (nm == null) return;
3532             nm.notifyCaptivePortalAppFinished(response);
3533         }
3534 
3535         @Override
logEvent(int eventId, String packageName)3536         public void logEvent(int eventId, String packageName) {
3537             enforceSettingsPermission();
3538 
3539             new MetricsLogger().action(eventId, packageName);
3540         }
3541     }
3542 
avoidBadWifi()3543     public boolean avoidBadWifi() {
3544         return mMultinetworkPolicyTracker.getAvoidBadWifi();
3545     }
3546 
3547     /**
3548      * Return whether the device should maintain continuous, working connectivity by switching away
3549      * from WiFi networks having no connectivity.
3550      * @see MultinetworkPolicyTracker#getAvoidBadWifi()
3551      */
shouldAvoidBadWifi()3552     public boolean shouldAvoidBadWifi() {
3553         if (!checkNetworkStackPermission()) {
3554             throw new SecurityException("avoidBadWifi requires NETWORK_STACK permission");
3555         }
3556         return avoidBadWifi();
3557     }
3558 
3559 
rematchForAvoidBadWifiUpdate()3560     private void rematchForAvoidBadWifiUpdate() {
3561         rematchAllNetworksAndRequests(null, 0);
3562         for (NetworkAgentInfo nai: mNetworkAgentInfos.values()) {
3563             if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
3564                 sendUpdatedScoreToFactories(nai);
3565             }
3566         }
3567     }
3568 
3569     // TODO: Evaluate whether this is of interest to other consumers of
3570     // MultinetworkPolicyTracker and worth moving out of here.
dumpAvoidBadWifiSettings(IndentingPrintWriter pw)3571     private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) {
3572         final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi();
3573         if (!configRestrict) {
3574             pw.println("Bad Wi-Fi avoidance: unrestricted");
3575             return;
3576         }
3577 
3578         pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi());
3579         pw.increaseIndent();
3580         pw.println("Config restrict:   " + configRestrict);
3581 
3582         final String value = mMultinetworkPolicyTracker.getAvoidBadWifiSetting();
3583         String description;
3584         // Can't use a switch statement because strings are legal case labels, but null is not.
3585         if ("0".equals(value)) {
3586             description = "get stuck";
3587         } else if (value == null) {
3588             description = "prompt";
3589         } else if ("1".equals(value)) {
3590             description = "avoid";
3591         } else {
3592             description = value + " (?)";
3593         }
3594         pw.println("User setting:      " + description);
3595         pw.println("Network overrides:");
3596         pw.increaseIndent();
3597         for (NetworkAgentInfo nai : networksSortedById()) {
3598             if (nai.avoidUnvalidated) {
3599                 pw.println(nai.name());
3600             }
3601         }
3602         pw.decreaseIndent();
3603         pw.decreaseIndent();
3604     }
3605 
showNetworkNotification(NetworkAgentInfo nai, NotificationType type)3606     private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) {
3607         final String action;
3608         final boolean highPriority;
3609         switch (type) {
3610             case LOGGED_IN:
3611                 action = Settings.ACTION_WIFI_SETTINGS;
3612                 mHandler.removeMessages(EVENT_TIMEOUT_NOTIFICATION);
3613                 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NOTIFICATION,
3614                         nai.network.netId, 0), TIMEOUT_NOTIFICATION_DELAY_MS);
3615                 // High priority because it is a direct result of the user logging in to a portal.
3616                 highPriority = true;
3617                 break;
3618             case NO_INTERNET:
3619                 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED;
3620                 // High priority because it is only displayed for explicitly selected networks.
3621                 highPriority = true;
3622                 break;
3623             case LOST_INTERNET:
3624                 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION;
3625                 // High priority because it could help the user avoid unexpected data usage.
3626                 highPriority = true;
3627                 break;
3628             case PARTIAL_CONNECTIVITY:
3629                 action = ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY;
3630                 // Don't bother the user with a high-priority notification if the network was not
3631                 // explicitly selected by the user.
3632                 highPriority = nai.networkMisc.explicitlySelected;
3633                 break;
3634             default:
3635                 Slog.wtf(TAG, "Unknown notification type " + type);
3636                 return;
3637         }
3638 
3639         Intent intent = new Intent(action);
3640         if (type != NotificationType.LOGGED_IN) {
3641             intent.setData(Uri.fromParts("netId", Integer.toString(nai.network.netId), null));
3642             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3643             intent.setClassName("com.android.settings",
3644                     "com.android.settings.wifi.WifiNoInternetDialog");
3645         }
3646 
3647         PendingIntent pendingIntent = PendingIntent.getActivityAsUser(
3648                 mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
3649 
3650         mNotifier.showNotification(nai.network.netId, type, nai, null, pendingIntent, highPriority);
3651     }
3652 
shouldPromptUnvalidated(NetworkAgentInfo nai)3653     private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) {
3654         // Don't prompt if the network is validated, and don't prompt on captive portals
3655         // because we're already prompting the user to sign in.
3656         if (nai.everValidated || nai.everCaptivePortalDetected) {
3657             return false;
3658         }
3659 
3660         // If a network has partial connectivity, always prompt unless the user has already accepted
3661         // partial connectivity and selected don't ask again. This ensures that if the device
3662         // automatically connects to a network that has partial Internet access, the user will
3663         // always be able to use it, either because they've already chosen "don't ask again" or
3664         // because we have prompt them.
3665         if (nai.partialConnectivity && !nai.networkMisc.acceptPartialConnectivity) {
3666             return true;
3667         }
3668 
3669         // If a network has no Internet access, only prompt if the network was explicitly selected
3670         // and if the user has not already told us to use the network regardless of whether it
3671         // validated or not.
3672         if (nai.networkMisc.explicitlySelected && !nai.networkMisc.acceptUnvalidated) {
3673             return true;
3674         }
3675 
3676         return false;
3677     }
3678 
handlePromptUnvalidated(Network network)3679     private void handlePromptUnvalidated(Network network) {
3680         if (VDBG || DDBG) log("handlePromptUnvalidated " + network);
3681         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3682 
3683         if (nai == null || !shouldPromptUnvalidated(nai)) {
3684             return;
3685         }
3686 
3687         // Stop automatically reconnecting to this network in the future. Automatically connecting
3688         // to a network that provides no or limited connectivity is not useful, because the user
3689         // cannot use that network except through the notification shown by this method, and the
3690         // notification is only shown if the network is explicitly selected by the user.
3691         nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
3692 
3693         // TODO: Evaluate if it's needed to wait 8 seconds for triggering notification when
3694         // NetworkMonitor detects the network is partial connectivity. Need to change the design to
3695         // popup the notification immediately when the network is partial connectivity.
3696         if (nai.partialConnectivity) {
3697             showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY);
3698         } else {
3699             showNetworkNotification(nai, NotificationType.NO_INTERNET);
3700         }
3701     }
3702 
handleNetworkUnvalidated(NetworkAgentInfo nai)3703     private void handleNetworkUnvalidated(NetworkAgentInfo nai) {
3704         NetworkCapabilities nc = nai.networkCapabilities;
3705         if (DBG) log("handleNetworkUnvalidated " + nai.name() + " cap=" + nc);
3706 
3707         if (!nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
3708             return;
3709         }
3710 
3711         if (mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) {
3712             showNetworkNotification(nai, NotificationType.LOST_INTERNET);
3713         }
3714     }
3715 
3716     @Override
getMultipathPreference(Network network)3717     public int getMultipathPreference(Network network) {
3718         enforceAccessPermission();
3719 
3720         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3721         if (nai != null && nai.networkCapabilities
3722                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
3723             return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
3724         }
3725 
3726         Integer networkPreference = mMultipathPolicyTracker.getMultipathPreference(network);
3727         if (networkPreference != null) {
3728             return networkPreference;
3729         }
3730 
3731         return mMultinetworkPolicyTracker.getMeteredMultipathPreference();
3732     }
3733 
3734     @Override
getDefaultRequest()3735     public NetworkRequest getDefaultRequest() {
3736         return mDefaultRequest;
3737     }
3738 
3739     private class InternalHandler extends Handler {
InternalHandler(Looper looper)3740         public InternalHandler(Looper looper) {
3741             super(looper);
3742         }
3743 
3744         @Override
handleMessage(Message msg)3745         public void handleMessage(Message msg) {
3746             switch (msg.what) {
3747                 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK:
3748                 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: {
3749                     handleReleaseNetworkTransitionWakelock(msg.what);
3750                     break;
3751                 }
3752                 case EVENT_APPLY_GLOBAL_HTTP_PROXY: {
3753                     mProxyTracker.loadDeprecatedGlobalHttpProxy();
3754                     break;
3755                 }
3756                 case EVENT_PROXY_HAS_CHANGED: {
3757                     handleApplyDefaultProxy((ProxyInfo)msg.obj);
3758                     break;
3759                 }
3760                 case EVENT_REGISTER_NETWORK_FACTORY: {
3761                     handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj);
3762                     break;
3763                 }
3764                 case EVENT_UNREGISTER_NETWORK_FACTORY: {
3765                     handleUnregisterNetworkFactory((Messenger)msg.obj);
3766                     break;
3767                 }
3768                 case EVENT_REGISTER_NETWORK_AGENT: {
3769                     final Pair<NetworkAgentInfo, INetworkMonitor> arg =
3770                             (Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj;
3771                     handleRegisterNetworkAgent(arg.first, arg.second);
3772                     break;
3773                 }
3774                 case EVENT_REGISTER_NETWORK_REQUEST:
3775                 case EVENT_REGISTER_NETWORK_LISTENER: {
3776                     handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj);
3777                     break;
3778                 }
3779                 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT:
3780                 case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: {
3781                     handleRegisterNetworkRequestWithIntent(msg);
3782                     break;
3783                 }
3784                 case EVENT_TIMEOUT_NETWORK_REQUEST: {
3785                     NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj;
3786                     handleTimedOutNetworkRequest(nri);
3787                     break;
3788                 }
3789                 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: {
3790                     handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1);
3791                     break;
3792                 }
3793                 case EVENT_RELEASE_NETWORK_REQUEST: {
3794                     handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1,
3795                             /* callOnUnavailable */ false);
3796                     break;
3797                 }
3798                 case EVENT_SET_ACCEPT_UNVALIDATED: {
3799                     Network network = (Network) msg.obj;
3800                     handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2));
3801                     break;
3802                 }
3803                 case EVENT_SET_ACCEPT_PARTIAL_CONNECTIVITY: {
3804                     Network network = (Network) msg.obj;
3805                     handleSetAcceptPartialConnectivity(network, toBool(msg.arg1),
3806                             toBool(msg.arg2));
3807                     break;
3808                 }
3809                 case EVENT_SET_AVOID_UNVALIDATED: {
3810                     handleSetAvoidUnvalidated((Network) msg.obj);
3811                     break;
3812                 }
3813                 case EVENT_PROMPT_UNVALIDATED: {
3814                     handlePromptUnvalidated((Network) msg.obj);
3815                     break;
3816                 }
3817                 case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: {
3818                     handleConfigureAlwaysOnNetworks();
3819                     break;
3820                 }
3821                 // Sent by KeepaliveTracker to process an app request on the state machine thread.
3822                 case NetworkAgent.CMD_START_SOCKET_KEEPALIVE: {
3823                     mKeepaliveTracker.handleStartKeepalive(msg);
3824                     break;
3825                 }
3826                 // Sent by KeepaliveTracker to process an app request on the state machine thread.
3827                 case NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE: {
3828                     NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj);
3829                     int slot = msg.arg1;
3830                     int reason = msg.arg2;
3831                     mKeepaliveTracker.handleStopKeepalive(nai, slot, reason);
3832                     break;
3833                 }
3834                 case EVENT_SYSTEM_READY: {
3835                     mMultipathPolicyTracker.start();
3836                     break;
3837                 }
3838                 case EVENT_REVALIDATE_NETWORK: {
3839                     handleReportNetworkConnectivity((Network) msg.obj, msg.arg1, toBool(msg.arg2));
3840                     break;
3841                 }
3842                 case EVENT_PRIVATE_DNS_SETTINGS_CHANGED:
3843                     handlePrivateDnsSettingsChanged();
3844                     break;
3845                 case EVENT_PRIVATE_DNS_VALIDATION_UPDATE:
3846                     handlePrivateDnsValidationUpdate(
3847                             (PrivateDnsValidationUpdate) msg.obj);
3848                     break;
3849                 case EVENT_UID_RULES_CHANGED:
3850                     handleUidRulesChanged(msg.arg1, msg.arg2);
3851                     break;
3852                 case EVENT_DATA_SAVER_CHANGED:
3853                     handleRestrictBackgroundChanged(toBool(msg.arg1));
3854                     break;
3855                 case EVENT_TIMEOUT_NOTIFICATION:
3856                     mNotifier.clearNotification(msg.arg1, NotificationType.LOGGED_IN);
3857                     break;
3858             }
3859         }
3860     }
3861 
3862     // javadoc from interface
3863     @Override
tether(String iface, String callerPkg)3864     public int tether(String iface, String callerPkg) {
3865         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
3866         if (isTetheringSupported()) {
3867             return mTethering.tether(iface);
3868         } else {
3869             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
3870         }
3871     }
3872 
3873     // javadoc from interface
3874     @Override
untether(String iface, String callerPkg)3875     public int untether(String iface, String callerPkg) {
3876         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
3877 
3878         if (isTetheringSupported()) {
3879             return mTethering.untether(iface);
3880         } else {
3881             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
3882         }
3883     }
3884 
3885     // javadoc from interface
3886     @Override
getLastTetherError(String iface)3887     public int getLastTetherError(String iface) {
3888         enforceTetherAccessPermission();
3889 
3890         if (isTetheringSupported()) {
3891             return mTethering.getLastTetherError(iface);
3892         } else {
3893             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
3894         }
3895     }
3896 
3897     // TODO - proper iface API for selection by property, inspection, etc
3898     @Override
getTetherableUsbRegexs()3899     public String[] getTetherableUsbRegexs() {
3900         enforceTetherAccessPermission();
3901         if (isTetheringSupported()) {
3902             return mTethering.getTetherableUsbRegexs();
3903         } else {
3904             return new String[0];
3905         }
3906     }
3907 
3908     @Override
getTetherableWifiRegexs()3909     public String[] getTetherableWifiRegexs() {
3910         enforceTetherAccessPermission();
3911         if (isTetheringSupported()) {
3912             return mTethering.getTetherableWifiRegexs();
3913         } else {
3914             return new String[0];
3915         }
3916     }
3917 
3918     @Override
getTetherableBluetoothRegexs()3919     public String[] getTetherableBluetoothRegexs() {
3920         enforceTetherAccessPermission();
3921         if (isTetheringSupported()) {
3922             return mTethering.getTetherableBluetoothRegexs();
3923         } else {
3924             return new String[0];
3925         }
3926     }
3927 
3928     @Override
setUsbTethering(boolean enable, String callerPkg)3929     public int setUsbTethering(boolean enable, String callerPkg) {
3930         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
3931         if (isTetheringSupported()) {
3932             return mTethering.setUsbTethering(enable);
3933         } else {
3934             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
3935         }
3936     }
3937 
3938     // TODO - move iface listing, queries, etc to new module
3939     // javadoc from interface
3940     @Override
getTetherableIfaces()3941     public String[] getTetherableIfaces() {
3942         enforceTetherAccessPermission();
3943         return mTethering.getTetherableIfaces();
3944     }
3945 
3946     @Override
getTetheredIfaces()3947     public String[] getTetheredIfaces() {
3948         enforceTetherAccessPermission();
3949         return mTethering.getTetheredIfaces();
3950     }
3951 
3952     @Override
getTetheringErroredIfaces()3953     public String[] getTetheringErroredIfaces() {
3954         enforceTetherAccessPermission();
3955         return mTethering.getErroredIfaces();
3956     }
3957 
3958     @Override
getTetheredDhcpRanges()3959     public String[] getTetheredDhcpRanges() {
3960         enforceConnectivityInternalPermission();
3961         return mTethering.getTetheredDhcpRanges();
3962     }
3963 
3964     @Override
isTetheringSupported(String callerPkg)3965     public boolean isTetheringSupported(String callerPkg) {
3966         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
3967         return isTetheringSupported();
3968     }
3969 
3970     // if ro.tether.denied = true we default to no tethering
3971     // gservices could set the secure setting to 1 though to enable it on a build where it
3972     // had previously been turned off.
isTetheringSupported()3973     private boolean isTetheringSupported() {
3974         int defaultVal = encodeBool(!mSystemProperties.get("ro.tether.denied").equals("true"));
3975         boolean tetherSupported = toBool(Settings.Global.getInt(mContext.getContentResolver(),
3976                 Settings.Global.TETHER_SUPPORTED, defaultVal));
3977         boolean tetherEnabledInSettings = tetherSupported
3978                 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
3979 
3980         // Elevate to system UID to avoid caller requiring MANAGE_USERS permission.
3981         boolean adminUser = false;
3982         final long token = Binder.clearCallingIdentity();
3983         try {
3984             adminUser = mUserManager.isAdminUser();
3985         } finally {
3986             Binder.restoreCallingIdentity(token);
3987         }
3988 
3989         return tetherEnabledInSettings && adminUser && mTethering.hasTetherableConfiguration();
3990     }
3991 
3992     @Override
startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi, String callerPkg)3993     public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi,
3994             String callerPkg) {
3995         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
3996         if (!isTetheringSupported()) {
3997             receiver.send(ConnectivityManager.TETHER_ERROR_UNSUPPORTED, null);
3998             return;
3999         }
4000         mTethering.startTethering(type, receiver, showProvisioningUi);
4001     }
4002 
4003     @Override
stopTethering(int type, String callerPkg)4004     public void stopTethering(int type, String callerPkg) {
4005         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
4006         mTethering.stopTethering(type);
4007     }
4008 
4009     /**
4010      * Get the latest value of the tethering entitlement check.
4011      *
4012      * Note: Allow privileged apps who have TETHER_PRIVILEGED permission to access. If it turns
4013      * out some such apps are observed to abuse this API, change to per-UID limits on this API
4014      * if it's really needed.
4015      */
4016     @Override
getLatestTetheringEntitlementResult(int type, ResultReceiver receiver, boolean showEntitlementUi, String callerPkg)4017     public void getLatestTetheringEntitlementResult(int type, ResultReceiver receiver,
4018             boolean showEntitlementUi, String callerPkg) {
4019         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
4020         mTethering.getLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
4021     }
4022 
4023     /** Register tethering event callback. */
4024     @Override
registerTetheringEventCallback(ITetheringEventCallback callback, String callerPkg)4025     public void registerTetheringEventCallback(ITetheringEventCallback callback,
4026             String callerPkg) {
4027         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
4028         mTethering.registerTetheringEventCallback(callback);
4029     }
4030 
4031     /** Unregister tethering event callback. */
4032     @Override
unregisterTetheringEventCallback(ITetheringEventCallback callback, String callerPkg)4033     public void unregisterTetheringEventCallback(ITetheringEventCallback callback,
4034             String callerPkg) {
4035         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
4036         mTethering.unregisterTetheringEventCallback(callback);
4037     }
4038 
4039     // Called when we lose the default network and have no replacement yet.
4040     // This will automatically be cleared after X seconds or a new default network
4041     // becomes CONNECTED, whichever happens first.  The timer is started by the
4042     // first caller and not restarted by subsequent callers.
ensureNetworkTransitionWakelock(String forWhom)4043     private void ensureNetworkTransitionWakelock(String forWhom) {
4044         synchronized (this) {
4045             if (mNetTransitionWakeLock.isHeld()) {
4046                 return;
4047             }
4048             mNetTransitionWakeLock.acquire();
4049             mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime();
4050             mTotalWakelockAcquisitions++;
4051         }
4052         mWakelockLogs.log("ACQUIRE for " + forWhom);
4053         Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
4054         mHandler.sendMessageDelayed(msg, mNetTransitionWakeLockTimeout);
4055     }
4056 
4057     // Called when we gain a new default network to release the network transition wakelock in a
4058     // second, to allow a grace period for apps to reconnect over the new network. Pending expiry
4059     // message is cancelled.
scheduleReleaseNetworkTransitionWakelock()4060     private void scheduleReleaseNetworkTransitionWakelock() {
4061         synchronized (this) {
4062             if (!mNetTransitionWakeLock.isHeld()) {
4063                 return; // expiry message released the lock first.
4064             }
4065         }
4066         // Cancel self timeout on wakelock hold.
4067         mHandler.removeMessages(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
4068         Message msg = mHandler.obtainMessage(EVENT_CLEAR_NET_TRANSITION_WAKELOCK);
4069         mHandler.sendMessageDelayed(msg, 1000);
4070     }
4071 
4072     // Called when either message of ensureNetworkTransitionWakelock or
4073     // scheduleReleaseNetworkTransitionWakelock is processed.
handleReleaseNetworkTransitionWakelock(int eventId)4074     private void handleReleaseNetworkTransitionWakelock(int eventId) {
4075         String event = eventName(eventId);
4076         synchronized (this) {
4077             if (!mNetTransitionWakeLock.isHeld()) {
4078                 mWakelockLogs.log(String.format("RELEASE: already released (%s)", event));
4079                 Slog.w(TAG, "expected Net Transition WakeLock to be held");
4080                 return;
4081             }
4082             mNetTransitionWakeLock.release();
4083             long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
4084             mTotalWakelockDurationMs += lockDuration;
4085             mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration);
4086             mTotalWakelockReleases++;
4087         }
4088         mWakelockLogs.log(String.format("RELEASE (%s)", event));
4089     }
4090 
4091     // 100 percent is full good, 0 is full bad.
4092     @Override
reportInetCondition(int networkType, int percentage)4093     public void reportInetCondition(int networkType, int percentage) {
4094         NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
4095         if (nai == null) return;
4096         reportNetworkConnectivity(nai.network, percentage > 50);
4097     }
4098 
4099     @Override
reportNetworkConnectivity(Network network, boolean hasConnectivity)4100     public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
4101         enforceAccessPermission();
4102         enforceInternetPermission();
4103         final int uid = Binder.getCallingUid();
4104         final int connectivityInfo = encodeBool(hasConnectivity);
4105         mHandler.sendMessage(
4106                 mHandler.obtainMessage(EVENT_REVALIDATE_NETWORK, uid, connectivityInfo, network));
4107     }
4108 
handleReportNetworkConnectivity( Network network, int uid, boolean hasConnectivity)4109     private void handleReportNetworkConnectivity(
4110             Network network, int uid, boolean hasConnectivity) {
4111         final NetworkAgentInfo nai;
4112         if (network == null) {
4113             nai = getDefaultNetwork();
4114         } else {
4115             nai = getNetworkAgentInfoForNetwork(network);
4116         }
4117         if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING ||
4118             nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
4119             return;
4120         }
4121         // Revalidate if the app report does not match our current validated state.
4122         if (hasConnectivity == nai.lastValidated) {
4123             return;
4124         }
4125         if (DBG) {
4126             int netid = nai.network.netId;
4127             log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid);
4128         }
4129         // Validating a network that has not yet connected could result in a call to
4130         // rematchNetworkAndRequests() which is not meant to work on such networks.
4131         if (!nai.everConnected) {
4132             return;
4133         }
4134         LinkProperties lp = getLinkProperties(nai);
4135         if (isNetworkWithLinkPropertiesBlocked(lp, uid, false)) {
4136             return;
4137         }
4138         nai.networkMonitor().forceReevaluation(uid);
4139     }
4140 
4141     /**
4142      * Returns information about the proxy a certain network is using. If given a null network, it
4143      * it will return the proxy for the bound network for the caller app or the default proxy if
4144      * none.
4145      *
4146      * @param network the network we want to get the proxy information for.
4147      * @return Proxy information if a network has a proxy configured, or otherwise null.
4148      */
4149     @Override
getProxyForNetwork(Network network)4150     public ProxyInfo getProxyForNetwork(Network network) {
4151         final ProxyInfo globalProxy = mProxyTracker.getGlobalProxy();
4152         if (globalProxy != null) return globalProxy;
4153         if (network == null) {
4154             // Get the network associated with the calling UID.
4155             final Network activeNetwork = getActiveNetworkForUidInternal(Binder.getCallingUid(),
4156                     true);
4157             if (activeNetwork == null) {
4158                 return null;
4159             }
4160             return getLinkPropertiesProxyInfo(activeNetwork);
4161         } else if (queryUserAccess(Binder.getCallingUid(), network.netId)) {
4162             // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which
4163             // caller may not have.
4164             return getLinkPropertiesProxyInfo(network);
4165         }
4166         // No proxy info available if the calling UID does not have network access.
4167         return null;
4168     }
4169 
4170     @VisibleForTesting
queryUserAccess(int uid, int netId)4171     protected boolean queryUserAccess(int uid, int netId) {
4172         return NetworkUtils.queryUserAccess(uid, netId);
4173     }
4174 
getLinkPropertiesProxyInfo(Network network)4175     private ProxyInfo getLinkPropertiesProxyInfo(Network network) {
4176         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
4177         if (nai == null) return null;
4178         synchronized (nai) {
4179             final ProxyInfo linkHttpProxy = nai.linkProperties.getHttpProxy();
4180             return linkHttpProxy == null ? null : new ProxyInfo(linkHttpProxy);
4181         }
4182     }
4183 
4184     @Override
setGlobalProxy(final ProxyInfo proxyProperties)4185     public void setGlobalProxy(final ProxyInfo proxyProperties) {
4186         enforceConnectivityInternalPermission();
4187         mProxyTracker.setGlobalProxy(proxyProperties);
4188     }
4189 
4190     @Override
4191     @Nullable
getGlobalProxy()4192     public ProxyInfo getGlobalProxy() {
4193         return mProxyTracker.getGlobalProxy();
4194     }
4195 
handleApplyDefaultProxy(ProxyInfo proxy)4196     private void handleApplyDefaultProxy(ProxyInfo proxy) {
4197         if (proxy != null && TextUtils.isEmpty(proxy.getHost())
4198                 && Uri.EMPTY.equals(proxy.getPacFileUrl())) {
4199             proxy = null;
4200         }
4201         mProxyTracker.setDefaultProxy(proxy);
4202     }
4203 
4204     // If the proxy has changed from oldLp to newLp, resend proxy broadcast. This method gets called
4205     // when any network changes proxy.
4206     // TODO: Remove usage of broadcast extras as they are deprecated and not applicable in a
4207     // multi-network world where an app might be bound to a non-default network.
updateProxy(LinkProperties newLp, LinkProperties oldLp)4208     private void updateProxy(LinkProperties newLp, LinkProperties oldLp) {
4209         ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy();
4210         ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
4211 
4212         if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
4213             mProxyTracker.sendProxyBroadcast();
4214         }
4215     }
4216 
4217     private static class SettingsObserver extends ContentObserver {
4218         final private HashMap<Uri, Integer> mUriEventMap;
4219         final private Context mContext;
4220         final private Handler mHandler;
4221 
SettingsObserver(Context context, Handler handler)4222         SettingsObserver(Context context, Handler handler) {
4223             super(null);
4224             mUriEventMap = new HashMap<>();
4225             mContext = context;
4226             mHandler = handler;
4227         }
4228 
observe(Uri uri, int what)4229         void observe(Uri uri, int what) {
4230             mUriEventMap.put(uri, what);
4231             final ContentResolver resolver = mContext.getContentResolver();
4232             resolver.registerContentObserver(uri, false, this);
4233         }
4234 
4235         @Override
onChange(boolean selfChange)4236         public void onChange(boolean selfChange) {
4237             Slog.wtf(TAG, "Should never be reached.");
4238         }
4239 
4240         @Override
onChange(boolean selfChange, Uri uri)4241         public void onChange(boolean selfChange, Uri uri) {
4242             final Integer what = mUriEventMap.get(uri);
4243             if (what != null) {
4244                 mHandler.obtainMessage(what.intValue()).sendToTarget();
4245             } else {
4246                 loge("No matching event to send for URI=" + uri);
4247             }
4248         }
4249     }
4250 
log(String s)4251     private static void log(String s) {
4252         Slog.d(TAG, s);
4253     }
4254 
loge(String s)4255     private static void loge(String s) {
4256         Slog.e(TAG, s);
4257     }
4258 
loge(String s, Throwable t)4259     private static void loge(String s, Throwable t) {
4260         Slog.e(TAG, s, t);
4261     }
4262 
4263     /**
4264      * Prepare for a VPN application.
4265      * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId},
4266      * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
4267      *
4268      * @param oldPackage Package name of the application which currently controls VPN, which will
4269      *                   be replaced. If there is no such application, this should should either be
4270      *                   {@code null} or {@link VpnConfig.LEGACY_VPN}.
4271      * @param newPackage Package name of the application which should gain control of VPN, or
4272      *                   {@code null} to disable.
4273      * @param userId User for whom to prepare the new VPN.
4274      *
4275      * @hide
4276      */
4277     @Override
prepareVpn(@ullable String oldPackage, @Nullable String newPackage, int userId)4278     public boolean prepareVpn(@Nullable String oldPackage, @Nullable String newPackage,
4279             int userId) {
4280         enforceCrossUserPermission(userId);
4281 
4282         synchronized (mVpns) {
4283             throwIfLockdownEnabled();
4284             Vpn vpn = mVpns.get(userId);
4285             if (vpn != null) {
4286                 return vpn.prepare(oldPackage, newPackage);
4287             } else {
4288                 return false;
4289             }
4290         }
4291     }
4292 
4293     /**
4294      * Set whether the VPN package has the ability to launch VPNs without user intervention.
4295      * This method is used by system-privileged apps.
4296      * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId},
4297      * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
4298      *
4299      * @param packageName The package for which authorization state should change.
4300      * @param userId User for whom {@code packageName} is installed.
4301      * @param authorized {@code true} if this app should be able to start a VPN connection without
4302      *                   explicit user approval, {@code false} if not.
4303      *
4304      * @hide
4305      */
4306     @Override
setVpnPackageAuthorization(String packageName, int userId, boolean authorized)4307     public void setVpnPackageAuthorization(String packageName, int userId, boolean authorized) {
4308         enforceCrossUserPermission(userId);
4309 
4310         synchronized (mVpns) {
4311             Vpn vpn = mVpns.get(userId);
4312             if (vpn != null) {
4313                 vpn.setPackageAuthorization(packageName, authorized);
4314             }
4315         }
4316     }
4317 
4318     /**
4319      * Configure a TUN interface and return its file descriptor. Parameters
4320      * are encoded and opaque to this class. This method is used by VpnBuilder
4321      * and not available in ConnectivityManager. Permissions are checked in
4322      * Vpn class.
4323      * @hide
4324      */
4325     @Override
establishVpn(VpnConfig config)4326     public ParcelFileDescriptor establishVpn(VpnConfig config) {
4327         int user = UserHandle.getUserId(Binder.getCallingUid());
4328         synchronized (mVpns) {
4329             throwIfLockdownEnabled();
4330             return mVpns.get(user).establish(config);
4331         }
4332     }
4333 
4334     /**
4335      * Start legacy VPN, controlling native daemons as needed. Creates a
4336      * secondary thread to perform connection work, returning quickly.
4337      */
4338     @Override
startLegacyVpn(VpnProfile profile)4339     public void startLegacyVpn(VpnProfile profile) {
4340         int user = UserHandle.getUserId(Binder.getCallingUid());
4341         final LinkProperties egress = getActiveLinkProperties();
4342         if (egress == null) {
4343             throw new IllegalStateException("Missing active network connection");
4344         }
4345         synchronized (mVpns) {
4346             throwIfLockdownEnabled();
4347             mVpns.get(user).startLegacyVpn(profile, mKeyStore, egress);
4348         }
4349     }
4350 
4351     /**
4352      * Return the information of the ongoing legacy VPN. This method is used
4353      * by VpnSettings and not available in ConnectivityManager. Permissions
4354      * are checked in Vpn class.
4355      */
4356     @Override
getLegacyVpnInfo(int userId)4357     public LegacyVpnInfo getLegacyVpnInfo(int userId) {
4358         enforceCrossUserPermission(userId);
4359 
4360         synchronized (mVpns) {
4361             return mVpns.get(userId).getLegacyVpnInfo();
4362         }
4363     }
4364 
4365     /**
4366      * Return the information of all ongoing VPNs.
4367      *
4368      * <p>This method is used to update NetworkStatsService.
4369      *
4370      * <p>Must be called on the handler thread.
4371      */
getAllVpnInfo()4372     private VpnInfo[] getAllVpnInfo() {
4373         ensureRunningOnConnectivityServiceThread();
4374         synchronized (mVpns) {
4375             if (mLockdownEnabled) {
4376                 return new VpnInfo[0];
4377             }
4378 
4379             List<VpnInfo> infoList = new ArrayList<>();
4380             for (int i = 0; i < mVpns.size(); i++) {
4381                 VpnInfo info = createVpnInfo(mVpns.valueAt(i));
4382                 if (info != null) {
4383                     infoList.add(info);
4384                 }
4385             }
4386             return infoList.toArray(new VpnInfo[infoList.size()]);
4387         }
4388     }
4389 
4390     /**
4391      * @return VPN information for accounting, or null if we can't retrieve all required
4392      *         information, e.g primary underlying iface.
4393      */
4394     @Nullable
createVpnInfo(Vpn vpn)4395     private VpnInfo createVpnInfo(Vpn vpn) {
4396         VpnInfo info = vpn.getVpnInfo();
4397         if (info == null) {
4398             return null;
4399         }
4400         Network[] underlyingNetworks = vpn.getUnderlyingNetworks();
4401         // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret
4402         // the underlyingNetworks list.
4403         if (underlyingNetworks == null) {
4404             NetworkAgentInfo defaultNetwork = getDefaultNetwork();
4405             if (defaultNetwork != null && defaultNetwork.linkProperties != null) {
4406                 info.primaryUnderlyingIface = getDefaultNetwork().linkProperties.getInterfaceName();
4407             }
4408         } else if (underlyingNetworks.length > 0) {
4409             LinkProperties linkProperties = getLinkProperties(underlyingNetworks[0]);
4410             if (linkProperties != null) {
4411                 info.primaryUnderlyingIface = linkProperties.getInterfaceName();
4412             }
4413         }
4414         return info.primaryUnderlyingIface == null ? null : info;
4415     }
4416 
4417     /**
4418      * Returns the information of the ongoing VPN for {@code userId}. This method is used by
4419      * VpnDialogs and not available in ConnectivityManager.
4420      * Permissions are checked in Vpn class.
4421      * @hide
4422      */
4423     @Override
getVpnConfig(int userId)4424     public VpnConfig getVpnConfig(int userId) {
4425         enforceCrossUserPermission(userId);
4426         synchronized (mVpns) {
4427             Vpn vpn = mVpns.get(userId);
4428             if (vpn != null) {
4429                 return vpn.getVpnConfig();
4430             } else {
4431                 return null;
4432             }
4433         }
4434     }
4435 
4436     /**
4437      * Ask all VPN objects to recompute and update their capabilities.
4438      *
4439      * When underlying networks change, VPNs may have to update capabilities to reflect things
4440      * like the metered bit, their transports, and so on. This asks the VPN objects to update
4441      * their capabilities, and as this will cause them to send messages to the ConnectivityService
4442      * handler thread through their agent, this is asynchronous. When the capabilities objects
4443      * are computed they will be up-to-date as they are computed synchronously from here and
4444      * this is running on the ConnectivityService thread.
4445      */
updateAllVpnsCapabilities()4446     private void updateAllVpnsCapabilities() {
4447         Network defaultNetwork = getNetwork(getDefaultNetwork());
4448         synchronized (mVpns) {
4449             for (int i = 0; i < mVpns.size(); i++) {
4450                 final Vpn vpn = mVpns.valueAt(i);
4451                 NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork);
4452                 updateVpnCapabilities(vpn, nc);
4453             }
4454         }
4455     }
4456 
updateVpnCapabilities(Vpn vpn, @Nullable NetworkCapabilities nc)4457     private void updateVpnCapabilities(Vpn vpn, @Nullable NetworkCapabilities nc) {
4458         ensureRunningOnConnectivityServiceThread();
4459         NetworkAgentInfo vpnNai = getNetworkAgentInfoForNetId(vpn.getNetId());
4460         if (vpnNai == null || nc == null) {
4461             return;
4462         }
4463         updateCapabilities(vpnNai.getCurrentScore(), vpnNai, nc);
4464     }
4465 
4466     @Override
updateLockdownVpn()4467     public boolean updateLockdownVpn() {
4468         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
4469             Slog.w(TAG, "Lockdown VPN only available to AID_SYSTEM");
4470             return false;
4471         }
4472 
4473         synchronized (mVpns) {
4474             // Tear down existing lockdown if profile was removed
4475             mLockdownEnabled = LockdownVpnTracker.isEnabled();
4476             if (mLockdownEnabled) {
4477                 byte[] profileTag = mKeyStore.get(Credentials.LOCKDOWN_VPN);
4478                 if (profileTag == null) {
4479                     Slog.e(TAG, "Lockdown VPN configured but cannot be read from keystore");
4480                     return false;
4481                 }
4482                 String profileName = new String(profileTag);
4483                 final VpnProfile profile = VpnProfile.decode(
4484                         profileName, mKeyStore.get(Credentials.VPN + profileName));
4485                 if (profile == null) {
4486                     Slog.e(TAG, "Lockdown VPN configured invalid profile " + profileName);
4487                     setLockdownTracker(null);
4488                     return true;
4489                 }
4490                 int user = UserHandle.getUserId(Binder.getCallingUid());
4491                 Vpn vpn = mVpns.get(user);
4492                 if (vpn == null) {
4493                     Slog.w(TAG, "VPN for user " + user + " not ready yet. Skipping lockdown");
4494                     return false;
4495                 }
4496                 setLockdownTracker(new LockdownVpnTracker(mContext, mNMS, this, vpn, profile));
4497             } else {
4498                 setLockdownTracker(null);
4499             }
4500         }
4501 
4502         return true;
4503     }
4504 
4505     /**
4506      * Internally set new {@link LockdownVpnTracker}, shutting down any existing
4507      * {@link LockdownVpnTracker}. Can be {@code null} to disable lockdown.
4508      */
4509     @GuardedBy("mVpns")
setLockdownTracker(LockdownVpnTracker tracker)4510     private void setLockdownTracker(LockdownVpnTracker tracker) {
4511         // Shutdown any existing tracker
4512         final LockdownVpnTracker existing = mLockdownTracker;
4513         // TODO: Add a trigger when the always-on VPN enable/disable to reevaluate and send the
4514         // necessary onBlockedStatusChanged callbacks.
4515         mLockdownTracker = null;
4516         if (existing != null) {
4517             existing.shutdown();
4518         }
4519 
4520         if (tracker != null) {
4521             mLockdownTracker = tracker;
4522             mLockdownTracker.init();
4523         }
4524     }
4525 
4526     @GuardedBy("mVpns")
throwIfLockdownEnabled()4527     private void throwIfLockdownEnabled() {
4528         if (mLockdownEnabled) {
4529             throw new IllegalStateException("Unavailable in lockdown mode");
4530         }
4531     }
4532 
4533     /**
4534      * Starts the always-on VPN {@link VpnService} for user {@param userId}, which should perform
4535      * some setup and then call {@code establish()} to connect.
4536      *
4537      * @return {@code true} if the service was started, the service was already connected, or there
4538      *         was no always-on VPN to start. {@code false} otherwise.
4539      */
startAlwaysOnVpn(int userId)4540     private boolean startAlwaysOnVpn(int userId) {
4541         synchronized (mVpns) {
4542             Vpn vpn = mVpns.get(userId);
4543             if (vpn == null) {
4544                 // Shouldn't happen as all code paths that point here should have checked the Vpn
4545                 // exists already.
4546                 Slog.wtf(TAG, "User " + userId + " has no Vpn configuration");
4547                 return false;
4548             }
4549 
4550             return vpn.startAlwaysOnVpn();
4551         }
4552     }
4553 
4554     @Override
isAlwaysOnVpnPackageSupported(int userId, String packageName)4555     public boolean isAlwaysOnVpnPackageSupported(int userId, String packageName) {
4556         enforceSettingsPermission();
4557         enforceCrossUserPermission(userId);
4558 
4559         synchronized (mVpns) {
4560             Vpn vpn = mVpns.get(userId);
4561             if (vpn == null) {
4562                 Slog.w(TAG, "User " + userId + " has no Vpn configuration");
4563                 return false;
4564             }
4565             return vpn.isAlwaysOnPackageSupported(packageName);
4566         }
4567     }
4568 
4569     @Override
setAlwaysOnVpnPackage( int userId, String packageName, boolean lockdown, List<String> lockdownWhitelist)4570     public boolean setAlwaysOnVpnPackage(
4571             int userId, String packageName, boolean lockdown, List<String> lockdownWhitelist) {
4572         enforceControlAlwaysOnVpnPermission();
4573         enforceCrossUserPermission(userId);
4574 
4575         synchronized (mVpns) {
4576             // Can't set always-on VPN if legacy VPN is already in lockdown mode.
4577             if (LockdownVpnTracker.isEnabled()) {
4578                 return false;
4579             }
4580 
4581             Vpn vpn = mVpns.get(userId);
4582             if (vpn == null) {
4583                 Slog.w(TAG, "User " + userId + " has no Vpn configuration");
4584                 return false;
4585             }
4586             if (!vpn.setAlwaysOnPackage(packageName, lockdown, lockdownWhitelist)) {
4587                 return false;
4588             }
4589             if (!startAlwaysOnVpn(userId)) {
4590                 vpn.setAlwaysOnPackage(null, false, null);
4591                 return false;
4592             }
4593         }
4594         return true;
4595     }
4596 
4597     @Override
getAlwaysOnVpnPackage(int userId)4598     public String getAlwaysOnVpnPackage(int userId) {
4599         enforceControlAlwaysOnVpnPermission();
4600         enforceCrossUserPermission(userId);
4601 
4602         synchronized (mVpns) {
4603             Vpn vpn = mVpns.get(userId);
4604             if (vpn == null) {
4605                 Slog.w(TAG, "User " + userId + " has no Vpn configuration");
4606                 return null;
4607             }
4608             return vpn.getAlwaysOnPackage();
4609         }
4610     }
4611 
4612     @Override
isVpnLockdownEnabled(int userId)4613     public boolean isVpnLockdownEnabled(int userId) {
4614         enforceControlAlwaysOnVpnPermission();
4615         enforceCrossUserPermission(userId);
4616 
4617         synchronized (mVpns) {
4618             Vpn vpn = mVpns.get(userId);
4619             if (vpn == null) {
4620                 Slog.w(TAG, "User " + userId + " has no Vpn configuration");
4621                 return false;
4622             }
4623             return vpn.getLockdown();
4624         }
4625     }
4626 
4627     @Override
getVpnLockdownWhitelist(int userId)4628     public List<String> getVpnLockdownWhitelist(int userId) {
4629         enforceControlAlwaysOnVpnPermission();
4630         enforceCrossUserPermission(userId);
4631 
4632         synchronized (mVpns) {
4633             Vpn vpn = mVpns.get(userId);
4634             if (vpn == null) {
4635                 Slog.w(TAG, "User " + userId + " has no Vpn configuration");
4636                 return null;
4637             }
4638             return vpn.getLockdownWhitelist();
4639         }
4640     }
4641 
4642     @Override
checkMobileProvisioning(int suggestedTimeOutMs)4643     public int checkMobileProvisioning(int suggestedTimeOutMs) {
4644         // TODO: Remove?  Any reason to trigger a provisioning check?
4645         return -1;
4646     }
4647 
4648     /** Location to an updatable file listing carrier provisioning urls.
4649      *  An example:
4650      *
4651      * <?xml version="1.0" encoding="utf-8"?>
4652      *  <provisioningUrls>
4653      *   <provisioningUrl mcc="310" mnc="4">http://myserver.com/foo?mdn=%3$s&amp;iccid=%1$s&amp;imei=%2$s</provisioningUrl>
4654      *  </provisioningUrls>
4655      */
4656     private static final String PROVISIONING_URL_PATH =
4657             "/data/misc/radio/provisioning_urls.xml";
4658     private final File mProvisioningUrlFile = new File(PROVISIONING_URL_PATH);
4659 
4660     /** XML tag for root element. */
4661     private static final String TAG_PROVISIONING_URLS = "provisioningUrls";
4662     /** XML tag for individual url */
4663     private static final String TAG_PROVISIONING_URL = "provisioningUrl";
4664     /** XML attribute for mcc */
4665     private static final String ATTR_MCC = "mcc";
4666     /** XML attribute for mnc */
4667     private static final String ATTR_MNC = "mnc";
4668 
getProvisioningUrlBaseFromFile()4669     private String getProvisioningUrlBaseFromFile() {
4670         FileReader fileReader = null;
4671         XmlPullParser parser = null;
4672         Configuration config = mContext.getResources().getConfiguration();
4673 
4674         try {
4675             fileReader = new FileReader(mProvisioningUrlFile);
4676             parser = Xml.newPullParser();
4677             parser.setInput(fileReader);
4678             XmlUtils.beginDocument(parser, TAG_PROVISIONING_URLS);
4679 
4680             while (true) {
4681                 XmlUtils.nextElement(parser);
4682 
4683                 String element = parser.getName();
4684                 if (element == null) break;
4685 
4686                 if (element.equals(TAG_PROVISIONING_URL)) {
4687                     String mcc = parser.getAttributeValue(null, ATTR_MCC);
4688                     try {
4689                         if (mcc != null && Integer.parseInt(mcc) == config.mcc) {
4690                             String mnc = parser.getAttributeValue(null, ATTR_MNC);
4691                             if (mnc != null && Integer.parseInt(mnc) == config.mnc) {
4692                                 parser.next();
4693                                 if (parser.getEventType() == XmlPullParser.TEXT) {
4694                                     return parser.getText();
4695                                 }
4696                             }
4697                         }
4698                     } catch (NumberFormatException e) {
4699                         loge("NumberFormatException in getProvisioningUrlBaseFromFile: " + e);
4700                     }
4701                 }
4702             }
4703             return null;
4704         } catch (FileNotFoundException e) {
4705             loge("Carrier Provisioning Urls file not found");
4706         } catch (XmlPullParserException e) {
4707             loge("Xml parser exception reading Carrier Provisioning Urls file: " + e);
4708         } catch (IOException e) {
4709             loge("I/O exception reading Carrier Provisioning Urls file: " + e);
4710         } finally {
4711             if (fileReader != null) {
4712                 try {
4713                     fileReader.close();
4714                 } catch (IOException e) {}
4715             }
4716         }
4717         return null;
4718     }
4719 
4720     @Override
getMobileProvisioningUrl()4721     public String getMobileProvisioningUrl() {
4722         enforceConnectivityInternalPermission();
4723         String url = getProvisioningUrlBaseFromFile();
4724         if (TextUtils.isEmpty(url)) {
4725             url = mContext.getResources().getString(R.string.mobile_provisioning_url);
4726             log("getMobileProvisioningUrl: mobile_provisioining_url from resource =" + url);
4727         } else {
4728             log("getMobileProvisioningUrl: mobile_provisioning_url from File =" + url);
4729         }
4730         // populate the iccid, imei and phone number in the provisioning url.
4731         if (!TextUtils.isEmpty(url)) {
4732             String phoneNumber = mTelephonyManager.getLine1Number();
4733             if (TextUtils.isEmpty(phoneNumber)) {
4734                 phoneNumber = "0000000000";
4735             }
4736             url = String.format(url,
4737                     mTelephonyManager.getSimSerialNumber() /* ICCID */,
4738                     mTelephonyManager.getDeviceId() /* IMEI */,
4739                     phoneNumber /* Phone number */);
4740         }
4741 
4742         return url;
4743     }
4744 
4745     @Override
setProvisioningNotificationVisible(boolean visible, int networkType, String action)4746     public void setProvisioningNotificationVisible(boolean visible, int networkType,
4747             String action) {
4748         enforceConnectivityInternalPermission();
4749         if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
4750             return;
4751         }
4752         final long ident = Binder.clearCallingIdentity();
4753         try {
4754             // Concatenate the range of types onto the range of NetIDs.
4755             int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE);
4756             mNotifier.setProvNotificationVisible(visible, id, action);
4757         } finally {
4758             Binder.restoreCallingIdentity(ident);
4759         }
4760     }
4761 
4762     @Override
setAirplaneMode(boolean enable)4763     public void setAirplaneMode(boolean enable) {
4764         enforceNetworkStackSettingsOrSetup();
4765         final long ident = Binder.clearCallingIdentity();
4766         try {
4767             final ContentResolver cr = mContext.getContentResolver();
4768             Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, encodeBool(enable));
4769             Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
4770             intent.putExtra("state", enable);
4771             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
4772         } finally {
4773             Binder.restoreCallingIdentity(ident);
4774         }
4775     }
4776 
onUserStart(int userId)4777     private void onUserStart(int userId) {
4778         synchronized (mVpns) {
4779             Vpn userVpn = mVpns.get(userId);
4780             if (userVpn != null) {
4781                 loge("Starting user already has a VPN");
4782                 return;
4783             }
4784             userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, userId);
4785             mVpns.put(userId, userVpn);
4786             if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) {
4787                 updateLockdownVpn();
4788             }
4789         }
4790     }
4791 
onUserStop(int userId)4792     private void onUserStop(int userId) {
4793         synchronized (mVpns) {
4794             Vpn userVpn = mVpns.get(userId);
4795             if (userVpn == null) {
4796                 loge("Stopped user has no VPN");
4797                 return;
4798             }
4799             userVpn.onUserStopped();
4800             mVpns.delete(userId);
4801         }
4802     }
4803 
onUserAdded(int userId)4804     private void onUserAdded(int userId) {
4805         mPermissionMonitor.onUserAdded(userId);
4806         Network defaultNetwork = getNetwork(getDefaultNetwork());
4807         synchronized (mVpns) {
4808             final int vpnsSize = mVpns.size();
4809             for (int i = 0; i < vpnsSize; i++) {
4810                 Vpn vpn = mVpns.valueAt(i);
4811                 vpn.onUserAdded(userId);
4812                 NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork);
4813                 updateVpnCapabilities(vpn, nc);
4814             }
4815         }
4816     }
4817 
onUserRemoved(int userId)4818     private void onUserRemoved(int userId) {
4819         mPermissionMonitor.onUserRemoved(userId);
4820         Network defaultNetwork = getNetwork(getDefaultNetwork());
4821         synchronized (mVpns) {
4822             final int vpnsSize = mVpns.size();
4823             for (int i = 0; i < vpnsSize; i++) {
4824                 Vpn vpn = mVpns.valueAt(i);
4825                 vpn.onUserRemoved(userId);
4826                 NetworkCapabilities nc = vpn.updateCapabilities(defaultNetwork);
4827                 updateVpnCapabilities(vpn, nc);
4828             }
4829         }
4830     }
4831 
onPackageAdded(String packageName, int uid)4832     private void onPackageAdded(String packageName, int uid) {
4833         if (TextUtils.isEmpty(packageName) || uid < 0) {
4834             Slog.wtf(TAG, "Invalid package in onPackageAdded: " + packageName + " | " + uid);
4835             return;
4836         }
4837         mPermissionMonitor.onPackageAdded(packageName, uid);
4838     }
4839 
onPackageReplaced(String packageName, int uid)4840     private void onPackageReplaced(String packageName, int uid) {
4841         if (TextUtils.isEmpty(packageName) || uid < 0) {
4842             Slog.wtf(TAG, "Invalid package in onPackageReplaced: " + packageName + " | " + uid);
4843             return;
4844         }
4845         final int userId = UserHandle.getUserId(uid);
4846         synchronized (mVpns) {
4847             final Vpn vpn = mVpns.get(userId);
4848             if (vpn == null) {
4849                 return;
4850             }
4851             // Legacy always-on VPN won't be affected since the package name is not set.
4852             if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName)) {
4853                 Slog.d(TAG, "Restarting always-on VPN package " + packageName + " for user "
4854                         + userId);
4855                 vpn.startAlwaysOnVpn();
4856             }
4857         }
4858     }
4859 
onPackageRemoved(String packageName, int uid, boolean isReplacing)4860     private void onPackageRemoved(String packageName, int uid, boolean isReplacing) {
4861         if (TextUtils.isEmpty(packageName) || uid < 0) {
4862             Slog.wtf(TAG, "Invalid package in onPackageRemoved: " + packageName + " | " + uid);
4863             return;
4864         }
4865         mPermissionMonitor.onPackageRemoved(uid);
4866 
4867         final int userId = UserHandle.getUserId(uid);
4868         synchronized (mVpns) {
4869             final Vpn vpn = mVpns.get(userId);
4870             if (vpn == null) {
4871                 return;
4872             }
4873             // Legacy always-on VPN won't be affected since the package name is not set.
4874             if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName) && !isReplacing) {
4875                 Slog.d(TAG, "Removing always-on VPN package " + packageName + " for user "
4876                         + userId);
4877                 vpn.setAlwaysOnPackage(null, false, null);
4878             }
4879         }
4880     }
4881 
onUserUnlocked(int userId)4882     private void onUserUnlocked(int userId) {
4883         synchronized (mVpns) {
4884             // User present may be sent because of an unlock, which might mean an unlocked keystore.
4885             if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) {
4886                 updateLockdownVpn();
4887             } else {
4888                 startAlwaysOnVpn(userId);
4889             }
4890         }
4891     }
4892 
4893     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
4894         @Override
4895         public void onReceive(Context context, Intent intent) {
4896             ensureRunningOnConnectivityServiceThread();
4897             final String action = intent.getAction();
4898             final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
4899             final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
4900             final Uri packageData = intent.getData();
4901             final String packageName =
4902                     packageData != null ? packageData.getSchemeSpecificPart() : null;
4903             if (userId == UserHandle.USER_NULL) return;
4904 
4905             if (Intent.ACTION_USER_STARTED.equals(action)) {
4906                 onUserStart(userId);
4907             } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
4908                 onUserStop(userId);
4909             } else if (Intent.ACTION_USER_ADDED.equals(action)) {
4910                 onUserAdded(userId);
4911             } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
4912                 onUserRemoved(userId);
4913             } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
4914                 onUserUnlocked(userId);
4915             } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
4916                 onPackageAdded(packageName, uid);
4917             } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
4918                 onPackageReplaced(packageName, uid);
4919             } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
4920                 final boolean isReplacing = intent.getBooleanExtra(
4921                         Intent.EXTRA_REPLACING, false);
4922                 onPackageRemoved(packageName, uid, isReplacing);
4923             }
4924         }
4925     };
4926 
4927     private BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() {
4928         @Override
4929         public void onReceive(Context context, Intent intent) {
4930             // Try creating lockdown tracker, since user present usually means
4931             // unlocked keystore.
4932             updateLockdownVpn();
4933             mContext.unregisterReceiver(this);
4934         }
4935     };
4936 
4937     private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos = new HashMap<>();
4938     private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests = new HashMap<>();
4939 
4940     private static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
4941     // Map from UID to number of NetworkRequests that UID has filed.
4942     @GuardedBy("mUidToNetworkRequestCount")
4943     private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray();
4944 
4945     private static class NetworkFactoryInfo {
4946         public final String name;
4947         public final Messenger messenger;
4948         public final AsyncChannel asyncChannel;
4949         public final int factorySerialNumber;
4950 
NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel, int factorySerialNumber)4951         NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel,
4952                 int factorySerialNumber) {
4953             this.name = name;
4954             this.messenger = messenger;
4955             this.asyncChannel = asyncChannel;
4956             this.factorySerialNumber = factorySerialNumber;
4957         }
4958     }
4959 
ensureNetworkRequestHasType(NetworkRequest request)4960     private void ensureNetworkRequestHasType(NetworkRequest request) {
4961         if (request.type == NetworkRequest.Type.NONE) {
4962             throw new IllegalArgumentException(
4963                     "All NetworkRequests in ConnectivityService must have a type");
4964         }
4965     }
4966 
4967     /**
4968      * Tracks info about the requester.
4969      * Also used to notice when the calling process dies so we can self-expire
4970      */
4971     private class NetworkRequestInfo implements IBinder.DeathRecipient {
4972         final NetworkRequest request;
4973         final PendingIntent mPendingIntent;
4974         boolean mPendingIntentSent;
4975         private final IBinder mBinder;
4976         final int mPid;
4977         final int mUid;
4978         final Messenger messenger;
4979 
NetworkRequestInfo(NetworkRequest r, PendingIntent pi)4980         NetworkRequestInfo(NetworkRequest r, PendingIntent pi) {
4981             request = r;
4982             ensureNetworkRequestHasType(request);
4983             mPendingIntent = pi;
4984             messenger = null;
4985             mBinder = null;
4986             mPid = getCallingPid();
4987             mUid = getCallingUid();
4988             enforceRequestCountLimit();
4989         }
4990 
NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder)4991         NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder) {
4992             super();
4993             messenger = m;
4994             request = r;
4995             ensureNetworkRequestHasType(request);
4996             mBinder = binder;
4997             mPid = getCallingPid();
4998             mUid = getCallingUid();
4999             mPendingIntent = null;
5000             enforceRequestCountLimit();
5001 
5002             try {
5003                 mBinder.linkToDeath(this, 0);
5004             } catch (RemoteException e) {
5005                 binderDied();
5006             }
5007         }
5008 
enforceRequestCountLimit()5009         private void enforceRequestCountLimit() {
5010             synchronized (mUidToNetworkRequestCount) {
5011                 int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1;
5012                 if (networkRequests >= MAX_NETWORK_REQUESTS_PER_UID) {
5013                     throw new ServiceSpecificException(
5014                             ConnectivityManager.Errors.TOO_MANY_REQUESTS);
5015                 }
5016                 mUidToNetworkRequestCount.put(mUid, networkRequests);
5017             }
5018         }
5019 
unlinkDeathRecipient()5020         void unlinkDeathRecipient() {
5021             if (mBinder != null) {
5022                 mBinder.unlinkToDeath(this, 0);
5023             }
5024         }
5025 
binderDied()5026         public void binderDied() {
5027             log("ConnectivityService NetworkRequestInfo binderDied(" +
5028                     request + ", " + mBinder + ")");
5029             releaseNetworkRequest(request);
5030         }
5031 
toString()5032         public String toString() {
5033             return "uid/pid:" + mUid + "/" + mPid + " " + request +
5034                     (mPendingIntent == null ? "" : " to trigger " + mPendingIntent);
5035         }
5036     }
5037 
ensureRequestableCapabilities(NetworkCapabilities networkCapabilities)5038     private void ensureRequestableCapabilities(NetworkCapabilities networkCapabilities) {
5039         final String badCapability = networkCapabilities.describeFirstNonRequestableCapability();
5040         if (badCapability != null) {
5041             throw new IllegalArgumentException("Cannot request network with " + badCapability);
5042         }
5043     }
5044 
5045     // This checks that the passed capabilities either do not request a specific SSID/SignalStrength
5046     // , or the calling app has permission to do so.
ensureSufficientPermissionsForRequest(NetworkCapabilities nc, int callerPid, int callerUid)5047     private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
5048             int callerPid, int callerUid) {
5049         if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) {
5050             throw new SecurityException("Insufficient permissions to request a specific SSID");
5051         }
5052 
5053         if (nc.hasSignalStrength()
5054                 && !checkNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) {
5055             throw new SecurityException(
5056                     "Insufficient permissions to request a specific signal strength");
5057         }
5058     }
5059 
getSignalStrengthThresholds(NetworkAgentInfo nai)5060     private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) {
5061         final SortedSet<Integer> thresholds = new TreeSet<>();
5062         synchronized (nai) {
5063             for (NetworkRequestInfo nri : mNetworkRequests.values()) {
5064                 if (nri.request.networkCapabilities.hasSignalStrength() &&
5065                         nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
5066                     thresholds.add(nri.request.networkCapabilities.getSignalStrength());
5067                 }
5068             }
5069         }
5070         return new ArrayList<>(thresholds);
5071     }
5072 
updateSignalStrengthThresholds( NetworkAgentInfo nai, String reason, NetworkRequest request)5073     private void updateSignalStrengthThresholds(
5074             NetworkAgentInfo nai, String reason, NetworkRequest request) {
5075         ArrayList<Integer> thresholdsArray = getSignalStrengthThresholds(nai);
5076         Bundle thresholds = new Bundle();
5077         thresholds.putIntegerArrayList("thresholds", thresholdsArray);
5078 
5079         if (VDBG || (DBG && !"CONNECT".equals(reason))) {
5080             String detail;
5081             if (request != null && request.networkCapabilities.hasSignalStrength()) {
5082                 detail = reason + " " + request.networkCapabilities.getSignalStrength();
5083             } else {
5084                 detail = reason;
5085             }
5086             log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s",
5087                     detail, Arrays.toString(thresholdsArray.toArray()), nai.name()));
5088         }
5089 
5090         nai.asyncChannel.sendMessage(
5091                 android.net.NetworkAgent.CMD_SET_SIGNAL_STRENGTH_THRESHOLDS,
5092                 0, 0, thresholds);
5093     }
5094 
ensureValidNetworkSpecifier(NetworkCapabilities nc)5095     private void ensureValidNetworkSpecifier(NetworkCapabilities nc) {
5096         if (nc == null) {
5097             return;
5098         }
5099         NetworkSpecifier ns = nc.getNetworkSpecifier();
5100         if (ns == null) {
5101             return;
5102         }
5103         MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(ns);
5104         ns.assertValidFromUid(Binder.getCallingUid());
5105     }
5106 
5107     @Override
requestNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, int timeoutMs, IBinder binder, int legacyType)5108     public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
5109             Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
5110         final NetworkRequest.Type type = (networkCapabilities == null)
5111                 ? NetworkRequest.Type.TRACK_DEFAULT
5112                 : NetworkRequest.Type.REQUEST;
5113         // If the requested networkCapabilities is null, take them instead from
5114         // the default network request. This allows callers to keep track of
5115         // the system default network.
5116         if (type == NetworkRequest.Type.TRACK_DEFAULT) {
5117             networkCapabilities = createDefaultNetworkCapabilitiesForUid(Binder.getCallingUid());
5118             enforceAccessPermission();
5119         } else {
5120             networkCapabilities = new NetworkCapabilities(networkCapabilities);
5121             enforceNetworkRequestPermissions(networkCapabilities);
5122             // TODO: this is incorrect. We mark the request as metered or not depending on the state
5123             // of the app when the request is filed, but we never change the request if the app
5124             // changes network state. http://b/29964605
5125             enforceMeteredApnPolicy(networkCapabilities);
5126         }
5127         ensureRequestableCapabilities(networkCapabilities);
5128         ensureSufficientPermissionsForRequest(networkCapabilities,
5129                 Binder.getCallingPid(), Binder.getCallingUid());
5130         // Set the UID range for this request to the single UID of the requester, or to an empty
5131         // set of UIDs if the caller has the appropriate permission and UIDs have not been set.
5132         // This will overwrite any allowed UIDs in the requested capabilities. Though there
5133         // are no visible methods to set the UIDs, an app could use reflection to try and get
5134         // networks for other apps so it's essential that the UIDs are overwritten.
5135         restrictRequestUidsForCaller(networkCapabilities);
5136 
5137         if (timeoutMs < 0) {
5138             throw new IllegalArgumentException("Bad timeout specified");
5139         }
5140         ensureValidNetworkSpecifier(networkCapabilities);
5141 
5142         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
5143                 nextNetworkRequestId(), type);
5144         NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder);
5145         if (DBG) log("requestNetwork for " + nri);
5146 
5147         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
5148         if (timeoutMs > 0) {
5149             mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST,
5150                     nri), timeoutMs);
5151         }
5152         return networkRequest;
5153     }
5154 
enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities)5155     private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) {
5156         if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
5157             enforceConnectivityRestrictedNetworksPermission();
5158         } else {
5159             enforceChangePermission();
5160         }
5161     }
5162 
5163     @Override
requestBandwidthUpdate(Network network)5164     public boolean requestBandwidthUpdate(Network network) {
5165         enforceAccessPermission();
5166         NetworkAgentInfo nai = null;
5167         if (network == null) {
5168             return false;
5169         }
5170         synchronized (mNetworkForNetId) {
5171             nai = mNetworkForNetId.get(network.netId);
5172         }
5173         if (nai != null) {
5174             nai.asyncChannel.sendMessage(android.net.NetworkAgent.CMD_REQUEST_BANDWIDTH_UPDATE);
5175             synchronized (mBandwidthRequests) {
5176                 final int uid = Binder.getCallingUid();
5177                 Integer uidReqs = mBandwidthRequests.get(uid);
5178                 if (uidReqs == null) {
5179                     uidReqs = new Integer(0);
5180                 }
5181                 mBandwidthRequests.put(uid, ++uidReqs);
5182             }
5183             return true;
5184         }
5185         return false;
5186     }
5187 
isSystem(int uid)5188     private boolean isSystem(int uid) {
5189         return uid < Process.FIRST_APPLICATION_UID;
5190     }
5191 
enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities)5192     private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) {
5193         final int uid = Binder.getCallingUid();
5194         if (isSystem(uid)) {
5195             // Exemption for system uid.
5196             return;
5197         }
5198         if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
5199             // Policy already enforced.
5200             return;
5201         }
5202         if (mPolicyManagerInternal.isUidRestrictedOnMeteredNetworks(uid)) {
5203             // If UID is restricted, don't allow them to bring up metered APNs.
5204             networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
5205         }
5206     }
5207 
5208     @Override
pendingRequestForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation)5209     public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
5210             PendingIntent operation) {
5211         checkNotNull(operation, "PendingIntent cannot be null.");
5212         networkCapabilities = new NetworkCapabilities(networkCapabilities);
5213         enforceNetworkRequestPermissions(networkCapabilities);
5214         enforceMeteredApnPolicy(networkCapabilities);
5215         ensureRequestableCapabilities(networkCapabilities);
5216         ensureSufficientPermissionsForRequest(networkCapabilities,
5217                 Binder.getCallingPid(), Binder.getCallingUid());
5218         ensureValidNetworkSpecifier(networkCapabilities);
5219         restrictRequestUidsForCaller(networkCapabilities);
5220 
5221         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
5222                 nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
5223         NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation);
5224         if (DBG) log("pendingRequest for " + nri);
5225         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT,
5226                 nri));
5227         return networkRequest;
5228     }
5229 
releasePendingNetworkRequestWithDelay(PendingIntent operation)5230     private void releasePendingNetworkRequestWithDelay(PendingIntent operation) {
5231         mHandler.sendMessageDelayed(
5232                 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
5233                 getCallingUid(), 0, operation), mReleasePendingIntentDelayMs);
5234     }
5235 
5236     @Override
releasePendingNetworkRequest(PendingIntent operation)5237     public void releasePendingNetworkRequest(PendingIntent operation) {
5238         checkNotNull(operation, "PendingIntent cannot be null.");
5239         mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
5240                 getCallingUid(), 0, operation));
5241     }
5242 
5243     // In order to implement the compatibility measure for pre-M apps that call
5244     // WifiManager.enableNetwork(..., true) without also binding to that network explicitly,
5245     // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork.
5246     // This ensures it has permission to do so.
hasWifiNetworkListenPermission(NetworkCapabilities nc)5247     private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) {
5248         if (nc == null) {
5249             return false;
5250         }
5251         int[] transportTypes = nc.getTransportTypes();
5252         if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) {
5253             return false;
5254         }
5255         try {
5256             mContext.enforceCallingOrSelfPermission(
5257                     android.Manifest.permission.ACCESS_WIFI_STATE,
5258                     "ConnectivityService");
5259         } catch (SecurityException e) {
5260             return false;
5261         }
5262         return true;
5263     }
5264 
5265     @Override
listenForNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, IBinder binder)5266     public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
5267             Messenger messenger, IBinder binder) {
5268         if (!hasWifiNetworkListenPermission(networkCapabilities)) {
5269             enforceAccessPermission();
5270         }
5271 
5272         NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
5273         ensureSufficientPermissionsForRequest(networkCapabilities,
5274                 Binder.getCallingPid(), Binder.getCallingUid());
5275         restrictRequestUidsForCaller(nc);
5276         // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so
5277         // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get
5278         // onLost and onAvailable callbacks when networks move in and out of the background.
5279         // There is no need to do this for requests because an app without CHANGE_NETWORK_STATE
5280         // can't request networks.
5281         restrictBackgroundRequestForCaller(nc);
5282         ensureValidNetworkSpecifier(nc);
5283 
5284         NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
5285                 NetworkRequest.Type.LISTEN);
5286         NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder);
5287         if (VDBG) log("listenForNetwork for " + nri);
5288 
5289         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
5290         return networkRequest;
5291     }
5292 
5293     @Override
pendingListenForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation)5294     public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
5295             PendingIntent operation) {
5296         checkNotNull(operation, "PendingIntent cannot be null.");
5297         if (!hasWifiNetworkListenPermission(networkCapabilities)) {
5298             enforceAccessPermission();
5299         }
5300         ensureValidNetworkSpecifier(networkCapabilities);
5301         ensureSufficientPermissionsForRequest(networkCapabilities,
5302                 Binder.getCallingPid(), Binder.getCallingUid());
5303 
5304         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
5305         restrictRequestUidsForCaller(nc);
5306 
5307         NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
5308                 NetworkRequest.Type.LISTEN);
5309         NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation);
5310         if (VDBG) log("pendingListenForNetwork for " + nri);
5311 
5312         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
5313     }
5314 
5315     @Override
releaseNetworkRequest(NetworkRequest networkRequest)5316     public void releaseNetworkRequest(NetworkRequest networkRequest) {
5317         ensureNetworkRequestHasType(networkRequest);
5318         mHandler.sendMessage(mHandler.obtainMessage(
5319                 EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(), 0, networkRequest));
5320     }
5321 
5322     @Override
registerNetworkFactory(Messenger messenger, String name)5323     public int registerNetworkFactory(Messenger messenger, String name) {
5324         enforceConnectivityInternalPermission();
5325         NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel(),
5326                 NetworkFactory.SerialNumber.nextSerialNumber());
5327         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi));
5328         return nfi.factorySerialNumber;
5329     }
5330 
handleRegisterNetworkFactory(NetworkFactoryInfo nfi)5331     private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) {
5332         if (DBG) log("Got NetworkFactory Messenger for " + nfi.name);
5333         mNetworkFactoryInfos.put(nfi.messenger, nfi);
5334         nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger);
5335     }
5336 
5337     @Override
unregisterNetworkFactory(Messenger messenger)5338     public void unregisterNetworkFactory(Messenger messenger) {
5339         enforceConnectivityInternalPermission();
5340         mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger));
5341     }
5342 
handleUnregisterNetworkFactory(Messenger messenger)5343     private void handleUnregisterNetworkFactory(Messenger messenger) {
5344         NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger);
5345         if (nfi == null) {
5346             loge("Failed to find Messenger in unregisterNetworkFactory");
5347             return;
5348         }
5349         if (DBG) log("unregisterNetworkFactory for " + nfi.name);
5350     }
5351 
5352     /**
5353      * NetworkAgentInfo supporting a request by requestId.
5354      * These have already been vetted (their Capabilities satisfy the request)
5355      * and the are the highest scored network available.
5356      * the are keyed off the Requests requestId.
5357      */
5358     // NOTE: Accessed on multiple threads, must be synchronized on itself.
5359     @GuardedBy("mNetworkForRequestId")
5360     private final SparseArray<NetworkAgentInfo> mNetworkForRequestId = new SparseArray<>();
5361 
5362     // NOTE: Accessed on multiple threads, must be synchronized on itself.
5363     @GuardedBy("mNetworkForNetId")
5364     private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>();
5365     // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId.
5366     // An entry is first added to mNetIdInUse, prior to mNetworkForNetId, so
5367     // there may not be a strict 1:1 correlation between the two.
5368     @GuardedBy("mNetworkForNetId")
5369     private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray();
5370 
5371     // NetworkAgentInfo keyed off its connecting messenger
5372     // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays
5373     // NOTE: Only should be accessed on ConnectivityServiceThread, except dump().
5374     private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos = new HashMap<>();
5375 
5376     @GuardedBy("mBlockedAppUids")
5377     private final HashSet<Integer> mBlockedAppUids = new HashSet<>();
5378 
5379     // Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
5380     private final NetworkRequest mDefaultRequest;
5381 
5382     // Request used to optionally keep mobile data active even when higher
5383     // priority networks like Wi-Fi are active.
5384     private final NetworkRequest mDefaultMobileDataRequest;
5385 
5386     // Request used to optionally keep wifi data active even when higher
5387     // priority networks like ethernet are active.
5388     private final NetworkRequest mDefaultWifiRequest;
5389 
getNetworkForRequest(int requestId)5390     private NetworkAgentInfo getNetworkForRequest(int requestId) {
5391         synchronized (mNetworkForRequestId) {
5392             return mNetworkForRequestId.get(requestId);
5393         }
5394     }
5395 
clearNetworkForRequest(int requestId)5396     private void clearNetworkForRequest(int requestId) {
5397         synchronized (mNetworkForRequestId) {
5398             mNetworkForRequestId.remove(requestId);
5399         }
5400     }
5401 
setNetworkForRequest(int requestId, NetworkAgentInfo nai)5402     private void setNetworkForRequest(int requestId, NetworkAgentInfo nai) {
5403         synchronized (mNetworkForRequestId) {
5404             mNetworkForRequestId.put(requestId, nai);
5405         }
5406     }
5407 
getDefaultNetwork()5408     private NetworkAgentInfo getDefaultNetwork() {
5409         return getNetworkForRequest(mDefaultRequest.requestId);
5410     }
5411 
5412     @Nullable
getNetwork(@ullable NetworkAgentInfo nai)5413     private Network getNetwork(@Nullable NetworkAgentInfo nai) {
5414         return nai != null ? nai.network : null;
5415     }
5416 
ensureRunningOnConnectivityServiceThread()5417     private void ensureRunningOnConnectivityServiceThread() {
5418         if (mHandler.getLooper().getThread() != Thread.currentThread()) {
5419             throw new IllegalStateException(
5420                     "Not running on ConnectivityService thread: "
5421                             + Thread.currentThread().getName());
5422         }
5423     }
5424 
5425     @VisibleForTesting
isDefaultNetwork(NetworkAgentInfo nai)5426     protected boolean isDefaultNetwork(NetworkAgentInfo nai) {
5427         return nai == getDefaultNetwork();
5428     }
5429 
isDefaultRequest(NetworkRequestInfo nri)5430     private boolean isDefaultRequest(NetworkRequestInfo nri) {
5431         return nri.request.requestId == mDefaultRequest.requestId;
5432     }
5433 
5434     // TODO : remove this method. It's a stopgap measure to help sheperding a number of dependent
5435     // changes that would conflict throughout the automerger graph. Having this method temporarily
5436     // helps with the process of going through with all these dependent changes across the entire
5437     // tree.
registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int currentScore, NetworkMisc networkMisc)5438     public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
5439             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
5440             int currentScore, NetworkMisc networkMisc) {
5441         return registerNetworkAgent(messenger, networkInfo, linkProperties, networkCapabilities,
5442                 currentScore, networkMisc, NetworkFactory.SerialNumber.NONE);
5443     }
5444 
5445     /**
5446      * Register a new agent with ConnectivityService to handle a network.
5447      *
5448      * @param messenger a messenger for ConnectivityService to contact the agent asynchronously.
5449      * @param networkInfo the initial info associated with this network. It can be updated later :
5450      *         see {@link #updateNetworkInfo}.
5451      * @param linkProperties the initial link properties of this network. They can be updated
5452      *         later : see {@link #updateLinkProperties}.
5453      * @param networkCapabilities the initial capabilites of this network. They can be updated
5454      *         later : see {@link #updateNetworkCapabilities}.
5455      * @param currentScore the initial score of the network. See
5456      *         {@link NetworkAgentInfo#getCurrentScore}.
5457      * @param networkMisc metadata about the network. This is never updated.
5458      * @param factorySerialNumber the serial number of the factory owning this NetworkAgent.
5459      */
registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int currentScore, NetworkMisc networkMisc, int factorySerialNumber)5460     public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
5461             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
5462             int currentScore, NetworkMisc networkMisc, int factorySerialNumber) {
5463         enforceConnectivityInternalPermission();
5464 
5465         LinkProperties lp = new LinkProperties(linkProperties);
5466         lp.ensureDirectlyConnectedRoutes();
5467         // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
5468         // satisfies mDefaultRequest.
5469         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
5470         final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
5471                 new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore,
5472                 mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mDnsResolver,
5473                 mNMS, factorySerialNumber);
5474         // Make sure the network capabilities reflect what the agent info says.
5475         nai.setNetworkCapabilities(mixInCapabilities(nai, nc));
5476         final String extraInfo = networkInfo.getExtraInfo();
5477         final String name = TextUtils.isEmpty(extraInfo)
5478                 ? nai.networkCapabilities.getSSID() : extraInfo;
5479         if (DBG) log("registerNetworkAgent " + nai);
5480         final long token = Binder.clearCallingIdentity();
5481         try {
5482             getNetworkStack().makeNetworkMonitor(
5483                     nai.network, name, new NetworkMonitorCallbacks(nai));
5484         } finally {
5485             Binder.restoreCallingIdentity(token);
5486         }
5487         // NetworkAgentInfo registration will finish when the NetworkMonitor is created.
5488         // If the network disconnects or sends any other event before that, messages are deferred by
5489         // NetworkAgent until nai.asyncChannel.connect(), which will be called when finalizing the
5490         // registration.
5491         return nai.network.netId;
5492     }
5493 
5494     @VisibleForTesting
getNetworkStack()5495     protected NetworkStackClient getNetworkStack() {
5496         return NetworkStackClient.getInstance();
5497     }
5498 
handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor)5499     private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) {
5500         nai.onNetworkMonitorCreated(networkMonitor);
5501         if (VDBG) log("Got NetworkAgent Messenger");
5502         mNetworkAgentInfos.put(nai.messenger, nai);
5503         synchronized (mNetworkForNetId) {
5504             mNetworkForNetId.put(nai.network.netId, nai);
5505         }
5506 
5507         try {
5508             networkMonitor.start();
5509         } catch (RemoteException e) {
5510             e.rethrowAsRuntimeException();
5511         }
5512         nai.asyncChannel.connect(mContext, mTrackerHandler, nai.messenger);
5513         NetworkInfo networkInfo = nai.networkInfo;
5514         nai.networkInfo = null;
5515         updateNetworkInfo(nai, networkInfo);
5516         updateUids(nai, null, nai.networkCapabilities);
5517     }
5518 
updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp, LinkProperties oldLp)5519     private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp,
5520             LinkProperties oldLp) {
5521         int netId = networkAgent.network.netId;
5522 
5523         // The NetworkAgentInfo does not know whether clatd is running on its network or not, or
5524         // whether there is a NAT64 prefix. Before we do anything else, make sure its LinkProperties
5525         // are accurate.
5526         networkAgent.clatd.fixupLinkProperties(oldLp, newLp);
5527 
5528         updateInterfaces(newLp, oldLp, netId, networkAgent.networkCapabilities);
5529 
5530         // update filtering rules, need to happen after the interface update so netd knows about the
5531         // new interface (the interface name -> index map becomes initialized)
5532         updateVpnFiltering(newLp, oldLp, networkAgent);
5533 
5534         updateMtu(newLp, oldLp);
5535         // TODO - figure out what to do for clat
5536 //        for (LinkProperties lp : newLp.getStackedLinks()) {
5537 //            updateMtu(lp, null);
5538 //        }
5539         if (isDefaultNetwork(networkAgent)) {
5540             updateTcpBufferSizes(newLp.getTcpBufferSizes());
5541         }
5542 
5543         updateRoutes(newLp, oldLp, netId);
5544         updateDnses(newLp, oldLp, netId);
5545         // Make sure LinkProperties represents the latest private DNS status.
5546         // This does not need to be done before updateDnses because the
5547         // LinkProperties are not the source of the private DNS configuration.
5548         // updateDnses will fetch the private DNS configuration from DnsManager.
5549         mDnsManager.updatePrivateDnsStatus(netId, newLp);
5550 
5551         if (isDefaultNetwork(networkAgent)) {
5552             handleApplyDefaultProxy(newLp.getHttpProxy());
5553         } else {
5554             updateProxy(newLp, oldLp);
5555         }
5556         // TODO - move this check to cover the whole function
5557         if (!Objects.equals(newLp, oldLp)) {
5558             synchronized (networkAgent) {
5559                 networkAgent.linkProperties = newLp;
5560             }
5561             // Start or stop DNS64 detection and 464xlat according to network state.
5562             networkAgent.clatd.update();
5563             notifyIfacesChangedForNetworkStats();
5564             networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp);
5565             if (networkAgent.everConnected) {
5566                 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
5567             }
5568         }
5569 
5570         mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent);
5571     }
5572 
wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add)5573     private void wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add) {
5574         // Marks are only available on WiFi interfaces. Checking for
5575         // marks on unsupported interfaces is harmless.
5576         if (!caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
5577             return;
5578         }
5579 
5580         int mark = mContext.getResources().getInteger(
5581             com.android.internal.R.integer.config_networkWakeupPacketMark);
5582         int mask = mContext.getResources().getInteger(
5583             com.android.internal.R.integer.config_networkWakeupPacketMask);
5584 
5585         // Mask/mark of zero will not detect anything interesting.
5586         // Don't install rules unless both values are nonzero.
5587         if (mark == 0 || mask == 0) {
5588             return;
5589         }
5590 
5591         final String prefix = "iface:" + iface;
5592         try {
5593             if (add) {
5594                 mNetd.wakeupAddInterface(iface, prefix, mark, mask);
5595             } else {
5596                 mNetd.wakeupDelInterface(iface, prefix, mark, mask);
5597             }
5598         } catch (Exception e) {
5599             loge("Exception modifying wakeup packet monitoring: " + e);
5600         }
5601 
5602     }
5603 
updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId, NetworkCapabilities caps)5604     private void updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId,
5605                                   NetworkCapabilities caps) {
5606         CompareResult<String> interfaceDiff = new CompareResult<>(
5607                 oldLp != null ? oldLp.getAllInterfaceNames() : null,
5608                 newLp != null ? newLp.getAllInterfaceNames() : null);
5609         for (String iface : interfaceDiff.added) {
5610             try {
5611                 if (DBG) log("Adding iface " + iface + " to network " + netId);
5612                 mNMS.addInterfaceToNetwork(iface, netId);
5613                 wakeupModifyInterface(iface, caps, true);
5614             } catch (Exception e) {
5615                 loge("Exception adding interface: " + e);
5616             }
5617         }
5618         for (String iface : interfaceDiff.removed) {
5619             try {
5620                 if (DBG) log("Removing iface " + iface + " from network " + netId);
5621                 wakeupModifyInterface(iface, caps, false);
5622                 mNMS.removeInterfaceFromNetwork(iface, netId);
5623             } catch (Exception e) {
5624                 loge("Exception removing interface: " + e);
5625             }
5626         }
5627     }
5628 
5629     /**
5630      * Have netd update routes from oldLp to newLp.
5631      * @return true if routes changed between oldLp and newLp
5632      */
updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId)5633     private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
5634         // Compare the route diff to determine which routes should be added and removed.
5635         CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>(
5636                 oldLp != null ? oldLp.getAllRoutes() : null,
5637                 newLp != null ? newLp.getAllRoutes() : null);
5638 
5639         // add routes before removing old in case it helps with continuous connectivity
5640 
5641         // do this twice, adding non-next-hop routes first, then routes they are dependent on
5642         for (RouteInfo route : routeDiff.added) {
5643             if (route.hasGateway()) continue;
5644             if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
5645             try {
5646                 mNMS.addRoute(netId, route);
5647             } catch (Exception e) {
5648                 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) {
5649                     loge("Exception in addRoute for non-gateway: " + e);
5650                 }
5651             }
5652         }
5653         for (RouteInfo route : routeDiff.added) {
5654             if (route.hasGateway() == false) continue;
5655             if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
5656             try {
5657                 mNMS.addRoute(netId, route);
5658             } catch (Exception e) {
5659                 if ((route.getGateway() instanceof Inet4Address) || VDBG) {
5660                     loge("Exception in addRoute for gateway: " + e);
5661                 }
5662             }
5663         }
5664 
5665         for (RouteInfo route : routeDiff.removed) {
5666             if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId);
5667             try {
5668                 mNMS.removeRoute(netId, route);
5669             } catch (Exception e) {
5670                 loge("Exception in removeRoute: " + e);
5671             }
5672         }
5673         return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty();
5674     }
5675 
updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId)5676     private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
5677         if (oldLp != null && newLp.isIdenticalDnses(oldLp)) {
5678             return;  // no updating necessary
5679         }
5680 
5681         final NetworkAgentInfo defaultNai = getDefaultNetwork();
5682         final boolean isDefaultNetwork = (defaultNai != null && defaultNai.network.netId == netId);
5683 
5684         if (DBG) {
5685             final Collection<InetAddress> dnses = newLp.getDnsServers();
5686             log("Setting DNS servers for network " + netId + " to " + dnses);
5687         }
5688         try {
5689             mDnsManager.setDnsConfigurationForNetwork(netId, newLp, isDefaultNetwork);
5690         } catch (Exception e) {
5691             loge("Exception in setDnsConfigurationForNetwork: " + e);
5692         }
5693     }
5694 
updateVpnFiltering(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai)5695     private void updateVpnFiltering(LinkProperties newLp, LinkProperties oldLp,
5696             NetworkAgentInfo nai) {
5697         final String oldIface = oldLp != null ? oldLp.getInterfaceName() : null;
5698         final String newIface = newLp != null ? newLp.getInterfaceName() : null;
5699         final boolean wasFiltering = requiresVpnIsolation(nai, nai.networkCapabilities, oldLp);
5700         final boolean needsFiltering = requiresVpnIsolation(nai, nai.networkCapabilities, newLp);
5701 
5702         if (!wasFiltering && !needsFiltering) {
5703             // Nothing to do.
5704             return;
5705         }
5706 
5707         if (Objects.equals(oldIface, newIface) && (wasFiltering == needsFiltering)) {
5708             // Nothing changed.
5709             return;
5710         }
5711 
5712         final Set<UidRange> ranges = nai.networkCapabilities.getUids();
5713         final int vpnAppUid = nai.networkCapabilities.getEstablishingVpnAppUid();
5714         // TODO: this create a window of opportunity for apps to receive traffic between the time
5715         // when the old rules are removed and the time when new rules are added. To fix this,
5716         // make eBPF support two whitelisted interfaces so here new rules can be added before the
5717         // old rules are being removed.
5718         if (wasFiltering) {
5719             mPermissionMonitor.onVpnUidRangesRemoved(oldIface, ranges, vpnAppUid);
5720         }
5721         if (needsFiltering) {
5722             mPermissionMonitor.onVpnUidRangesAdded(newIface, ranges, vpnAppUid);
5723         }
5724     }
5725 
getNetworkPermission(NetworkCapabilities nc)5726     private int getNetworkPermission(NetworkCapabilities nc) {
5727         if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
5728             return INetd.PERMISSION_SYSTEM;
5729         }
5730         if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) {
5731             return INetd.PERMISSION_NETWORK;
5732         }
5733         return INetd.PERMISSION_NONE;
5734     }
5735 
5736     /**
5737      * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are
5738      * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal,
5739      * and foreground status).
5740      */
mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc)5741     private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) {
5742         // Once a NetworkAgent is connected, complain if some immutable capabilities are removed.
5743          // Don't complain for VPNs since they're not driven by requests and there is no risk of
5744          // causing a connect/teardown loop.
5745          // TODO: remove this altogether and make it the responsibility of the NetworkFactories to
5746          // avoid connect/teardown loops.
5747         if (nai.everConnected &&
5748                 !nai.isVPN() &&
5749                 !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) {
5750             // TODO: consider not complaining when a network agent degrades its capabilities if this
5751             // does not cause any request (that is not a listen) currently matching that agent to
5752             // stop being matched by the updated agent.
5753             String diff = nai.networkCapabilities.describeImmutableDifferences(nc);
5754             if (!TextUtils.isEmpty(diff)) {
5755                 Slog.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff);
5756             }
5757         }
5758 
5759         // Don't modify caller's NetworkCapabilities.
5760         NetworkCapabilities newNc = new NetworkCapabilities(nc);
5761         if (nai.lastValidated) {
5762             newNc.addCapability(NET_CAPABILITY_VALIDATED);
5763         } else {
5764             newNc.removeCapability(NET_CAPABILITY_VALIDATED);
5765         }
5766         if (nai.lastCaptivePortalDetected) {
5767             newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
5768         } else {
5769             newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
5770         }
5771         if (nai.isBackgroundNetwork()) {
5772             newNc.removeCapability(NET_CAPABILITY_FOREGROUND);
5773         } else {
5774             newNc.addCapability(NET_CAPABILITY_FOREGROUND);
5775         }
5776         if (nai.isSuspended()) {
5777             newNc.removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
5778         } else {
5779             newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
5780         }
5781         if (nai.partialConnectivity) {
5782             newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
5783         } else {
5784             newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
5785         }
5786 
5787         return newNc;
5788     }
5789 
5790     /**
5791      * Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically:
5792      *
5793      * 1. Calls mixInCapabilities to merge the passed-in NetworkCapabilities {@code nc} with the
5794      *    capabilities we manage and store in {@code nai}, such as validated status and captive
5795      *    portal status)
5796      * 2. Takes action on the result: changes network permissions, sends CAP_CHANGED callbacks, and
5797      *    potentially triggers rematches.
5798      * 3. Directly informs other network stack components (NetworkStatsService, VPNs, etc. of the
5799      *    change.)
5800      *
5801      * @param oldScore score of the network before any of the changes that prompted us
5802      *                 to call this function.
5803      * @param nai the network having its capabilities updated.
5804      * @param nc the new network capabilities.
5805      */
updateCapabilities(int oldScore, NetworkAgentInfo nai, NetworkCapabilities nc)5806     private void updateCapabilities(int oldScore, NetworkAgentInfo nai, NetworkCapabilities nc) {
5807         NetworkCapabilities newNc = mixInCapabilities(nai, nc);
5808 
5809         if (Objects.equals(nai.networkCapabilities, newNc)) return;
5810 
5811         final int oldPermission = getNetworkPermission(nai.networkCapabilities);
5812         final int newPermission = getNetworkPermission(newNc);
5813         if (oldPermission != newPermission && nai.created && !nai.isVPN()) {
5814             try {
5815                 mNMS.setNetworkPermission(nai.network.netId, newPermission);
5816             } catch (RemoteException e) {
5817                 loge("Exception in setNetworkPermission: " + e);
5818             }
5819         }
5820 
5821         final NetworkCapabilities prevNc;
5822         synchronized (nai) {
5823             prevNc = nai.networkCapabilities;
5824             nai.setNetworkCapabilities(newNc);
5825         }
5826 
5827         updateUids(nai, prevNc, newNc);
5828 
5829         if (nai.getCurrentScore() == oldScore && newNc.equalRequestableCapabilities(prevNc)) {
5830             // If the requestable capabilities haven't changed, and the score hasn't changed, then
5831             // the change we're processing can't affect any requests, it can only affect the listens
5832             // on this network. We might have been called by rematchNetworkAndRequests when a
5833             // network changed foreground state.
5834             processListenRequests(nai, true);
5835         } else {
5836             // If the requestable capabilities have changed or the score changed, we can't have been
5837             // called by rematchNetworkAndRequests, so it's safe to start a rematch.
5838             rematchAllNetworksAndRequests(nai, oldScore);
5839             notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
5840         }
5841 
5842         if (prevNc != null) {
5843             final boolean oldMetered = prevNc.isMetered();
5844             final boolean newMetered = newNc.isMetered();
5845             final boolean meteredChanged = oldMetered != newMetered;
5846 
5847             if (meteredChanged) {
5848                 maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, mRestrictBackground,
5849                         mRestrictBackground);
5850             }
5851 
5852             final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) !=
5853                     newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
5854 
5855             // Report changes that are interesting for network statistics tracking.
5856             if (meteredChanged || roamingChanged) {
5857                 notifyIfacesChangedForNetworkStats();
5858             }
5859         }
5860 
5861         if (!newNc.hasTransport(TRANSPORT_VPN)) {
5862             // Tell VPNs about updated capabilities, since they may need to
5863             // bubble those changes through.
5864             updateAllVpnsCapabilities();
5865         }
5866     }
5867 
5868     /**
5869      * Returns whether VPN isolation (ingress interface filtering) should be applied on the given
5870      * network.
5871      *
5872      * Ingress interface filtering enforces that all apps under the given network can only receive
5873      * packets from the network's interface (and loopback). This is important for VPNs because
5874      * apps that cannot bypass a fully-routed VPN shouldn't be able to receive packets from any
5875      * non-VPN interfaces.
5876      *
5877      * As a result, this method should return true iff
5878      *  1. the network is an app VPN (not legacy VPN)
5879      *  2. the VPN does not allow bypass
5880      *  3. the VPN is fully-routed
5881      *  4. the VPN interface is non-null
5882      *
5883      * @See INetd#firewallAddUidInterfaceRules
5884      * @See INetd#firewallRemoveUidInterfaceRules
5885      */
requiresVpnIsolation(@onNull NetworkAgentInfo nai, NetworkCapabilities nc, LinkProperties lp)5886     private boolean requiresVpnIsolation(@NonNull NetworkAgentInfo nai, NetworkCapabilities nc,
5887             LinkProperties lp) {
5888         if (nc == null || lp == null) return false;
5889         return nai.isVPN()
5890                 && !nai.networkMisc.allowBypass
5891                 && nc.getEstablishingVpnAppUid() != Process.SYSTEM_UID
5892                 && lp.getInterfaceName() != null
5893                 && (lp.hasIPv4DefaultRoute() || lp.hasIPv6DefaultRoute());
5894     }
5895 
updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc, NetworkCapabilities newNc)5896     private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc,
5897             NetworkCapabilities newNc) {
5898         Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUids();
5899         Set<UidRange> newRanges = null == newNc ? null : newNc.getUids();
5900         if (null == prevRanges) prevRanges = new ArraySet<>();
5901         if (null == newRanges) newRanges = new ArraySet<>();
5902         final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges);
5903 
5904         prevRanges.removeAll(newRanges);
5905         newRanges.removeAll(prevRangesCopy);
5906 
5907         try {
5908             // When updating the VPN uid routing rules, add the new range first then remove the old
5909             // range. If old range were removed first, there would be a window between the old
5910             // range being removed and the new range being added, during which UIDs contained
5911             // in both ranges are not subject to any VPN routing rules. Adding new range before
5912             // removing old range works because, unlike the filtering rules below, it's possible to
5913             // add duplicate UID routing rules.
5914             if (!newRanges.isEmpty()) {
5915                 final UidRange[] addedRangesArray = new UidRange[newRanges.size()];
5916                 newRanges.toArray(addedRangesArray);
5917                 mNMS.addVpnUidRanges(nai.network.netId, addedRangesArray);
5918             }
5919             if (!prevRanges.isEmpty()) {
5920                 final UidRange[] removedRangesArray = new UidRange[prevRanges.size()];
5921                 prevRanges.toArray(removedRangesArray);
5922                 mNMS.removeVpnUidRanges(nai.network.netId, removedRangesArray);
5923             }
5924             final boolean wasFiltering = requiresVpnIsolation(nai, prevNc, nai.linkProperties);
5925             final boolean shouldFilter = requiresVpnIsolation(nai, newNc, nai.linkProperties);
5926             final String iface = nai.linkProperties.getInterfaceName();
5927             // For VPN uid interface filtering, old ranges need to be removed before new ranges can
5928             // be added, due to the range being expanded and stored as invidiual UIDs. For example
5929             // the UIDs might be updated from [0, 99999] to ([0, 10012], [10014, 99999]) which means
5930             // prevRanges = [0, 99999] while newRanges = [0, 10012], [10014, 99999]. If prevRanges
5931             // were added first and then newRanges got removed later, there would be only one uid
5932             // 10013 left. A consequence of removing old ranges before adding new ranges is that
5933             // there is now a window of opportunity when the UIDs are not subject to any filtering.
5934             // Note that this is in contrast with the (more robust) update of VPN routing rules
5935             // above, where the addition of new ranges happens before the removal of old ranges.
5936             // TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range
5937             // to be removed will never overlap with the new range to be added.
5938             if (wasFiltering && !prevRanges.isEmpty()) {
5939                 mPermissionMonitor.onVpnUidRangesRemoved(iface, prevRanges,
5940                         prevNc.getEstablishingVpnAppUid());
5941             }
5942             if (shouldFilter && !newRanges.isEmpty()) {
5943                 mPermissionMonitor.onVpnUidRangesAdded(iface, newRanges,
5944                         newNc.getEstablishingVpnAppUid());
5945             }
5946         } catch (Exception e) {
5947             // Never crash!
5948             loge("Exception in updateUids: ", e);
5949         }
5950     }
5951 
handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp)5952     public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) {
5953         ensureRunningOnConnectivityServiceThread();
5954 
5955         if (getNetworkAgentInfoForNetId(nai.network.netId) != nai) {
5956             // Ignore updates for disconnected networks
5957             return;
5958         }
5959         // newLp is already a defensive copy.
5960         newLp.ensureDirectlyConnectedRoutes();
5961         if (VDBG || DDBG) {
5962             log("Update of LinkProperties for " + nai.name() +
5963                     "; created=" + nai.created +
5964                     "; everConnected=" + nai.everConnected);
5965         }
5966         updateLinkProperties(nai, newLp, new LinkProperties(nai.linkProperties));
5967     }
5968 
sendUpdatedScoreToFactories(NetworkAgentInfo nai)5969     private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) {
5970         for (int i = 0; i < nai.numNetworkRequests(); i++) {
5971             NetworkRequest nr = nai.requestAt(i);
5972             // Don't send listening requests to factories. b/17393458
5973             if (nr.isListen()) continue;
5974             sendUpdatedScoreToFactories(nr, nai);
5975         }
5976     }
5977 
sendUpdatedScoreToFactories(NetworkRequest networkRequest, NetworkAgentInfo nai)5978     private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, NetworkAgentInfo nai) {
5979         int score = 0;
5980         int serial = 0;
5981         if (nai != null) {
5982             score = nai.getCurrentScore();
5983             serial = nai.factorySerialNumber;
5984         }
5985         if (VDBG || DDBG){
5986             log("sending new Min Network Score(" + score + "): " + networkRequest.toString());
5987         }
5988         for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
5989             nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score,
5990                     serial, networkRequest);
5991         }
5992     }
5993 
sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, int notificationType)5994     private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent,
5995             int notificationType) {
5996         if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) {
5997             Intent intent = new Intent();
5998             intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network);
5999             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, nri.request);
6000             nri.mPendingIntentSent = true;
6001             sendIntent(nri.mPendingIntent, intent);
6002         }
6003         // else not handled
6004     }
6005 
sendIntent(PendingIntent pendingIntent, Intent intent)6006     private void sendIntent(PendingIntent pendingIntent, Intent intent) {
6007         mPendingIntentWakeLock.acquire();
6008         try {
6009             if (DBG) log("Sending " + pendingIntent);
6010             pendingIntent.send(mContext, 0, intent, this /* onFinished */, null /* Handler */);
6011         } catch (PendingIntent.CanceledException e) {
6012             if (DBG) log(pendingIntent + " was not sent, it had been canceled.");
6013             mPendingIntentWakeLock.release();
6014             releasePendingNetworkRequest(pendingIntent);
6015         }
6016         // ...otherwise, mPendingIntentWakeLock.release() gets called by onSendFinished()
6017     }
6018 
6019     @Override
onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras)6020     public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
6021             String resultData, Bundle resultExtras) {
6022         if (DBG) log("Finished sending " + pendingIntent);
6023         mPendingIntentWakeLock.release();
6024         // Release with a delay so the receiving client has an opportunity to put in its
6025         // own request.
6026         releasePendingNetworkRequestWithDelay(pendingIntent);
6027     }
6028 
callCallbackForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, int notificationType, int arg1)6029     private void callCallbackForRequest(NetworkRequestInfo nri,
6030             NetworkAgentInfo networkAgent, int notificationType, int arg1) {
6031         if (nri.messenger == null) {
6032             return;  // Default request has no msgr
6033         }
6034         Bundle bundle = new Bundle();
6035         // TODO: check if defensive copies of data is needed.
6036         putParcelable(bundle, new NetworkRequest(nri.request));
6037         Message msg = Message.obtain();
6038         if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) {
6039             putParcelable(bundle, networkAgent.network);
6040         }
6041         switch (notificationType) {
6042             case ConnectivityManager.CALLBACK_AVAILABLE: {
6043                 putParcelable(bundle, networkCapabilitiesRestrictedForCallerPermissions(
6044                         networkAgent.networkCapabilities, nri.mPid, nri.mUid));
6045                 putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
6046                 // For this notification, arg1 contains the blocked status.
6047                 msg.arg1 = arg1;
6048                 break;
6049             }
6050             case ConnectivityManager.CALLBACK_LOSING: {
6051                 msg.arg1 = arg1;
6052                 break;
6053             }
6054             case ConnectivityManager.CALLBACK_CAP_CHANGED: {
6055                 // networkAgent can't be null as it has been accessed a few lines above.
6056                 final NetworkCapabilities nc = networkCapabilitiesRestrictedForCallerPermissions(
6057                         networkAgent.networkCapabilities, nri.mPid, nri.mUid);
6058                 putParcelable(bundle, nc);
6059                 break;
6060             }
6061             case ConnectivityManager.CALLBACK_IP_CHANGED: {
6062                 putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
6063                 break;
6064             }
6065             case ConnectivityManager.CALLBACK_BLK_CHANGED: {
6066                 maybeLogBlockedStatusChanged(nri, networkAgent.network, arg1 != 0);
6067                 msg.arg1 = arg1;
6068                 break;
6069             }
6070         }
6071         msg.what = notificationType;
6072         msg.setData(bundle);
6073         try {
6074             if (VDBG) {
6075                 String notification = ConnectivityManager.getCallbackName(notificationType);
6076                 log("sending notification " + notification + " for " + nri.request);
6077             }
6078             nri.messenger.send(msg);
6079         } catch (RemoteException e) {
6080             // may occur naturally in the race of binder death.
6081             loge("RemoteException caught trying to send a callback msg for " + nri.request);
6082         }
6083     }
6084 
putParcelable(Bundle bundle, T t)6085     private static <T extends Parcelable> void putParcelable(Bundle bundle, T t) {
6086         bundle.putParcelable(t.getClass().getSimpleName(), t);
6087     }
6088 
teardownUnneededNetwork(NetworkAgentInfo nai)6089     private void teardownUnneededNetwork(NetworkAgentInfo nai) {
6090         if (nai.numRequestNetworkRequests() != 0) {
6091             for (int i = 0; i < nai.numNetworkRequests(); i++) {
6092                 NetworkRequest nr = nai.requestAt(i);
6093                 // Ignore listening requests.
6094                 if (nr.isListen()) continue;
6095                 loge("Dead network still had at least " + nr);
6096                 break;
6097             }
6098         }
6099         nai.asyncChannel.disconnect();
6100     }
6101 
handleLingerComplete(NetworkAgentInfo oldNetwork)6102     private void handleLingerComplete(NetworkAgentInfo oldNetwork) {
6103         if (oldNetwork == null) {
6104             loge("Unknown NetworkAgentInfo in handleLingerComplete");
6105             return;
6106         }
6107         if (DBG) log("handleLingerComplete for " + oldNetwork.name());
6108 
6109         // If we get here it means that the last linger timeout for this network expired. So there
6110         // must be no other active linger timers, and we must stop lingering.
6111         oldNetwork.clearLingerState();
6112 
6113         if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) {
6114             // Tear the network down.
6115             teardownUnneededNetwork(oldNetwork);
6116         } else {
6117             // Put the network in the background.
6118             updateCapabilities(oldNetwork.getCurrentScore(), oldNetwork,
6119                     oldNetwork.networkCapabilities);
6120         }
6121     }
6122 
makeDefault(NetworkAgentInfo newNetwork)6123     private void makeDefault(NetworkAgentInfo newNetwork) {
6124         if (DBG) log("Switching to new default network: " + newNetwork);
6125 
6126         try {
6127             mNMS.setDefaultNetId(newNetwork.network.netId);
6128         } catch (Exception e) {
6129             loge("Exception setting default network :" + e);
6130         }
6131 
6132         notifyLockdownVpn(newNetwork);
6133         handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy());
6134         updateTcpBufferSizes(newNetwork.linkProperties.getTcpBufferSizes());
6135         mDnsManager.setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers());
6136         notifyIfacesChangedForNetworkStats();
6137         // Fix up the NetworkCapabilities of any VPNs that don't specify underlying networks.
6138         updateAllVpnsCapabilities();
6139     }
6140 
processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged)6141     private void processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged) {
6142         // For consistency with previous behaviour, send onLost callbacks before onAvailable.
6143         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
6144             NetworkRequest nr = nri.request;
6145             if (!nr.isListen()) continue;
6146             if (nai.isSatisfyingRequest(nr.requestId) && !nai.satisfies(nr)) {
6147                 nai.removeRequest(nri.request.requestId);
6148                 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_LOST, 0);
6149             }
6150         }
6151 
6152         if (capabilitiesChanged) {
6153             notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
6154         }
6155 
6156         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
6157             NetworkRequest nr = nri.request;
6158             if (!nr.isListen()) continue;
6159             if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) {
6160                 nai.addRequest(nr);
6161                 notifyNetworkAvailable(nai, nri);
6162             }
6163         }
6164     }
6165 
6166     // Handles a network appearing or improving its score.
6167     //
6168     // - Evaluates all current NetworkRequests that can be
6169     //   satisfied by newNetwork, and reassigns to newNetwork
6170     //   any such requests for which newNetwork is the best.
6171     //
6172     // - Lingers any validated Networks that as a result are no longer
6173     //   needed. A network is needed if it is the best network for
6174     //   one or more NetworkRequests, or if it is a VPN.
6175     //
6176     // - Tears down newNetwork if it just became validated
6177     //   but turns out to be unneeded.
6178     //
6179     // - If reapUnvalidatedNetworks==REAP, tears down unvalidated
6180     //   networks that have no chance (i.e. even if validated)
6181     //   of becoming the highest scoring network.
6182     //
6183     // NOTE: This function only adds NetworkRequests that "newNetwork" could satisfy,
6184     // it does not remove NetworkRequests that other Networks could better satisfy.
6185     // If you need to handle decreases in score, use {@link rematchAllNetworksAndRequests}.
6186     // This function should be used when possible instead of {@code rematchAllNetworksAndRequests}
6187     // as it performs better by a factor of the number of Networks.
6188     //
6189     // @param newNetwork is the network to be matched against NetworkRequests.
6190     // @param reapUnvalidatedNetworks indicates if an additional pass over all networks should be
6191     //               performed to tear down unvalidated networks that have no chance (i.e. even if
6192     //               validated) of becoming the highest scoring network.
rematchNetworkAndRequests(NetworkAgentInfo newNetwork, ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now)6193     private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork,
6194             ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now) {
6195         if (!newNetwork.everConnected) return;
6196         boolean keep = newNetwork.isVPN();
6197         boolean isNewDefault = false;
6198         NetworkAgentInfo oldDefaultNetwork = null;
6199 
6200         final boolean wasBackgroundNetwork = newNetwork.isBackgroundNetwork();
6201         final int score = newNetwork.getCurrentScore();
6202 
6203         if (VDBG || DDBG) log("rematching " + newNetwork.name());
6204 
6205         // Find and migrate to this Network any NetworkRequests for
6206         // which this network is now the best.
6207         ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<>();
6208         ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<>();
6209         NetworkCapabilities nc = newNetwork.networkCapabilities;
6210         if (VDBG) log(" network has: " + nc);
6211         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
6212             // Process requests in the first pass and listens in the second pass. This allows us to
6213             // change a network's capabilities depending on which requests it has. This is only
6214             // correct if the change in capabilities doesn't affect whether the network satisfies
6215             // requests or not, and doesn't affect the network's score.
6216             if (nri.request.isListen()) continue;
6217 
6218             final NetworkAgentInfo currentNetwork = getNetworkForRequest(nri.request.requestId);
6219             final boolean satisfies = newNetwork.satisfies(nri.request);
6220             if (newNetwork == currentNetwork && satisfies) {
6221                 if (VDBG) {
6222                     log("Network " + newNetwork.name() + " was already satisfying" +
6223                             " request " + nri.request.requestId + ". No change.");
6224                 }
6225                 keep = true;
6226                 continue;
6227             }
6228 
6229             // check if it satisfies the NetworkCapabilities
6230             if (VDBG) log("  checking if request is satisfied: " + nri.request);
6231             if (satisfies) {
6232                 // next check if it's better than any current network we're using for
6233                 // this request
6234                 if (VDBG || DDBG) {
6235                     log("currentScore = " +
6236                             (currentNetwork != null ? currentNetwork.getCurrentScore() : 0) +
6237                             ", newScore = " + score);
6238                 }
6239                 if (currentNetwork == null || currentNetwork.getCurrentScore() < score) {
6240                     if (VDBG) log("rematch for " + newNetwork.name());
6241                     if (currentNetwork != null) {
6242                         if (VDBG || DDBG){
6243                             log("   accepting network in place of " + currentNetwork.name());
6244                         }
6245                         currentNetwork.removeRequest(nri.request.requestId);
6246                         currentNetwork.lingerRequest(nri.request, now, mLingerDelayMs);
6247                         affectedNetworks.add(currentNetwork);
6248                     } else {
6249                         if (VDBG || DDBG) log("   accepting network in place of null");
6250                     }
6251                     newNetwork.unlingerRequest(nri.request);
6252                     setNetworkForRequest(nri.request.requestId, newNetwork);
6253                     if (!newNetwork.addRequest(nri.request)) {
6254                         Slog.wtf(TAG, "BUG: " + newNetwork.name() + " already has " + nri.request);
6255                     }
6256                     addedRequests.add(nri);
6257                     keep = true;
6258                     // Tell NetworkFactories about the new score, so they can stop
6259                     // trying to connect if they know they cannot match it.
6260                     // TODO - this could get expensive if we have a lot of requests for this
6261                     // network.  Think about if there is a way to reduce this.  Push
6262                     // netid->request mapping to each factory?
6263                     sendUpdatedScoreToFactories(nri.request, newNetwork);
6264                     if (isDefaultRequest(nri)) {
6265                         isNewDefault = true;
6266                         oldDefaultNetwork = currentNetwork;
6267                         if (currentNetwork != null) {
6268                             mLingerMonitor.noteLingerDefaultNetwork(currentNetwork, newNetwork);
6269                         }
6270                     }
6271                 }
6272             } else if (newNetwork.isSatisfyingRequest(nri.request.requestId)) {
6273                 // If "newNetwork" is listed as satisfying "nri" but no longer satisfies "nri",
6274                 // mark it as no longer satisfying "nri".  Because networks are processed by
6275                 // rematchAllNetworksAndRequests() in descending score order, "currentNetwork" will
6276                 // match "newNetwork" before this loop will encounter a "currentNetwork" with higher
6277                 // score than "newNetwork" and where "currentNetwork" no longer satisfies "nri".
6278                 // This means this code doesn't have to handle the case where "currentNetwork" no
6279                 // longer satisfies "nri" when "currentNetwork" does not equal "newNetwork".
6280                 if (DBG) {
6281                     log("Network " + newNetwork.name() + " stopped satisfying" +
6282                             " request " + nri.request.requestId);
6283                 }
6284                 newNetwork.removeRequest(nri.request.requestId);
6285                 if (currentNetwork == newNetwork) {
6286                     clearNetworkForRequest(nri.request.requestId);
6287                     sendUpdatedScoreToFactories(nri.request, null);
6288                 } else {
6289                     Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " +
6290                             newNetwork.name() +
6291                             " without updating mNetworkForRequestId or factories!");
6292                 }
6293                 // TODO: Technically, sending CALLBACK_LOST here is
6294                 // incorrect if there is a replacement network currently
6295                 // connected that can satisfy nri, which is a request
6296                 // (not a listen). However, the only capability that can both
6297                 // a) be requested and b) change is NET_CAPABILITY_TRUSTED,
6298                 // so this code is only incorrect for a network that loses
6299                 // the TRUSTED capability, which is a rare case.
6300                 callCallbackForRequest(nri, newNetwork, ConnectivityManager.CALLBACK_LOST, 0);
6301             }
6302         }
6303         if (isNewDefault) {
6304             updateDataActivityTracking(newNetwork, oldDefaultNetwork);
6305             // Notify system services that this network is up.
6306             makeDefault(newNetwork);
6307             // Log 0 -> X and Y -> X default network transitions, where X is the new default.
6308             metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(
6309                     now, newNetwork, oldDefaultNetwork);
6310             // Have a new default network, release the transition wakelock in
6311             scheduleReleaseNetworkTransitionWakelock();
6312         }
6313 
6314         if (!newNetwork.networkCapabilities.equalRequestableCapabilities(nc)) {
6315             Slog.wtf(TAG, String.format(
6316                     "BUG: %s changed requestable capabilities during rematch: %s -> %s",
6317                     newNetwork.name(), nc, newNetwork.networkCapabilities));
6318         }
6319         if (newNetwork.getCurrentScore() != score) {
6320             Slog.wtf(TAG, String.format(
6321                     "BUG: %s changed score during rematch: %d -> %d",
6322                    newNetwork.name(), score, newNetwork.getCurrentScore()));
6323         }
6324 
6325         // Second pass: process all listens.
6326         if (wasBackgroundNetwork != newNetwork.isBackgroundNetwork()) {
6327             // If the network went from background to foreground or vice versa, we need to update
6328             // its foreground state. It is safe to do this after rematching the requests because
6329             // NET_CAPABILITY_FOREGROUND does not affect requests, as is not a requestable
6330             // capability and does not affect the network's score (see the Slog.wtf call above).
6331             updateCapabilities(score, newNetwork, newNetwork.networkCapabilities);
6332         } else {
6333             processListenRequests(newNetwork, false);
6334         }
6335 
6336         // do this after the default net is switched, but
6337         // before LegacyTypeTracker sends legacy broadcasts
6338         for (NetworkRequestInfo nri : addedRequests) notifyNetworkAvailable(newNetwork, nri);
6339 
6340         // Linger any networks that are no longer needed. This should be done after sending the
6341         // available callback for newNetwork.
6342         for (NetworkAgentInfo nai : affectedNetworks) {
6343             updateLingerState(nai, now);
6344         }
6345         // Possibly unlinger newNetwork. Unlingering a network does not send any callbacks so it
6346         // does not need to be done in any particular order.
6347         updateLingerState(newNetwork, now);
6348 
6349         if (isNewDefault) {
6350             // Maintain the illusion: since the legacy API only
6351             // understands one network at a time, we must pretend
6352             // that the current default network disconnected before
6353             // the new one connected.
6354             if (oldDefaultNetwork != null) {
6355                 mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
6356                                           oldDefaultNetwork, true);
6357             }
6358             mDefaultInetConditionPublished = newNetwork.lastValidated ? 100 : 0;
6359             mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork);
6360             notifyLockdownVpn(newNetwork);
6361         }
6362 
6363         if (keep) {
6364             // Notify battery stats service about this network, both the normal
6365             // interface and any stacked links.
6366             // TODO: Avoid redoing this; this must only be done once when a network comes online.
6367             try {
6368                 final IBatteryStats bs = BatteryStatsService.getService();
6369                 final int type = newNetwork.networkInfo.getType();
6370 
6371                 final String baseIface = newNetwork.linkProperties.getInterfaceName();
6372                 bs.noteNetworkInterfaceType(baseIface, type);
6373                 for (LinkProperties stacked : newNetwork.linkProperties.getStackedLinks()) {
6374                     final String stackedIface = stacked.getInterfaceName();
6375                     bs.noteNetworkInterfaceType(stackedIface, type);
6376                 }
6377             } catch (RemoteException ignored) {
6378             }
6379 
6380             // This has to happen after the notifyNetworkCallbacks as that tickles each
6381             // ConnectivityManager instance so that legacy requests correctly bind dns
6382             // requests to this network.  The legacy users are listening for this broadcast
6383             // and will generally do a dns request so they can ensureRouteToHost and if
6384             // they do that before the callbacks happen they'll use the default network.
6385             //
6386             // TODO: Is there still a race here? We send the broadcast
6387             // after sending the callback, but if the app can receive the
6388             // broadcast before the callback, it might still break.
6389             //
6390             // This *does* introduce a race where if the user uses the new api
6391             // (notification callbacks) and then uses the old api (getNetworkInfo(type))
6392             // they may get old info.  Reverse this after the old startUsing api is removed.
6393             // This is on top of the multiple intent sequencing referenced in the todo above.
6394             for (int i = 0; i < newNetwork.numNetworkRequests(); i++) {
6395                 NetworkRequest nr = newNetwork.requestAt(i);
6396                 if (nr.legacyType != TYPE_NONE && nr.isRequest()) {
6397                     // legacy type tracker filters out repeat adds
6398                     mLegacyTypeTracker.add(nr.legacyType, newNetwork);
6399                 }
6400             }
6401 
6402             // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above,
6403             // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest
6404             // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the
6405             // newNetwork to the tracker explicitly (it's a no-op if it has already been added).
6406             if (newNetwork.isVPN()) {
6407                 mLegacyTypeTracker.add(TYPE_VPN, newNetwork);
6408             }
6409         }
6410         if (reapUnvalidatedNetworks == ReapUnvalidatedNetworks.REAP) {
6411             for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
6412                 if (unneeded(nai, UnneededFor.TEARDOWN)) {
6413                     if (nai.getLingerExpiry() > 0) {
6414                         // This network has active linger timers and no requests, but is not
6415                         // lingering. Linger it.
6416                         //
6417                         // One way (the only way?) this can happen if this network is unvalidated
6418                         // and became unneeded due to another network improving its score to the
6419                         // point where this network will no longer be able to satisfy any requests
6420                         // even if it validates.
6421                         updateLingerState(nai, now);
6422                     } else {
6423                         if (DBG) log("Reaping " + nai.name());
6424                         teardownUnneededNetwork(nai);
6425                     }
6426                 }
6427             }
6428         }
6429     }
6430 
6431     /**
6432      * Attempt to rematch all Networks with NetworkRequests.  This may result in Networks
6433      * being disconnected.
6434      * @param changed If only one Network's score or capabilities have been modified since the last
6435      *         time this function was called, pass this Network in this argument, otherwise pass
6436      *         null.
6437      * @param oldScore If only one Network has been changed but its NetworkCapabilities have not
6438      *         changed, pass in the Network's score (from getCurrentScore()) prior to the change via
6439      *         this argument, otherwise pass {@code changed.getCurrentScore()} or 0 if
6440      *         {@code changed} is {@code null}. This is because NetworkCapabilities influence a
6441      *         network's score.
6442      */
rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore)6443     private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore) {
6444         // TODO: This may get slow.  The "changed" parameter is provided for future optimization
6445         // to avoid the slowness.  It is not simply enough to process just "changed", for
6446         // example in the case where "changed"'s score decreases and another network should begin
6447         // satisfying a NetworkRequest that "changed" currently satisfies.
6448 
6449         // Optimization: Only reprocess "changed" if its score improved.  This is safe because it
6450         // can only add more NetworkRequests satisfied by "changed", and this is exactly what
6451         // rematchNetworkAndRequests() handles.
6452         final long now = SystemClock.elapsedRealtime();
6453         if (changed != null && oldScore < changed.getCurrentScore()) {
6454             rematchNetworkAndRequests(changed, ReapUnvalidatedNetworks.REAP, now);
6455         } else {
6456             final NetworkAgentInfo[] nais = mNetworkAgentInfos.values().toArray(
6457                     new NetworkAgentInfo[mNetworkAgentInfos.size()]);
6458             // Rematch higher scoring networks first to prevent requests first matching a lower
6459             // scoring network and then a higher scoring network, which could produce multiple
6460             // callbacks and inadvertently unlinger networks.
6461             Arrays.sort(nais);
6462             for (NetworkAgentInfo nai : nais) {
6463                 rematchNetworkAndRequests(nai,
6464                         // Only reap the last time through the loop.  Reaping before all rematching
6465                         // is complete could incorrectly teardown a network that hasn't yet been
6466                         // rematched.
6467                         (nai != nais[nais.length-1]) ? ReapUnvalidatedNetworks.DONT_REAP
6468                                 : ReapUnvalidatedNetworks.REAP,
6469                         now);
6470             }
6471         }
6472     }
6473 
updateInetCondition(NetworkAgentInfo nai)6474     private void updateInetCondition(NetworkAgentInfo nai) {
6475         // Don't bother updating until we've graduated to validated at least once.
6476         if (!nai.everValidated) return;
6477         // For now only update icons for default connection.
6478         // TODO: Update WiFi and cellular icons separately. b/17237507
6479         if (!isDefaultNetwork(nai)) return;
6480 
6481         int newInetCondition = nai.lastValidated ? 100 : 0;
6482         // Don't repeat publish.
6483         if (newInetCondition == mDefaultInetConditionPublished) return;
6484 
6485         mDefaultInetConditionPublished = newInetCondition;
6486         sendInetConditionBroadcast(nai.networkInfo);
6487     }
6488 
notifyLockdownVpn(NetworkAgentInfo nai)6489     private void notifyLockdownVpn(NetworkAgentInfo nai) {
6490         synchronized (mVpns) {
6491             if (mLockdownTracker != null) {
6492                 if (nai != null && nai.isVPN()) {
6493                     mLockdownTracker.onVpnStateChanged(nai.networkInfo);
6494                 } else {
6495                     mLockdownTracker.onNetworkInfoChanged();
6496                 }
6497             }
6498         }
6499     }
6500 
updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo)6501     private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo) {
6502         final NetworkInfo.State state = newInfo.getState();
6503         NetworkInfo oldInfo = null;
6504         final int oldScore = networkAgent.getCurrentScore();
6505         synchronized (networkAgent) {
6506             oldInfo = networkAgent.networkInfo;
6507             networkAgent.networkInfo = newInfo;
6508         }
6509         notifyLockdownVpn(networkAgent);
6510 
6511         if (DBG) {
6512             log(networkAgent.name() + " EVENT_NETWORK_INFO_CHANGED, going from " +
6513                     (oldInfo == null ? "null" : oldInfo.getState()) +
6514                     " to " + state);
6515         }
6516 
6517         if (!networkAgent.created
6518                 && (state == NetworkInfo.State.CONNECTED
6519                 || (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) {
6520 
6521             // A network that has just connected has zero requests and is thus a foreground network.
6522             networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND);
6523 
6524             if (!createNativeNetwork(networkAgent)) return;
6525             networkAgent.created = true;
6526         }
6527 
6528         if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) {
6529             networkAgent.everConnected = true;
6530 
6531             if (networkAgent.linkProperties == null) {
6532                 Slog.wtf(TAG, networkAgent.name() + " connected with null LinkProperties");
6533             }
6534 
6535             // NetworkCapabilities need to be set before sending the private DNS config to
6536             // NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required.
6537             synchronized (networkAgent) {
6538                 networkAgent.setNetworkCapabilities(networkAgent.networkCapabilities);
6539             }
6540             handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig());
6541             updateLinkProperties(networkAgent, new LinkProperties(networkAgent.linkProperties),
6542                     null);
6543 
6544             // Until parceled LinkProperties are sent directly to NetworkMonitor, the connect
6545             // command must be sent after updating LinkProperties to maximize chances of
6546             // NetworkMonitor seeing the correct LinkProperties when starting.
6547             // TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call.
6548             if (networkAgent.networkMisc.acceptPartialConnectivity) {
6549                 networkAgent.networkMonitor().setAcceptPartialConnectivity();
6550             }
6551             networkAgent.networkMonitor().notifyNetworkConnected(
6552                     networkAgent.linkProperties, networkAgent.networkCapabilities);
6553             scheduleUnvalidatedPrompt(networkAgent);
6554 
6555             // Whether a particular NetworkRequest listen should cause signal strength thresholds to
6556             // be communicated to a particular NetworkAgent depends only on the network's immutable,
6557             // capabilities, so it only needs to be done once on initial connect, not every time the
6558             // network's capabilities change. Note that we do this before rematching the network,
6559             // so we could decide to tear it down immediately afterwards. That's fine though - on
6560             // disconnection NetworkAgents should stop any signal strength monitoring they have been
6561             // doing.
6562             updateSignalStrengthThresholds(networkAgent, "CONNECT", null);
6563 
6564             if (networkAgent.isVPN()) {
6565                 updateAllVpnsCapabilities();
6566             }
6567 
6568             // Consider network even though it is not yet validated.
6569             final long now = SystemClock.elapsedRealtime();
6570             rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP, now);
6571 
6572             // This has to happen after matching the requests, because callbacks are just requests.
6573             notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
6574         } else if (state == NetworkInfo.State.DISCONNECTED) {
6575             networkAgent.asyncChannel.disconnect();
6576             if (networkAgent.isVPN()) {
6577                 updateUids(networkAgent, networkAgent.networkCapabilities, null);
6578             }
6579             disconnectAndDestroyNetwork(networkAgent);
6580             if (networkAgent.isVPN()) {
6581                 // As the active or bound network changes for apps, broadcast the default proxy, as
6582                 // apps may need to update their proxy data. This is called after disconnecting from
6583                 // VPN to make sure we do not broadcast the old proxy data.
6584                 // TODO(b/122649188): send the broadcast only to VPN users.
6585                 mProxyTracker.sendProxyBroadcast();
6586             }
6587         } else if ((oldInfo != null && oldInfo.getState() == NetworkInfo.State.SUSPENDED) ||
6588                 state == NetworkInfo.State.SUSPENDED) {
6589             // going into or coming out of SUSPEND: re-score and notify
6590             if (networkAgent.getCurrentScore() != oldScore) {
6591                 rematchAllNetworksAndRequests(networkAgent, oldScore);
6592             }
6593             updateCapabilities(networkAgent.getCurrentScore(), networkAgent,
6594                     networkAgent.networkCapabilities);
6595             // TODO (b/73132094) : remove this call once the few users of onSuspended and
6596             // onResumed have been removed.
6597             notifyNetworkCallbacks(networkAgent, (state == NetworkInfo.State.SUSPENDED ?
6598                     ConnectivityManager.CALLBACK_SUSPENDED :
6599                     ConnectivityManager.CALLBACK_RESUMED));
6600             mLegacyTypeTracker.update(networkAgent);
6601         }
6602     }
6603 
updateNetworkScore(NetworkAgentInfo nai, int score)6604     private void updateNetworkScore(NetworkAgentInfo nai, int score) {
6605         if (VDBG || DDBG) log("updateNetworkScore for " + nai.name() + " to " + score);
6606         if (score < 0) {
6607             loge("updateNetworkScore for " + nai.name() + " got a negative score (" + score +
6608                     ").  Bumping score to min of 0");
6609             score = 0;
6610         }
6611 
6612         final int oldScore = nai.getCurrentScore();
6613         nai.setCurrentScore(score);
6614 
6615         rematchAllNetworksAndRequests(nai, oldScore);
6616 
6617         sendUpdatedScoreToFactories(nai);
6618     }
6619 
6620     // Notify only this one new request of the current state. Transfer all the
6621     // current state by calling NetworkCapabilities and LinkProperties callbacks
6622     // so that callers can be guaranteed to have as close to atomicity in state
6623     // transfer as can be supported by this current API.
notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri)6624     protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) {
6625         mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri);
6626         if (nri.mPendingIntent != null) {
6627             sendPendingIntentForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE);
6628             // Attempt no subsequent state pushes where intents are involved.
6629             return;
6630         }
6631 
6632         final boolean metered = nai.networkCapabilities.isMetered();
6633         final boolean blocked = isUidNetworkingWithVpnBlocked(nri.mUid, mUidRules.get(nri.mUid),
6634                 metered, mRestrictBackground);
6635         callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0);
6636     }
6637 
6638     /**
6639      * Notify of the blocked state apps with a registered callback matching a given NAI.
6640      *
6641      * Unlike other callbacks, blocked status is different between each individual uid. So for
6642      * any given nai, all requests need to be considered according to the uid who filed it.
6643      *
6644      * @param nai The target NetworkAgentInfo.
6645      * @param oldMetered True if the previous network capabilities is metered.
6646      * @param newRestrictBackground True if data saver is enabled.
6647      */
maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered, boolean newMetered, boolean oldRestrictBackground, boolean newRestrictBackground)6648     private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
6649             boolean newMetered, boolean oldRestrictBackground, boolean newRestrictBackground) {
6650 
6651         for (int i = 0; i < nai.numNetworkRequests(); i++) {
6652             NetworkRequest nr = nai.requestAt(i);
6653             NetworkRequestInfo nri = mNetworkRequests.get(nr);
6654             final int uidRules = mUidRules.get(nri.mUid);
6655             final boolean oldBlocked, newBlocked;
6656             // mVpns lock needs to be hold here to ensure that the active VPN cannot be changed
6657             // between these two calls.
6658             synchronized (mVpns) {
6659                 oldBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, oldMetered,
6660                         oldRestrictBackground);
6661                 newBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, newMetered,
6662                         newRestrictBackground);
6663             }
6664             if (oldBlocked != newBlocked) {
6665                 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
6666                         encodeBool(newBlocked));
6667             }
6668         }
6669     }
6670 
6671     /**
6672      * Notify apps with a given UID of the new blocked state according to new uid rules.
6673      * @param uid The uid for which the rules changed.
6674      * @param newRules The new rules to apply.
6675      */
maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules)6676     private void maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules) {
6677         for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
6678             final boolean metered = nai.networkCapabilities.isMetered();
6679             final boolean oldBlocked, newBlocked;
6680             // TODO: Consider that doze mode or turn on/off battery saver would deliver lots of uid
6681             // rules changed event. And this function actually loop through all connected nai and
6682             // its requests. It seems that mVpns lock will be grabbed frequently in this case.
6683             // Reduce the number of locking or optimize the use of lock are likely needed in future.
6684             synchronized (mVpns) {
6685                 oldBlocked = isUidNetworkingWithVpnBlocked(
6686                         uid, mUidRules.get(uid), metered, mRestrictBackground);
6687                 newBlocked = isUidNetworkingWithVpnBlocked(
6688                         uid, newRules, metered, mRestrictBackground);
6689             }
6690             if (oldBlocked == newBlocked) {
6691                 continue;
6692             }
6693             final int arg = encodeBool(newBlocked);
6694             for (int i = 0; i < nai.numNetworkRequests(); i++) {
6695                 NetworkRequest nr = nai.requestAt(i);
6696                 NetworkRequestInfo nri = mNetworkRequests.get(nr);
6697                 if (nri != null && nri.mUid == uid) {
6698                     callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, arg);
6699                 }
6700             }
6701         }
6702     }
6703 
6704     @VisibleForTesting
sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type)6705     protected void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
6706         // The NetworkInfo we actually send out has no bearing on the real
6707         // state of affairs. For example, if the default connection is mobile,
6708         // and a request for HIPRI has just gone away, we need to pretend that
6709         // HIPRI has just disconnected. So we need to set the type to HIPRI and
6710         // the state to DISCONNECTED, even though the network is of type MOBILE
6711         // and is still connected.
6712         NetworkInfo info = new NetworkInfo(nai.networkInfo);
6713         info.setType(type);
6714         if (state != DetailedState.DISCONNECTED) {
6715             info.setDetailedState(state, null, info.getExtraInfo());
6716             sendConnectedBroadcast(info);
6717         } else {
6718             info.setDetailedState(state, info.getReason(), info.getExtraInfo());
6719             Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
6720             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
6721             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
6722             if (info.isFailover()) {
6723                 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
6724                 nai.networkInfo.setFailover(false);
6725             }
6726             if (info.getReason() != null) {
6727                 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
6728             }
6729             if (info.getExtraInfo() != null) {
6730                 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
6731             }
6732             NetworkAgentInfo newDefaultAgent = null;
6733             if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
6734                 newDefaultAgent = getDefaultNetwork();
6735                 if (newDefaultAgent != null) {
6736                     intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
6737                             newDefaultAgent.networkInfo);
6738                 } else {
6739                     intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
6740                 }
6741             }
6742             intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
6743                     mDefaultInetConditionPublished);
6744             sendStickyBroadcast(intent);
6745             if (newDefaultAgent != null) {
6746                 sendConnectedBroadcast(newDefaultAgent.networkInfo);
6747             }
6748         }
6749     }
6750 
notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1)6751     protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) {
6752         if (VDBG || DDBG) {
6753             String notification = ConnectivityManager.getCallbackName(notifyType);
6754             log("notifyType " + notification + " for " + networkAgent.name());
6755         }
6756         for (int i = 0; i < networkAgent.numNetworkRequests(); i++) {
6757             NetworkRequest nr = networkAgent.requestAt(i);
6758             NetworkRequestInfo nri = mNetworkRequests.get(nr);
6759             if (VDBG) log(" sending notification for " + nr);
6760             // TODO: if we're in the middle of a rematch, can we send a CAP_CHANGED callback for
6761             // a network that no longer satisfies the listen?
6762             if (nri.mPendingIntent == null) {
6763                 callCallbackForRequest(nri, networkAgent, notifyType, arg1);
6764             } else {
6765                 sendPendingIntentForRequest(nri, networkAgent, notifyType);
6766             }
6767         }
6768     }
6769 
notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType)6770     protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
6771         notifyNetworkCallbacks(networkAgent, notifyType, 0);
6772     }
6773 
6774     /**
6775      * Returns the list of all interfaces that could be used by network traffic that does not
6776      * explicitly specify a network. This includes the default network, but also all VPNs that are
6777      * currently connected.
6778      *
6779      * Must be called on the handler thread.
6780      */
getDefaultNetworks()6781     private Network[] getDefaultNetworks() {
6782         ensureRunningOnConnectivityServiceThread();
6783         ArrayList<Network> defaultNetworks = new ArrayList<>();
6784         NetworkAgentInfo defaultNetwork = getDefaultNetwork();
6785         for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
6786             if (nai.everConnected && (nai == defaultNetwork || nai.isVPN())) {
6787                 defaultNetworks.add(nai.network);
6788             }
6789         }
6790         return defaultNetworks.toArray(new Network[0]);
6791     }
6792 
6793     /**
6794      * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the
6795      * properties tracked by NetworkStatsService on an active iface has changed.
6796      */
notifyIfacesChangedForNetworkStats()6797     private void notifyIfacesChangedForNetworkStats() {
6798         ensureRunningOnConnectivityServiceThread();
6799         String activeIface = null;
6800         LinkProperties activeLinkProperties = getActiveLinkProperties();
6801         if (activeLinkProperties != null) {
6802             activeIface = activeLinkProperties.getInterfaceName();
6803         }
6804         try {
6805             mStatsService.forceUpdateIfaces(
6806                     getDefaultNetworks(), getAllVpnInfo(), getAllNetworkState(), activeIface);
6807         } catch (Exception ignored) {
6808         }
6809     }
6810 
6811     @Override
addVpnAddress(String address, int prefixLength)6812     public boolean addVpnAddress(String address, int prefixLength) {
6813         int user = UserHandle.getUserId(Binder.getCallingUid());
6814         synchronized (mVpns) {
6815             throwIfLockdownEnabled();
6816             return mVpns.get(user).addAddress(address, prefixLength);
6817         }
6818     }
6819 
6820     @Override
removeVpnAddress(String address, int prefixLength)6821     public boolean removeVpnAddress(String address, int prefixLength) {
6822         int user = UserHandle.getUserId(Binder.getCallingUid());
6823         synchronized (mVpns) {
6824             throwIfLockdownEnabled();
6825             return mVpns.get(user).removeAddress(address, prefixLength);
6826         }
6827     }
6828 
6829     @Override
setUnderlyingNetworksForVpn(Network[] networks)6830     public boolean setUnderlyingNetworksForVpn(Network[] networks) {
6831         int user = UserHandle.getUserId(Binder.getCallingUid());
6832         final boolean success;
6833         synchronized (mVpns) {
6834             throwIfLockdownEnabled();
6835             success = mVpns.get(user).setUnderlyingNetworks(networks);
6836         }
6837         if (success) {
6838             mHandler.post(() -> {
6839                 // Update VPN's capabilities based on updated underlying network set.
6840                 updateAllVpnsCapabilities();
6841                 notifyIfacesChangedForNetworkStats();
6842             });
6843         }
6844         return success;
6845     }
6846 
6847     @Override
getCaptivePortalServerUrl()6848     public String getCaptivePortalServerUrl() {
6849         enforceConnectivityInternalPermission();
6850         String settingUrl = mContext.getResources().getString(
6851                 R.string.config_networkCaptivePortalServerUrl);
6852 
6853         if (!TextUtils.isEmpty(settingUrl)) {
6854             return settingUrl;
6855         }
6856 
6857         settingUrl = Settings.Global.getString(mContext.getContentResolver(),
6858                 Settings.Global.CAPTIVE_PORTAL_HTTP_URL);
6859         if (!TextUtils.isEmpty(settingUrl)) {
6860             return settingUrl;
6861         }
6862 
6863         return DEFAULT_CAPTIVE_PORTAL_HTTP_URL;
6864     }
6865 
6866     @Override
startNattKeepalive(Network network, int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr)6867     public void startNattKeepalive(Network network, int intervalSeconds,
6868             ISocketKeepaliveCallback cb, String srcAddr, int srcPort, String dstAddr) {
6869         enforceKeepalivePermission();
6870         mKeepaliveTracker.startNattKeepalive(
6871                 getNetworkAgentInfoForNetwork(network), null /* fd */,
6872                 intervalSeconds, cb,
6873                 srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT);
6874     }
6875 
6876     @Override
startNattKeepaliveWithFd(Network network, FileDescriptor fd, int resourceId, int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr, String dstAddr)6877     public void startNattKeepaliveWithFd(Network network, FileDescriptor fd, int resourceId,
6878             int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr,
6879             String dstAddr) {
6880         mKeepaliveTracker.startNattKeepalive(
6881                 getNetworkAgentInfoForNetwork(network), fd, resourceId,
6882                 intervalSeconds, cb,
6883                 srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT);
6884     }
6885 
6886     @Override
startTcpKeepalive(Network network, FileDescriptor fd, int intervalSeconds, ISocketKeepaliveCallback cb)6887     public void startTcpKeepalive(Network network, FileDescriptor fd, int intervalSeconds,
6888             ISocketKeepaliveCallback cb) {
6889         enforceKeepalivePermission();
6890         mKeepaliveTracker.startTcpKeepalive(
6891                 getNetworkAgentInfoForNetwork(network), fd, intervalSeconds, cb);
6892     }
6893 
6894     @Override
stopKeepalive(Network network, int slot)6895     public void stopKeepalive(Network network, int slot) {
6896         mHandler.sendMessage(mHandler.obtainMessage(
6897                 NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE, slot, SocketKeepalive.SUCCESS, network));
6898     }
6899 
6900     @Override
factoryReset()6901     public void factoryReset() {
6902         enforceConnectivityInternalPermission();
6903 
6904         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
6905             return;
6906         }
6907 
6908         final int userId = UserHandle.getCallingUserId();
6909 
6910         Binder.withCleanCallingIdentity(() -> {
6911             final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext);
6912             ipMemoryStore.factoryReset();
6913         });
6914 
6915         // Turn airplane mode off
6916         setAirplaneMode(false);
6917 
6918         if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) {
6919             // Untether
6920             String pkgName = mContext.getOpPackageName();
6921             for (String tether : getTetheredIfaces()) {
6922                 untether(tether, pkgName);
6923             }
6924         }
6925 
6926         if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) {
6927             // Remove always-on package
6928             synchronized (mVpns) {
6929                 final String alwaysOnPackage = getAlwaysOnVpnPackage(userId);
6930                 if (alwaysOnPackage != null) {
6931                     setAlwaysOnVpnPackage(userId, null, false, null);
6932                     setVpnPackageAuthorization(alwaysOnPackage, userId, false);
6933                 }
6934 
6935                 // Turn Always-on VPN off
6936                 if (mLockdownEnabled && userId == UserHandle.USER_SYSTEM) {
6937                     final long ident = Binder.clearCallingIdentity();
6938                     try {
6939                         mKeyStore.delete(Credentials.LOCKDOWN_VPN);
6940                         mLockdownEnabled = false;
6941                         setLockdownTracker(null);
6942                     } finally {
6943                         Binder.restoreCallingIdentity(ident);
6944                     }
6945                 }
6946 
6947                 // Turn VPN off
6948                 VpnConfig vpnConfig = getVpnConfig(userId);
6949                 if (vpnConfig != null) {
6950                     if (vpnConfig.legacy) {
6951                         prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, userId);
6952                     } else {
6953                         // Prevent this app (packagename = vpnConfig.user) from initiating
6954                         // VPN connections in the future without user intervention.
6955                         setVpnPackageAuthorization(vpnConfig.user, userId, false);
6956 
6957                         prepareVpn(null, VpnConfig.LEGACY_VPN, userId);
6958                     }
6959                 }
6960             }
6961         }
6962 
6963         // restore private DNS settings to default mode (opportunistic)
6964         if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_PRIVATE_DNS)) {
6965             Settings.Global.putString(mContext.getContentResolver(),
6966                     Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OPPORTUNISTIC);
6967         }
6968 
6969         Settings.Global.putString(mContext.getContentResolver(),
6970                 Settings.Global.NETWORK_AVOID_BAD_WIFI, null);
6971     }
6972 
6973     @Override
getNetworkWatchlistConfigHash()6974     public byte[] getNetworkWatchlistConfigHash() {
6975         NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class);
6976         if (nwm == null) {
6977             loge("Unable to get NetworkWatchlistManager");
6978             return null;
6979         }
6980         // Redirect it to network watchlist service to access watchlist file and calculate hash.
6981         return nwm.getWatchlistConfigHash();
6982     }
6983 
6984     @VisibleForTesting
createMultinetworkPolicyTracker(Context c, Handler h, Runnable r)6985     MultinetworkPolicyTracker createMultinetworkPolicyTracker(Context c, Handler h, Runnable r) {
6986         return new MultinetworkPolicyTracker(c, h, r);
6987     }
6988 
6989     @VisibleForTesting
makeWakeupMessage(Context c, Handler h, String s, int cmd, Object obj)6990     public WakeupMessage makeWakeupMessage(Context c, Handler h, String s, int cmd, Object obj) {
6991         return new WakeupMessage(c, h, s, cmd, 0, 0, obj);
6992     }
6993 
6994     @VisibleForTesting
hasService(String name)6995     public boolean hasService(String name) {
6996         return ServiceManager.checkService(name) != null;
6997     }
6998 
6999     @VisibleForTesting
metricsLogger()7000     protected IpConnectivityMetrics.Logger metricsLogger() {
7001         return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class),
7002                 "no IpConnectivityMetrics service");
7003     }
7004 
logNetworkEvent(NetworkAgentInfo nai, int evtype)7005     private void logNetworkEvent(NetworkAgentInfo nai, int evtype) {
7006         int[] transports = nai.networkCapabilities.getTransportTypes();
7007         mMetricsLog.log(nai.network.netId, transports, new NetworkEvent(evtype));
7008     }
7009 
toBool(int encodedBoolean)7010     private static boolean toBool(int encodedBoolean) {
7011         return encodedBoolean != 0; // Only 0 means false.
7012     }
7013 
encodeBool(boolean b)7014     private static int encodeBool(boolean b) {
7015         return b ? 1 : 0;
7016     }
7017 
7018     @Override
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)7019     public void onShellCommand(FileDescriptor in, FileDescriptor out,
7020             FileDescriptor err, String[] args, ShellCallback callback,
7021             ResultReceiver resultReceiver) {
7022         (new ShellCmd()).exec(this, in, out, err, args, callback, resultReceiver);
7023     }
7024 
7025     private class ShellCmd extends ShellCommand {
7026 
7027         @Override
onCommand(String cmd)7028         public int onCommand(String cmd) {
7029             if (cmd == null) {
7030                 return handleDefaultCommands(cmd);
7031             }
7032             final PrintWriter pw = getOutPrintWriter();
7033             try {
7034                 switch (cmd) {
7035                     case "airplane-mode":
7036                         final String action = getNextArg();
7037                         if ("enable".equals(action)) {
7038                             setAirplaneMode(true);
7039                             return 0;
7040                         } else if ("disable".equals(action)) {
7041                             setAirplaneMode(false);
7042                             return 0;
7043                         } else if (action == null) {
7044                             final ContentResolver cr = mContext.getContentResolver();
7045                             final int enabled = Settings.Global.getInt(cr,
7046                                     Settings.Global.AIRPLANE_MODE_ON);
7047                             pw.println(enabled == 0 ? "disabled" : "enabled");
7048                             return 0;
7049                         } else {
7050                             onHelp();
7051                             return -1;
7052                         }
7053                     default:
7054                         return handleDefaultCommands(cmd);
7055                 }
7056             } catch (Exception e) {
7057                 pw.println(e);
7058             }
7059             return -1;
7060         }
7061 
7062         @Override
onHelp()7063         public void onHelp() {
7064             PrintWriter pw = getOutPrintWriter();
7065             pw.println("Connectivity service commands:");
7066             pw.println("  help");
7067             pw.println("    Print this help text.");
7068             pw.println("  airplane-mode [enable|disable]");
7069             pw.println("    Turn airplane mode on or off.");
7070             pw.println("  airplane-mode");
7071             pw.println("    Get airplane mode.");
7072         }
7073     }
7074 
7075     @GuardedBy("mVpns")
getVpnIfOwner()7076     private Vpn getVpnIfOwner() {
7077         final int uid = Binder.getCallingUid();
7078         final int user = UserHandle.getUserId(uid);
7079 
7080         final Vpn vpn = mVpns.get(user);
7081         if (vpn == null) {
7082             return null;
7083         } else {
7084             final VpnInfo info = vpn.getVpnInfo();
7085             return (info == null || info.ownerUid != uid) ? null : vpn;
7086         }
7087     }
7088 
7089     /**
7090      * Caller either needs to be an active VPN, or hold the NETWORK_STACK permission
7091      * for testing.
7092      */
enforceActiveVpnOrNetworkStackPermission()7093     private Vpn enforceActiveVpnOrNetworkStackPermission() {
7094         if (checkNetworkStackPermission()) {
7095             return null;
7096         }
7097         synchronized (mVpns) {
7098             Vpn vpn = getVpnIfOwner();
7099             if (vpn != null) {
7100                 return vpn;
7101             }
7102         }
7103         throw new SecurityException("App must either be an active VPN or have the NETWORK_STACK "
7104                 + "permission");
7105     }
7106 
7107     /**
7108      * @param connectionInfo the connection to resolve.
7109      * @return {@code uid} if the connection is found and the app has permission to observe it
7110      * (e.g., if it is associated with the calling VPN app's tunnel) or {@code INVALID_UID} if the
7111      * connection is not found.
7112      */
getConnectionOwnerUid(ConnectionInfo connectionInfo)7113     public int getConnectionOwnerUid(ConnectionInfo connectionInfo) {
7114         final Vpn vpn = enforceActiveVpnOrNetworkStackPermission();
7115         if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) {
7116             throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol);
7117         }
7118 
7119         final int uid = InetDiagMessage.getConnectionOwnerUid(connectionInfo.protocol,
7120                 connectionInfo.local, connectionInfo.remote);
7121 
7122         /* Filter out Uids not associated with the VPN. */
7123         if (vpn != null && !vpn.appliesToUid(uid)) {
7124             return INVALID_UID;
7125         }
7126 
7127         return uid;
7128     }
7129 
7130     @Override
isCallerCurrentAlwaysOnVpnApp()7131     public boolean isCallerCurrentAlwaysOnVpnApp() {
7132         synchronized (mVpns) {
7133             Vpn vpn = getVpnIfOwner();
7134             return vpn != null && vpn.getAlwaysOn();
7135         }
7136     }
7137 
7138     @Override
isCallerCurrentAlwaysOnVpnLockdownApp()7139     public boolean isCallerCurrentAlwaysOnVpnLockdownApp() {
7140         synchronized (mVpns) {
7141             Vpn vpn = getVpnIfOwner();
7142             return vpn != null && vpn.getLockdown();
7143         }
7144     }
7145 
7146     /**
7147      * Returns a IBinder to a TestNetworkService. Will be lazily created as needed.
7148      *
7149      * <p>The TestNetworkService must be run in the system server due to TUN creation.
7150      */
7151     @Override
startOrGetTestNetworkService()7152     public IBinder startOrGetTestNetworkService() {
7153         synchronized (mTNSLock) {
7154             TestNetworkService.enforceTestNetworkPermissions(mContext);
7155 
7156             if (mTNS == null) {
7157                 mTNS = new TestNetworkService(mContext, mNMS);
7158             }
7159 
7160             return mTNS;
7161         }
7162     }
7163 }
7164