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