OSDN Git Service

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