• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server;
18 
19 import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
20 import static android.content.pm.PackageManager.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 
networkRequiresPrivateDnsValidation(NetworkAgentInfo nai)2342     private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) {
2343         return nai.networkMonitor.isPrivateDnsValidationRequired();
2344     }
2345 
handlePrivateDnsSettingsChanged()2346     private void handlePrivateDnsSettingsChanged() {
2347         final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
2348 
2349         for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
2350             handlePerNetworkPrivateDnsConfig(nai, cfg);
2351             if (networkRequiresPrivateDnsValidation(nai)) {
2352                 handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
2353             }
2354         }
2355     }
2356 
handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg)2357     private void handlePerNetworkPrivateDnsConfig(NetworkAgentInfo nai, PrivateDnsConfig cfg) {
2358         if (!networkRequiresPrivateDnsValidation(nai)) return;
2359 
2360         // Notify the NetworkMonitor thread in case it needs to cancel or
2361         // schedule DNS resolutions. If a DNS resolution is required the
2362         // result will be sent back to us.
2363         nai.networkMonitor.notifyPrivateDnsSettingsChanged(cfg);
2364 
2365         // With Private DNS bypass support, we can proceed to update the
2366         // Private DNS config immediately, even if we're in strict mode
2367         // and have not yet resolved the provider name into a set of IPs.
2368         updatePrivateDns(nai, cfg);
2369     }
2370 
updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg)2371     private void updatePrivateDns(NetworkAgentInfo nai, PrivateDnsConfig newCfg) {
2372         mDnsManager.updatePrivateDns(nai.network, newCfg);
2373         updateDnses(nai.linkProperties, null, nai.network.netId);
2374     }
2375 
handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update)2376     private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) {
2377         NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId);
2378         if (nai == null) {
2379             return;
2380         }
2381         mDnsManager.updatePrivateDnsValidation(update);
2382         handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
2383     }
2384 
updateLingerState(NetworkAgentInfo nai, long now)2385     private void updateLingerState(NetworkAgentInfo nai, long now) {
2386         // 1. Update the linger timer. If it's changed, reschedule or cancel the alarm.
2387         // 2. If the network was lingering and there are now requests, unlinger it.
2388         // 3. If this network is unneeded (which implies it is not lingering), and there is at least
2389         //    one lingered request, start lingering.
2390         nai.updateLingerTimer();
2391         if (nai.isLingering() && nai.numForegroundNetworkRequests() > 0) {
2392             if (DBG) log("Unlingering " + nai.name());
2393             nai.unlinger();
2394             logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER);
2395         } else if (unneeded(nai, UnneededFor.LINGER) && nai.getLingerExpiry() > 0) {
2396             int lingerTime = (int) (nai.getLingerExpiry() - now);
2397             if (DBG) log("Lingering " + nai.name() + " for " + lingerTime + "ms");
2398             nai.linger();
2399             logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER);
2400             notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime);
2401         }
2402     }
2403 
handleAsyncChannelHalfConnect(Message msg)2404     private void handleAsyncChannelHalfConnect(Message msg) {
2405         AsyncChannel ac = (AsyncChannel) msg.obj;
2406         if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {
2407             if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
2408                 if (VDBG) log("NetworkFactory connected");
2409                 // A network factory has connected.  Send it all current NetworkRequests.
2410                 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
2411                     if (nri.request.isListen()) continue;
2412                     NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId);
2413                     ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK,
2414                             (nai != null ? nai.getCurrentScore() : 0), 0, nri.request);
2415                 }
2416             } else {
2417                 loge("Error connecting NetworkFactory");
2418                 mNetworkFactoryInfos.remove(msg.obj);
2419             }
2420         } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) {
2421             if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
2422                 if (VDBG) log("NetworkAgent connected");
2423                 // A network agent has requested a connection.  Establish the connection.
2424                 mNetworkAgentInfos.get(msg.replyTo).asyncChannel.
2425                         sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
2426             } else {
2427                 loge("Error connecting NetworkAgent");
2428                 NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo);
2429                 if (nai != null) {
2430                     final boolean wasDefault = isDefaultNetwork(nai);
2431                     synchronized (mNetworkForNetId) {
2432                         mNetworkForNetId.remove(nai.network.netId);
2433                         mNetIdInUse.delete(nai.network.netId);
2434                     }
2435                     // Just in case.
2436                     mLegacyTypeTracker.remove(nai, wasDefault);
2437                 }
2438             }
2439         }
2440     }
2441 
2442     // This is a no-op if it's called with a message designating a network that has
2443     // already been destroyed, because its reference will not be found in the relevant
2444     // maps.
handleAsyncChannelDisconnected(Message msg)2445     private void handleAsyncChannelDisconnected(Message msg) {
2446         NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
2447         if (nai != null) {
2448             disconnectAndDestroyNetwork(nai);
2449         } else {
2450             NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo);
2451             if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name);
2452         }
2453     }
2454 
2455     // Destroys a network, remove references to it from the internal state managed by
2456     // ConnectivityService, free its interfaces and clean up.
2457     // Must be called on the Handler thread.
disconnectAndDestroyNetwork(NetworkAgentInfo nai)2458     private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) {
2459         if (DBG) {
2460             log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests());
2461         }
2462         // A network agent has disconnected.
2463         // TODO - if we move the logic to the network agent (have them disconnect
2464         // because they lost all their requests or because their score isn't good)
2465         // then they would disconnect organically, report their new state and then
2466         // disconnect the channel.
2467         if (nai.networkInfo.isConnected()) {
2468             nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
2469                     null, null);
2470         }
2471         final boolean wasDefault = isDefaultNetwork(nai);
2472         if (wasDefault) {
2473             mDefaultInetConditionPublished = 0;
2474             // Log default network disconnection before required book-keeping.
2475             // Let rematchAllNetworksAndRequests() below record a new default network event
2476             // if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence
2477             // whose timestamps tell how long it takes to recover a default network.
2478             long now = SystemClock.elapsedRealtime();
2479             metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai);
2480         }
2481         notifyIfacesChangedForNetworkStats();
2482         // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
2483         // by other networks that are already connected. Perhaps that can be done by
2484         // sending all CALLBACK_LOST messages (for requests, not listens) at the end
2485         // of rematchAllNetworksAndRequests
2486         notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
2487         mKeepaliveTracker.handleStopAllKeepalives(nai,
2488                 ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK);
2489         for (String iface : nai.linkProperties.getAllInterfaceNames()) {
2490             // Disable wakeup packet monitoring for each interface.
2491             wakeupModifyInterface(iface, nai.networkCapabilities, false);
2492         }
2493         nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
2494         mNetworkAgentInfos.remove(nai.messenger);
2495         nai.maybeStopClat();
2496         synchronized (mNetworkForNetId) {
2497             // Remove the NetworkAgent, but don't mark the netId as
2498             // available until we've told netd to delete it below.
2499             mNetworkForNetId.remove(nai.network.netId);
2500         }
2501         // Remove all previously satisfied requests.
2502         for (int i = 0; i < nai.numNetworkRequests(); i++) {
2503             NetworkRequest request = nai.requestAt(i);
2504             NetworkAgentInfo currentNetwork = getNetworkForRequest(request.requestId);
2505             if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
2506                 clearNetworkForRequest(request.requestId);
2507                 sendUpdatedScoreToFactories(request, 0);
2508             }
2509         }
2510         nai.clearLingerState();
2511         if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
2512             removeDataActivityTracking(nai);
2513             notifyLockdownVpn(nai);
2514             ensureNetworkTransitionWakelock(nai.name());
2515         }
2516         mLegacyTypeTracker.remove(nai, wasDefault);
2517         if (!nai.networkCapabilities.hasTransport(TRANSPORT_VPN)) {
2518             updateAllVpnsCapabilities();
2519         }
2520         rematchAllNetworksAndRequests(null, 0);
2521         mLingerMonitor.noteDisconnect(nai);
2522         if (nai.created) {
2523             // Tell netd to clean up the configuration for this network
2524             // (routing rules, DNS, etc).
2525             // This may be slow as it requires a lot of netd shelling out to ip and
2526             // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it
2527             // after we've rematched networks with requests which should make a potential
2528             // fallback network the default or requested a new network from the
2529             // NetworkFactories, so network traffic isn't interrupted for an unnecessarily
2530             // long time.
2531             try {
2532                 mNetd.removeNetwork(nai.network.netId);
2533             } catch (Exception e) {
2534                 loge("Exception removing network: " + e);
2535             }
2536             mDnsManager.removeNetwork(nai.network);
2537         }
2538         synchronized (mNetworkForNetId) {
2539             mNetIdInUse.delete(nai.network.netId);
2540         }
2541     }
2542 
2543     // If this method proves to be too slow then we can maintain a separate
2544     // pendingIntent => NetworkRequestInfo map.
2545     // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo.
findExistingNetworkRequestInfo(PendingIntent pendingIntent)2546     private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) {
2547         Intent intent = pendingIntent.getIntent();
2548         for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) {
2549             PendingIntent existingPendingIntent = entry.getValue().mPendingIntent;
2550             if (existingPendingIntent != null &&
2551                     existingPendingIntent.getIntent().filterEquals(intent)) {
2552                 return entry.getValue();
2553             }
2554         }
2555         return null;
2556     }
2557 
handleRegisterNetworkRequestWithIntent(Message msg)2558     private void handleRegisterNetworkRequestWithIntent(Message msg) {
2559         final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
2560 
2561         NetworkRequestInfo existingRequest = findExistingNetworkRequestInfo(nri.mPendingIntent);
2562         if (existingRequest != null) { // remove the existing request.
2563             if (DBG) log("Replacing " + existingRequest.request + " with "
2564                     + nri.request + " because their intents matched.");
2565             handleReleaseNetworkRequest(existingRequest.request, getCallingUid());
2566         }
2567         handleRegisterNetworkRequest(nri);
2568     }
2569 
handleRegisterNetworkRequest(NetworkRequestInfo nri)2570     private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
2571         mNetworkRequests.put(nri.request, nri);
2572         mNetworkRequestInfoLogs.log("REGISTER " + nri);
2573         if (nri.request.isListen()) {
2574             for (NetworkAgentInfo network : mNetworkAgentInfos.values()) {
2575                 if (nri.request.networkCapabilities.hasSignalStrength() &&
2576                         network.satisfiesImmutableCapabilitiesOf(nri.request)) {
2577                     updateSignalStrengthThresholds(network, "REGISTER", nri.request);
2578                 }
2579             }
2580         }
2581         rematchAllNetworksAndRequests(null, 0);
2582         if (nri.request.isRequest() && getNetworkForRequest(nri.request.requestId) == null) {
2583             sendUpdatedScoreToFactories(nri.request, 0);
2584         }
2585     }
2586 
handleReleaseNetworkRequestWithIntent(PendingIntent pendingIntent, int callingUid)2587     private void handleReleaseNetworkRequestWithIntent(PendingIntent pendingIntent,
2588             int callingUid) {
2589         NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent);
2590         if (nri != null) {
2591             handleReleaseNetworkRequest(nri.request, callingUid);
2592         }
2593     }
2594 
2595     // Determines whether the network is the best (or could become the best, if it validated), for
2596     // none of a particular type of NetworkRequests. The type of NetworkRequests considered depends
2597     // on the value of reason:
2598     //
2599     // - UnneededFor.TEARDOWN: non-listen NetworkRequests. If a network is unneeded for this reason,
2600     //   then it should be torn down.
2601     // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason,
2602     //   then it should be lingered.
unneeded(NetworkAgentInfo nai, UnneededFor reason)2603     private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
2604         final int numRequests;
2605         switch (reason) {
2606             case TEARDOWN:
2607                 numRequests = nai.numRequestNetworkRequests();
2608                 break;
2609             case LINGER:
2610                 numRequests = nai.numForegroundNetworkRequests();
2611                 break;
2612             default:
2613                 Slog.wtf(TAG, "Invalid reason. Cannot happen.");
2614                 return true;
2615         }
2616 
2617         if (!nai.everConnected || nai.isVPN() || nai.isLingering() || numRequests > 0) {
2618             return false;
2619         }
2620         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
2621             if (reason == UnneededFor.LINGER && nri.request.isBackgroundRequest()) {
2622                 // Background requests don't affect lingering.
2623                 continue;
2624             }
2625 
2626             // If this Network is already the highest scoring Network for a request, or if
2627             // there is hope for it to become one if it validated, then it is needed.
2628             if (nri.request.isRequest() && nai.satisfies(nri.request) &&
2629                     (nai.isSatisfyingRequest(nri.request.requestId) ||
2630                     // Note that this catches two important cases:
2631                     // 1. Unvalidated cellular will not be reaped when unvalidated WiFi
2632                     //    is currently satisfying the request.  This is desirable when
2633                     //    cellular ends up validating but WiFi does not.
2634                     // 2. Unvalidated WiFi will not be reaped when validated cellular
2635                     //    is currently satisfying the request.  This is desirable when
2636                     //    WiFi ends up validating and out scoring cellular.
2637                     getNetworkForRequest(nri.request.requestId).getCurrentScore() <
2638                             nai.getCurrentScoreAsValidated())) {
2639                 return false;
2640             }
2641         }
2642         return true;
2643     }
2644 
getNriForAppRequest( NetworkRequest request, int callingUid, String requestedOperation)2645     private NetworkRequestInfo getNriForAppRequest(
2646             NetworkRequest request, int callingUid, String requestedOperation) {
2647         final NetworkRequestInfo nri = mNetworkRequests.get(request);
2648 
2649         if (nri != null) {
2650             if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) {
2651                 log(String.format("UID %d attempted to %s for unowned request %s",
2652                         callingUid, requestedOperation, nri));
2653                 return null;
2654             }
2655         }
2656 
2657         return nri;
2658     }
2659 
handleTimedOutNetworkRequest(final NetworkRequestInfo nri)2660     private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) {
2661         if (mNetworkRequests.get(nri.request) == null) {
2662             return;
2663         }
2664         if (getNetworkForRequest(nri.request.requestId) != null) {
2665             return;
2666         }
2667         if (VDBG || (DBG && nri.request.isRequest())) {
2668             log("releasing " + nri.request + " (timeout)");
2669         }
2670         handleRemoveNetworkRequest(nri);
2671         callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
2672     }
2673 
handleReleaseNetworkRequest(NetworkRequest request, int callingUid)2674     private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) {
2675         final NetworkRequestInfo nri =
2676                 getNriForAppRequest(request, callingUid, "release NetworkRequest");
2677         if (nri == null) {
2678             return;
2679         }
2680         if (VDBG || (DBG && nri.request.isRequest())) {
2681             log("releasing " + nri.request + " (release request)");
2682         }
2683         handleRemoveNetworkRequest(nri);
2684     }
2685 
handleRemoveNetworkRequest(final NetworkRequestInfo nri)2686     private void handleRemoveNetworkRequest(final NetworkRequestInfo nri) {
2687         nri.unlinkDeathRecipient();
2688         mNetworkRequests.remove(nri.request);
2689 
2690         synchronized (mUidToNetworkRequestCount) {
2691             int requests = mUidToNetworkRequestCount.get(nri.mUid, 0);
2692             if (requests < 1) {
2693                 Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " +
2694                         nri.mUid);
2695             } else if (requests == 1) {
2696                 mUidToNetworkRequestCount.removeAt(
2697                         mUidToNetworkRequestCount.indexOfKey(nri.mUid));
2698             } else {
2699                 mUidToNetworkRequestCount.put(nri.mUid, requests - 1);
2700             }
2701         }
2702 
2703         mNetworkRequestInfoLogs.log("RELEASE " + nri);
2704         if (nri.request.isRequest()) {
2705             boolean wasKept = false;
2706             NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId);
2707             if (nai != null) {
2708                 boolean wasBackgroundNetwork = nai.isBackgroundNetwork();
2709                 nai.removeRequest(nri.request.requestId);
2710                 if (VDBG) {
2711                     log(" Removing from current network " + nai.name() +
2712                             ", leaving " + nai.numNetworkRequests() + " requests.");
2713                 }
2714                 // If there are still lingered requests on this network, don't tear it down,
2715                 // but resume lingering instead.
2716                 updateLingerState(nai, SystemClock.elapsedRealtime());
2717                 if (unneeded(nai, UnneededFor.TEARDOWN)) {
2718                     if (DBG) log("no live requests for " + nai.name() + "; disconnecting");
2719                     teardownUnneededNetwork(nai);
2720                 } else {
2721                     wasKept = true;
2722                 }
2723                 clearNetworkForRequest(nri.request.requestId);
2724                 if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) {
2725                     // Went from foreground to background.
2726                     updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
2727                 }
2728             }
2729 
2730             // TODO: remove this code once we know that the Slog.wtf is never hit.
2731             //
2732             // Find all networks that are satisfying this request and remove the request
2733             // from their request lists.
2734             // TODO - it's my understanding that for a request there is only a single
2735             // network satisfying it, so this loop is wasteful
2736             for (NetworkAgentInfo otherNai : mNetworkAgentInfos.values()) {
2737                 if (otherNai.isSatisfyingRequest(nri.request.requestId) && otherNai != nai) {
2738                     Slog.wtf(TAG, "Request " + nri.request + " satisfied by " +
2739                             otherNai.name() + ", but mNetworkAgentInfos says " +
2740                             (nai != null ? nai.name() : "null"));
2741                 }
2742             }
2743 
2744             // Maintain the illusion.  When this request arrived, we might have pretended
2745             // that a network connected to serve it, even though the network was already
2746             // connected.  Now that this request has gone away, we might have to pretend
2747             // that the network disconnected.  LegacyTypeTracker will generate that
2748             // phantom disconnect for this type.
2749             if (nri.request.legacyType != TYPE_NONE && nai != null) {
2750                 boolean doRemove = true;
2751                 if (wasKept) {
2752                     // check if any of the remaining requests for this network are for the
2753                     // same legacy type - if so, don't remove the nai
2754                     for (int i = 0; i < nai.numNetworkRequests(); i++) {
2755                         NetworkRequest otherRequest = nai.requestAt(i);
2756                         if (otherRequest.legacyType == nri.request.legacyType &&
2757                                 otherRequest.isRequest()) {
2758                             if (DBG) log(" still have other legacy request - leaving");
2759                             doRemove = false;
2760                         }
2761                     }
2762                 }
2763 
2764                 if (doRemove) {
2765                     mLegacyTypeTracker.remove(nri.request.legacyType, nai, false);
2766                 }
2767             }
2768 
2769             for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
2770                 nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST,
2771                         nri.request);
2772             }
2773         } else {
2774             // listens don't have a singular affectedNetwork.  Check all networks to see
2775             // if this listen request applies and remove it.
2776             for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
2777                 nai.removeRequest(nri.request.requestId);
2778                 if (nri.request.networkCapabilities.hasSignalStrength() &&
2779                         nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
2780                     updateSignalStrengthThresholds(nai, "RELEASE", nri.request);
2781                 }
2782             }
2783         }
2784     }
2785 
2786     @Override
setAcceptUnvalidated(Network network, boolean accept, boolean always)2787     public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
2788         enforceConnectivityInternalPermission();
2789         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_ACCEPT_UNVALIDATED,
2790                 encodeBool(accept), encodeBool(always), network));
2791     }
2792 
2793     @Override
setAvoidUnvalidated(Network network)2794     public void setAvoidUnvalidated(Network network) {
2795         enforceConnectivityInternalPermission();
2796         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network));
2797     }
2798 
handleSetAcceptUnvalidated(Network network, boolean accept, boolean always)2799     private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) {
2800         if (DBG) log("handleSetAcceptUnvalidated network=" + network +
2801                 " accept=" + accept + " always=" + always);
2802 
2803         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
2804         if (nai == null) {
2805             // Nothing to do.
2806             return;
2807         }
2808 
2809         if (nai.everValidated) {
2810             // The network validated while the dialog box was up. Take no action.
2811             return;
2812         }
2813 
2814         if (!nai.networkMisc.explicitlySelected) {
2815             Slog.wtf(TAG, "BUG: setAcceptUnvalidated non non-explicitly selected network");
2816         }
2817 
2818         if (accept != nai.networkMisc.acceptUnvalidated) {
2819             int oldScore = nai.getCurrentScore();
2820             nai.networkMisc.acceptUnvalidated = accept;
2821             rematchAllNetworksAndRequests(nai, oldScore);
2822             sendUpdatedScoreToFactories(nai);
2823         }
2824 
2825         if (always) {
2826             nai.asyncChannel.sendMessage(
2827                     NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED, encodeBool(accept));
2828         }
2829 
2830         if (!accept) {
2831             // Tell the NetworkAgent to not automatically reconnect to the network.
2832             nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
2833             // Teardown the nework.
2834             teardownUnneededNetwork(nai);
2835         }
2836 
2837     }
2838 
handleSetAvoidUnvalidated(Network network)2839     private void handleSetAvoidUnvalidated(Network network) {
2840         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
2841         if (nai == null || nai.lastValidated) {
2842             // Nothing to do. The network either disconnected or revalidated.
2843             return;
2844         }
2845         if (!nai.avoidUnvalidated) {
2846             int oldScore = nai.getCurrentScore();
2847             nai.avoidUnvalidated = true;
2848             rematchAllNetworksAndRequests(nai, oldScore);
2849             sendUpdatedScoreToFactories(nai);
2850         }
2851     }
2852 
scheduleUnvalidatedPrompt(NetworkAgentInfo nai)2853     private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) {
2854         if (VDBG) log("scheduleUnvalidatedPrompt " + nai.network);
2855         mHandler.sendMessageDelayed(
2856                 mHandler.obtainMessage(EVENT_PROMPT_UNVALIDATED, nai.network),
2857                 PROMPT_UNVALIDATED_DELAY_MS);
2858     }
2859 
2860     @Override
startCaptivePortalApp(Network network)2861     public void startCaptivePortalApp(Network network) {
2862         enforceConnectivityInternalPermission();
2863         mHandler.post(() -> {
2864             NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
2865             if (nai == null) return;
2866             if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return;
2867             nai.networkMonitor.sendMessage(NetworkMonitor.CMD_LAUNCH_CAPTIVE_PORTAL_APP);
2868         });
2869     }
2870 
avoidBadWifi()2871     public boolean avoidBadWifi() {
2872         return mMultinetworkPolicyTracker.getAvoidBadWifi();
2873     }
2874 
rematchForAvoidBadWifiUpdate()2875     private void rematchForAvoidBadWifiUpdate() {
2876         rematchAllNetworksAndRequests(null, 0);
2877         for (NetworkAgentInfo nai: mNetworkAgentInfos.values()) {
2878             if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
2879                 sendUpdatedScoreToFactories(nai);
2880             }
2881         }
2882     }
2883 
2884     // TODO: Evaluate whether this is of interest to other consumers of
2885     // MultinetworkPolicyTracker and worth moving out of here.
dumpAvoidBadWifiSettings(IndentingPrintWriter pw)2886     private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) {
2887         final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi();
2888         if (!configRestrict) {
2889             pw.println("Bad Wi-Fi avoidance: unrestricted");
2890             return;
2891         }
2892 
2893         pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi());
2894         pw.increaseIndent();
2895         pw.println("Config restrict:   " + configRestrict);
2896 
2897         final String value = mMultinetworkPolicyTracker.getAvoidBadWifiSetting();
2898         String description;
2899         // Can't use a switch statement because strings are legal case labels, but null is not.
2900         if ("0".equals(value)) {
2901             description = "get stuck";
2902         } else if (value == null) {
2903             description = "prompt";
2904         } else if ("1".equals(value)) {
2905             description = "avoid";
2906         } else {
2907             description = value + " (?)";
2908         }
2909         pw.println("User setting:      " + description);
2910         pw.println("Network overrides:");
2911         pw.increaseIndent();
2912         for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
2913             if (nai.avoidUnvalidated) {
2914                 pw.println(nai.name());
2915             }
2916         }
2917         pw.decreaseIndent();
2918         pw.decreaseIndent();
2919     }
2920 
showValidationNotification(NetworkAgentInfo nai, NotificationType type)2921     private void showValidationNotification(NetworkAgentInfo nai, NotificationType type) {
2922         final String action;
2923         switch (type) {
2924             case NO_INTERNET:
2925                 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED;
2926                 break;
2927             case LOST_INTERNET:
2928                 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION;
2929                 break;
2930             default:
2931                 Slog.wtf(TAG, "Unknown notification type " + type);
2932                 return;
2933         }
2934 
2935         Intent intent = new Intent(action);
2936         intent.setData(Uri.fromParts("netId", Integer.toString(nai.network.netId), null));
2937         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2938         intent.setClassName("com.android.settings",
2939                 "com.android.settings.wifi.WifiNoInternetDialog");
2940 
2941         PendingIntent pendingIntent = PendingIntent.getActivityAsUser(
2942                 mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
2943         mNotifier.showNotification(nai.network.netId, type, nai, null, pendingIntent, true);
2944     }
2945 
handlePromptUnvalidated(Network network)2946     private void handlePromptUnvalidated(Network network) {
2947         if (VDBG) log("handlePromptUnvalidated " + network);
2948         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
2949 
2950         // Only prompt if the network is unvalidated and was explicitly selected by the user, and if
2951         // we haven't already been told to switch to it regardless of whether it validated or not.
2952         // Also don't prompt on captive portals because we're already prompting the user to sign in.
2953         if (nai == null || nai.everValidated || nai.everCaptivePortalDetected ||
2954                 !nai.networkMisc.explicitlySelected || nai.networkMisc.acceptUnvalidated) {
2955             return;
2956         }
2957         showValidationNotification(nai, NotificationType.NO_INTERNET);
2958     }
2959 
handleNetworkUnvalidated(NetworkAgentInfo nai)2960     private void handleNetworkUnvalidated(NetworkAgentInfo nai) {
2961         NetworkCapabilities nc = nai.networkCapabilities;
2962         if (DBG) log("handleNetworkUnvalidated " + nai.name() + " cap=" + nc);
2963 
2964         if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) &&
2965             mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) {
2966             showValidationNotification(nai, NotificationType.LOST_INTERNET);
2967         }
2968     }
2969 
2970     @Override
getMultipathPreference(Network network)2971     public int getMultipathPreference(Network network) {
2972         enforceAccessPermission();
2973 
2974         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
2975         if (nai != null && nai.networkCapabilities
2976                 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
2977             return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
2978         }
2979 
2980         Integer networkPreference = mMultipathPolicyTracker.getMultipathPreference(network);
2981         if (networkPreference != null) {
2982             return networkPreference;
2983         }
2984 
2985         return mMultinetworkPolicyTracker.getMeteredMultipathPreference();
2986     }
2987 
2988     private class InternalHandler extends Handler {
InternalHandler(Looper looper)2989         public InternalHandler(Looper looper) {
2990             super(looper);
2991         }
2992 
2993         @Override
handleMessage(Message msg)2994         public void handleMessage(Message msg) {
2995             switch (msg.what) {
2996                 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK:
2997                 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: {
2998                     handleReleaseNetworkTransitionWakelock(msg.what);
2999                     break;
3000                 }
3001                 case EVENT_APPLY_GLOBAL_HTTP_PROXY: {
3002                     handleDeprecatedGlobalHttpProxy();
3003                     break;
3004                 }
3005                 case EVENT_PROXY_HAS_CHANGED: {
3006                     handleApplyDefaultProxy((ProxyInfo)msg.obj);
3007                     break;
3008                 }
3009                 case EVENT_REGISTER_NETWORK_FACTORY: {
3010                     handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj);
3011                     break;
3012                 }
3013                 case EVENT_UNREGISTER_NETWORK_FACTORY: {
3014                     handleUnregisterNetworkFactory((Messenger)msg.obj);
3015                     break;
3016                 }
3017                 case EVENT_REGISTER_NETWORK_AGENT: {
3018                     handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj);
3019                     break;
3020                 }
3021                 case EVENT_REGISTER_NETWORK_REQUEST:
3022                 case EVENT_REGISTER_NETWORK_LISTENER: {
3023                     handleRegisterNetworkRequest((NetworkRequestInfo) msg.obj);
3024                     break;
3025                 }
3026                 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT:
3027                 case EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT: {
3028                     handleRegisterNetworkRequestWithIntent(msg);
3029                     break;
3030                 }
3031                 case EVENT_TIMEOUT_NETWORK_REQUEST: {
3032                     NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj;
3033                     handleTimedOutNetworkRequest(nri);
3034                     break;
3035                 }
3036                 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: {
3037                     handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1);
3038                     break;
3039                 }
3040                 case EVENT_RELEASE_NETWORK_REQUEST: {
3041                     handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1);
3042                     break;
3043                 }
3044                 case EVENT_SET_ACCEPT_UNVALIDATED: {
3045                     Network network = (Network) msg.obj;
3046                     handleSetAcceptUnvalidated(network, toBool(msg.arg1), toBool(msg.arg2));
3047                     break;
3048                 }
3049                 case EVENT_SET_AVOID_UNVALIDATED: {
3050                     handleSetAvoidUnvalidated((Network) msg.obj);
3051                     break;
3052                 }
3053                 case EVENT_PROMPT_UNVALIDATED: {
3054                     handlePromptUnvalidated((Network) msg.obj);
3055                     break;
3056                 }
3057                 case EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON: {
3058                     handleMobileDataAlwaysOn();
3059                     break;
3060                 }
3061                 // Sent by KeepaliveTracker to process an app request on the state machine thread.
3062                 case NetworkAgent.CMD_START_PACKET_KEEPALIVE: {
3063                     mKeepaliveTracker.handleStartKeepalive(msg);
3064                     break;
3065                 }
3066                 // Sent by KeepaliveTracker to process an app request on the state machine thread.
3067                 case NetworkAgent.CMD_STOP_PACKET_KEEPALIVE: {
3068                     NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj);
3069                     int slot = msg.arg1;
3070                     int reason = msg.arg2;
3071                     mKeepaliveTracker.handleStopKeepalive(nai, slot, reason);
3072                     break;
3073                 }
3074                 case EVENT_SYSTEM_READY: {
3075                     for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
3076                         nai.networkMonitor.systemReady = true;
3077                     }
3078                     mMultipathPolicyTracker.start();
3079                     break;
3080                 }
3081                 case EVENT_REVALIDATE_NETWORK: {
3082                     handleReportNetworkConnectivity((Network) msg.obj, msg.arg1, toBool(msg.arg2));
3083                     break;
3084                 }
3085                 case EVENT_PRIVATE_DNS_SETTINGS_CHANGED:
3086                     handlePrivateDnsSettingsChanged();
3087                     break;
3088                 case EVENT_PRIVATE_DNS_VALIDATION_UPDATE:
3089                     handlePrivateDnsValidationUpdate(
3090                             (PrivateDnsValidationUpdate) msg.obj);
3091                     break;
3092             }
3093         }
3094     }
3095 
3096     // javadoc from interface
3097     @Override
tether(String iface, String callerPkg)3098     public int tether(String iface, String callerPkg) {
3099         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
3100         if (isTetheringSupported()) {
3101             final int status = mTethering.tether(iface);
3102             return status;
3103         } else {
3104             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
3105         }
3106     }
3107 
3108     // javadoc from interface
3109     @Override
untether(String iface, String callerPkg)3110     public int untether(String iface, String callerPkg) {
3111         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
3112 
3113         if (isTetheringSupported()) {
3114             final int status = mTethering.untether(iface);
3115             return status;
3116         } else {
3117             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
3118         }
3119     }
3120 
3121     // javadoc from interface
3122     @Override
getLastTetherError(String iface)3123     public int getLastTetherError(String iface) {
3124         enforceTetherAccessPermission();
3125 
3126         if (isTetheringSupported()) {
3127             return mTethering.getLastTetherError(iface);
3128         } else {
3129             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
3130         }
3131     }
3132 
3133     // TODO - proper iface API for selection by property, inspection, etc
3134     @Override
getTetherableUsbRegexs()3135     public String[] getTetherableUsbRegexs() {
3136         enforceTetherAccessPermission();
3137         if (isTetheringSupported()) {
3138             return mTethering.getTetherableUsbRegexs();
3139         } else {
3140             return new String[0];
3141         }
3142     }
3143 
3144     @Override
getTetherableWifiRegexs()3145     public String[] getTetherableWifiRegexs() {
3146         enforceTetherAccessPermission();
3147         if (isTetheringSupported()) {
3148             return mTethering.getTetherableWifiRegexs();
3149         } else {
3150             return new String[0];
3151         }
3152     }
3153 
3154     @Override
getTetherableBluetoothRegexs()3155     public String[] getTetherableBluetoothRegexs() {
3156         enforceTetherAccessPermission();
3157         if (isTetheringSupported()) {
3158             return mTethering.getTetherableBluetoothRegexs();
3159         } else {
3160             return new String[0];
3161         }
3162     }
3163 
3164     @Override
setUsbTethering(boolean enable, String callerPkg)3165     public int setUsbTethering(boolean enable, String callerPkg) {
3166         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
3167         if (isTetheringSupported()) {
3168             return mTethering.setUsbTethering(enable);
3169         } else {
3170             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
3171         }
3172     }
3173 
3174     // TODO - move iface listing, queries, etc to new module
3175     // javadoc from interface
3176     @Override
getTetherableIfaces()3177     public String[] getTetherableIfaces() {
3178         enforceTetherAccessPermission();
3179         return mTethering.getTetherableIfaces();
3180     }
3181 
3182     @Override
getTetheredIfaces()3183     public String[] getTetheredIfaces() {
3184         enforceTetherAccessPermission();
3185         return mTethering.getTetheredIfaces();
3186     }
3187 
3188     @Override
getTetheringErroredIfaces()3189     public String[] getTetheringErroredIfaces() {
3190         enforceTetherAccessPermission();
3191         return mTethering.getErroredIfaces();
3192     }
3193 
3194     @Override
getTetheredDhcpRanges()3195     public String[] getTetheredDhcpRanges() {
3196         enforceConnectivityInternalPermission();
3197         return mTethering.getTetheredDhcpRanges();
3198     }
3199 
3200     @Override
isTetheringSupported(String callerPkg)3201     public boolean isTetheringSupported(String callerPkg) {
3202         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
3203         return isTetheringSupported();
3204     }
3205 
3206     // if ro.tether.denied = true we default to no tethering
3207     // gservices could set the secure setting to 1 though to enable it on a build where it
3208     // had previously been turned off.
isTetheringSupported()3209     private boolean isTetheringSupported() {
3210         int defaultVal = encodeBool(!mSystemProperties.get("ro.tether.denied").equals("true"));
3211         boolean tetherSupported = toBool(Settings.Global.getInt(mContext.getContentResolver(),
3212                 Settings.Global.TETHER_SUPPORTED, defaultVal));
3213         boolean tetherEnabledInSettings = tetherSupported
3214                 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
3215 
3216         // Elevate to system UID to avoid caller requiring MANAGE_USERS permission.
3217         boolean adminUser = false;
3218         final long token = Binder.clearCallingIdentity();
3219         try {
3220             adminUser = mUserManager.isAdminUser();
3221         } finally {
3222             Binder.restoreCallingIdentity(token);
3223         }
3224 
3225         return tetherEnabledInSettings && adminUser && mTethering.hasTetherableConfiguration();
3226     }
3227 
3228     @Override
startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi, String callerPkg)3229     public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi,
3230             String callerPkg) {
3231         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
3232         if (!isTetheringSupported()) {
3233             receiver.send(ConnectivityManager.TETHER_ERROR_UNSUPPORTED, null);
3234             return;
3235         }
3236         mTethering.startTethering(type, receiver, showProvisioningUi);
3237     }
3238 
3239     @Override
stopTethering(int type, String callerPkg)3240     public void stopTethering(int type, String callerPkg) {
3241         ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
3242         mTethering.stopTethering(type);
3243     }
3244 
3245     // Called when we lose the default network and have no replacement yet.
3246     // This will automatically be cleared after X seconds or a new default network
3247     // becomes CONNECTED, whichever happens first.  The timer is started by the
3248     // first caller and not restarted by subsequent callers.
ensureNetworkTransitionWakelock(String forWhom)3249     private void ensureNetworkTransitionWakelock(String forWhom) {
3250         synchronized (this) {
3251             if (mNetTransitionWakeLock.isHeld()) {
3252                 return;
3253             }
3254             mNetTransitionWakeLock.acquire();
3255             mLastWakeLockAcquireTimestamp = SystemClock.elapsedRealtime();
3256             mTotalWakelockAcquisitions++;
3257         }
3258         mWakelockLogs.log("ACQUIRE for " + forWhom);
3259         Message msg = mHandler.obtainMessage(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
3260         mHandler.sendMessageDelayed(msg, mNetTransitionWakeLockTimeout);
3261     }
3262 
3263     // Called when we gain a new default network to release the network transition wakelock in a
3264     // second, to allow a grace period for apps to reconnect over the new network. Pending expiry
3265     // message is cancelled.
scheduleReleaseNetworkTransitionWakelock()3266     private void scheduleReleaseNetworkTransitionWakelock() {
3267         synchronized (this) {
3268             if (!mNetTransitionWakeLock.isHeld()) {
3269                 return; // expiry message released the lock first.
3270             }
3271         }
3272         // Cancel self timeout on wakelock hold.
3273         mHandler.removeMessages(EVENT_EXPIRE_NET_TRANSITION_WAKELOCK);
3274         Message msg = mHandler.obtainMessage(EVENT_CLEAR_NET_TRANSITION_WAKELOCK);
3275         mHandler.sendMessageDelayed(msg, 1000);
3276     }
3277 
3278     // Called when either message of ensureNetworkTransitionWakelock or
3279     // scheduleReleaseNetworkTransitionWakelock is processed.
handleReleaseNetworkTransitionWakelock(int eventId)3280     private void handleReleaseNetworkTransitionWakelock(int eventId) {
3281         String event = eventName(eventId);
3282         synchronized (this) {
3283             if (!mNetTransitionWakeLock.isHeld()) {
3284                 mWakelockLogs.log(String.format("RELEASE: already released (%s)", event));
3285                 Slog.w(TAG, "expected Net Transition WakeLock to be held");
3286                 return;
3287             }
3288             mNetTransitionWakeLock.release();
3289             long lockDuration = SystemClock.elapsedRealtime() - mLastWakeLockAcquireTimestamp;
3290             mTotalWakelockDurationMs += lockDuration;
3291             mMaxWakelockDurationMs = Math.max(mMaxWakelockDurationMs, lockDuration);
3292             mTotalWakelockReleases++;
3293         }
3294         mWakelockLogs.log(String.format("RELEASE (%s)", event));
3295     }
3296 
3297     // 100 percent is full good, 0 is full bad.
3298     @Override
reportInetCondition(int networkType, int percentage)3299     public void reportInetCondition(int networkType, int percentage) {
3300         NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
3301         if (nai == null) return;
3302         reportNetworkConnectivity(nai.network, percentage > 50);
3303     }
3304 
3305     @Override
reportNetworkConnectivity(Network network, boolean hasConnectivity)3306     public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
3307         enforceAccessPermission();
3308         enforceInternetPermission();
3309         final int uid = Binder.getCallingUid();
3310         final int connectivityInfo = encodeBool(hasConnectivity);
3311         mHandler.sendMessage(
3312                 mHandler.obtainMessage(EVENT_REVALIDATE_NETWORK, uid, connectivityInfo, network));
3313     }
3314 
handleReportNetworkConnectivity( Network network, int uid, boolean hasConnectivity)3315     private void handleReportNetworkConnectivity(
3316             Network network, int uid, boolean hasConnectivity) {
3317         final NetworkAgentInfo nai;
3318         if (network == null) {
3319             nai = getDefaultNetwork();
3320         } else {
3321             nai = getNetworkAgentInfoForNetwork(network);
3322         }
3323         if (nai == null || nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTING ||
3324             nai.networkInfo.getState() == NetworkInfo.State.DISCONNECTED) {
3325             return;
3326         }
3327         // Revalidate if the app report does not match our current validated state.
3328         if (hasConnectivity == nai.lastValidated) {
3329             return;
3330         }
3331         if (DBG) {
3332             int netid = nai.network.netId;
3333             log("reportNetworkConnectivity(" + netid + ", " + hasConnectivity + ") by " + uid);
3334         }
3335         // Validating a network that has not yet connected could result in a call to
3336         // rematchNetworkAndRequests() which is not meant to work on such networks.
3337         if (!nai.everConnected) {
3338             return;
3339         }
3340         LinkProperties lp = getLinkProperties(nai);
3341         if (isNetworkWithLinkPropertiesBlocked(lp, uid, false)) {
3342             return;
3343         }
3344         nai.networkMonitor.forceReevaluation(uid);
3345     }
3346 
getDefaultProxy()3347     private ProxyInfo getDefaultProxy() {
3348         // this information is already available as a world read/writable jvm property
3349         // so this API change wouldn't have a benifit.  It also breaks the passing
3350         // of proxy info to all the JVMs.
3351         // enforceAccessPermission();
3352         synchronized (mProxyLock) {
3353             ProxyInfo ret = mGlobalProxy;
3354             if ((ret == null) && !mDefaultProxyDisabled) ret = mDefaultProxy;
3355             return ret;
3356         }
3357     }
3358 
3359     @Override
getProxyForNetwork(Network network)3360     public ProxyInfo getProxyForNetwork(Network network) {
3361         if (network == null) return getDefaultProxy();
3362         final ProxyInfo globalProxy = getGlobalProxy();
3363         if (globalProxy != null) return globalProxy;
3364         if (!NetworkUtils.queryUserAccess(Binder.getCallingUid(), network.netId)) return null;
3365         // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which
3366         // caller may not have.
3367         final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
3368         if (nai == null) return null;
3369         synchronized (nai) {
3370             final ProxyInfo proxyInfo = nai.linkProperties.getHttpProxy();
3371             if (proxyInfo == null) return null;
3372             return new ProxyInfo(proxyInfo);
3373         }
3374     }
3375 
3376     // Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present
3377     // (e.g. if mGlobalProxy==null fall back to network-specific proxy, if network-specific
3378     // proxy is null then there is no proxy in place).
canonicalizeProxyInfo(ProxyInfo proxy)3379     private ProxyInfo canonicalizeProxyInfo(ProxyInfo proxy) {
3380         if (proxy != null && TextUtils.isEmpty(proxy.getHost())
3381                 && (proxy.getPacFileUrl() == null || Uri.EMPTY.equals(proxy.getPacFileUrl()))) {
3382             proxy = null;
3383         }
3384         return proxy;
3385     }
3386 
3387     // ProxyInfo equality function with a couple modifications over ProxyInfo.equals() to make it
3388     // better for determining if a new proxy broadcast is necessary:
3389     // 1. Canonicalize empty ProxyInfos to null so an empty proxy compares equal to null so as to
3390     //    avoid unnecessary broadcasts.
3391     // 2. Make sure all parts of the ProxyInfo's compare true, including the host when a PAC URL
3392     //    is in place.  This is important so legacy PAC resolver (see com.android.proxyhandler)
3393     //    changes aren't missed.  The legacy PAC resolver pretends to be a simple HTTP proxy but
3394     //    actually uses the PAC to resolve; this results in ProxyInfo's with PAC URL, host and port
3395     //    all set.
proxyInfoEqual(ProxyInfo a, ProxyInfo b)3396     private boolean proxyInfoEqual(ProxyInfo a, ProxyInfo b) {
3397         a = canonicalizeProxyInfo(a);
3398         b = canonicalizeProxyInfo(b);
3399         // ProxyInfo.equals() doesn't check hosts when PAC URLs are present, but we need to check
3400         // hosts even when PAC URLs are present to account for the legacy PAC resolver.
3401         return Objects.equals(a, b) && (a == null || Objects.equals(a.getHost(), b.getHost()));
3402     }
3403 
setGlobalProxy(ProxyInfo proxyProperties)3404     public void setGlobalProxy(ProxyInfo proxyProperties) {
3405         enforceConnectivityInternalPermission();
3406 
3407         synchronized (mProxyLock) {
3408             if (proxyProperties == mGlobalProxy) return;
3409             if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return;
3410             if (mGlobalProxy != null && mGlobalProxy.equals(proxyProperties)) return;
3411 
3412             String host = "";
3413             int port = 0;
3414             String exclList = "";
3415             String pacFileUrl = "";
3416             if (proxyProperties != null && (!TextUtils.isEmpty(proxyProperties.getHost()) ||
3417                     !Uri.EMPTY.equals(proxyProperties.getPacFileUrl()))) {
3418                 if (!proxyProperties.isValid()) {
3419                     if (DBG)
3420                         log("Invalid proxy properties, ignoring: " + proxyProperties.toString());
3421                     return;
3422                 }
3423                 mGlobalProxy = new ProxyInfo(proxyProperties);
3424                 host = mGlobalProxy.getHost();
3425                 port = mGlobalProxy.getPort();
3426                 exclList = mGlobalProxy.getExclusionListAsString();
3427                 if (!Uri.EMPTY.equals(proxyProperties.getPacFileUrl())) {
3428                     pacFileUrl = proxyProperties.getPacFileUrl().toString();
3429                 }
3430             } else {
3431                 mGlobalProxy = null;
3432             }
3433             ContentResolver res = mContext.getContentResolver();
3434             final long token = Binder.clearCallingIdentity();
3435             try {
3436                 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, host);
3437                 Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, port);
3438                 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
3439                         exclList);
3440                 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
3441             } finally {
3442                 Binder.restoreCallingIdentity(token);
3443             }
3444 
3445             if (mGlobalProxy == null) {
3446                 proxyProperties = mDefaultProxy;
3447             }
3448             sendProxyBroadcast(proxyProperties);
3449         }
3450     }
3451 
loadGlobalProxy()3452     private void loadGlobalProxy() {
3453         ContentResolver res = mContext.getContentResolver();
3454         String host = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST);
3455         int port = Settings.Global.getInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, 0);
3456         String exclList = Settings.Global.getString(res,
3457                 Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
3458         String pacFileUrl = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC);
3459         if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) {
3460             ProxyInfo proxyProperties;
3461             if (!TextUtils.isEmpty(pacFileUrl)) {
3462                 proxyProperties = new ProxyInfo(pacFileUrl);
3463             } else {
3464                 proxyProperties = new ProxyInfo(host, port, exclList);
3465             }
3466             if (!proxyProperties.isValid()) {
3467                 if (DBG) log("Invalid proxy properties, ignoring: " + proxyProperties.toString());
3468                 return;
3469             }
3470 
3471             synchronized (mProxyLock) {
3472                 mGlobalProxy = proxyProperties;
3473             }
3474         }
3475     }
3476 
getGlobalProxy()3477     public ProxyInfo getGlobalProxy() {
3478         // this information is already available as a world read/writable jvm property
3479         // so this API change wouldn't have a benifit.  It also breaks the passing
3480         // of proxy info to all the JVMs.
3481         // enforceAccessPermission();
3482         synchronized (mProxyLock) {
3483             return mGlobalProxy;
3484         }
3485     }
3486 
handleApplyDefaultProxy(ProxyInfo proxy)3487     private void handleApplyDefaultProxy(ProxyInfo proxy) {
3488         if (proxy != null && TextUtils.isEmpty(proxy.getHost())
3489                 && Uri.EMPTY.equals(proxy.getPacFileUrl())) {
3490             proxy = null;
3491         }
3492         synchronized (mProxyLock) {
3493             if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return;
3494             if (mDefaultProxy == proxy) return; // catches repeated nulls
3495             if (proxy != null &&  !proxy.isValid()) {
3496                 if (DBG) log("Invalid proxy properties, ignoring: " + proxy.toString());
3497                 return;
3498             }
3499 
3500             // This call could be coming from the PacManager, containing the port of the local
3501             // proxy.  If this new proxy matches the global proxy then copy this proxy to the
3502             // global (to get the correct local port), and send a broadcast.
3503             // TODO: Switch PacManager to have its own message to send back rather than
3504             // reusing EVENT_HAS_CHANGED_PROXY and this call to handleApplyDefaultProxy.
3505             if ((mGlobalProxy != null) && (proxy != null)
3506                     && (!Uri.EMPTY.equals(proxy.getPacFileUrl()))
3507                     && proxy.getPacFileUrl().equals(mGlobalProxy.getPacFileUrl())) {
3508                 mGlobalProxy = proxy;
3509                 sendProxyBroadcast(mGlobalProxy);
3510                 return;
3511             }
3512             mDefaultProxy = proxy;
3513 
3514             if (mGlobalProxy != null) return;
3515             if (!mDefaultProxyDisabled) {
3516                 sendProxyBroadcast(proxy);
3517             }
3518         }
3519     }
3520 
3521     // If the proxy has changed from oldLp to newLp, resend proxy broadcast with default proxy.
3522     // This method gets called when any network changes proxy, but the broadcast only ever contains
3523     // the default proxy (even if it hasn't changed).
3524     // TODO: Deprecate the broadcast extras as they aren't necessarily applicable in a multi-network
3525     // world where an app might be bound to a non-default network.
updateProxy(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai)3526     private void updateProxy(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai) {
3527         ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy();
3528         ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
3529 
3530         if (!proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
3531             sendProxyBroadcast(getDefaultProxy());
3532         }
3533     }
3534 
handleDeprecatedGlobalHttpProxy()3535     private void handleDeprecatedGlobalHttpProxy() {
3536         String proxy = Settings.Global.getString(mContext.getContentResolver(),
3537                 Settings.Global.HTTP_PROXY);
3538         if (!TextUtils.isEmpty(proxy)) {
3539             String data[] = proxy.split(":");
3540             if (data.length == 0) {
3541                 return;
3542             }
3543 
3544             String proxyHost =  data[0];
3545             int proxyPort = 8080;
3546             if (data.length > 1) {
3547                 try {
3548                     proxyPort = Integer.parseInt(data[1]);
3549                 } catch (NumberFormatException e) {
3550                     return;
3551                 }
3552             }
3553             ProxyInfo p = new ProxyInfo(data[0], proxyPort, "");
3554             setGlobalProxy(p);
3555         }
3556     }
3557 
sendProxyBroadcast(ProxyInfo proxy)3558     private void sendProxyBroadcast(ProxyInfo proxy) {
3559         if (proxy == null) proxy = new ProxyInfo("", 0, "");
3560         if (mPacManager.setCurrentProxyScriptUrl(proxy)) return;
3561         if (DBG) log("sending Proxy Broadcast for " + proxy);
3562         Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
3563         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
3564             Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
3565         intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy);
3566         final long ident = Binder.clearCallingIdentity();
3567         try {
3568             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
3569         } finally {
3570             Binder.restoreCallingIdentity(ident);
3571         }
3572     }
3573 
3574     private static class SettingsObserver extends ContentObserver {
3575         final private HashMap<Uri, Integer> mUriEventMap;
3576         final private Context mContext;
3577         final private Handler mHandler;
3578 
SettingsObserver(Context context, Handler handler)3579         SettingsObserver(Context context, Handler handler) {
3580             super(null);
3581             mUriEventMap = new HashMap<Uri, Integer>();
3582             mContext = context;
3583             mHandler = handler;
3584         }
3585 
observe(Uri uri, int what)3586         void observe(Uri uri, int what) {
3587             mUriEventMap.put(uri, what);
3588             final ContentResolver resolver = mContext.getContentResolver();
3589             resolver.registerContentObserver(uri, false, this);
3590         }
3591 
3592         @Override
onChange(boolean selfChange)3593         public void onChange(boolean selfChange) {
3594             Slog.wtf(TAG, "Should never be reached.");
3595         }
3596 
3597         @Override
onChange(boolean selfChange, Uri uri)3598         public void onChange(boolean selfChange, Uri uri) {
3599             final Integer what = mUriEventMap.get(uri);
3600             if (what != null) {
3601                 mHandler.obtainMessage(what.intValue()).sendToTarget();
3602             } else {
3603                 loge("No matching event to send for URI=" + uri);
3604             }
3605         }
3606     }
3607 
log(String s)3608     private static void log(String s) {
3609         Slog.d(TAG, s);
3610     }
3611 
loge(String s)3612     private static void loge(String s) {
3613         Slog.e(TAG, s);
3614     }
3615 
loge(String s, Throwable t)3616     private static void loge(String s, Throwable t) {
3617         Slog.e(TAG, s, t);
3618     }
3619 
3620     /**
3621      * Prepare for a VPN application.
3622      * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId},
3623      * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
3624      *
3625      * @param oldPackage Package name of the application which currently controls VPN, which will
3626      *                   be replaced. If there is no such application, this should should either be
3627      *                   {@code null} or {@link VpnConfig.LEGACY_VPN}.
3628      * @param newPackage Package name of the application which should gain control of VPN, or
3629      *                   {@code null} to disable.
3630      * @param userId User for whom to prepare the new VPN.
3631      *
3632      * @hide
3633      */
3634     @Override
prepareVpn(@ullable String oldPackage, @Nullable String newPackage, int userId)3635     public boolean prepareVpn(@Nullable String oldPackage, @Nullable String newPackage,
3636             int userId) {
3637         enforceCrossUserPermission(userId);
3638 
3639         synchronized (mVpns) {
3640             throwIfLockdownEnabled();
3641             Vpn vpn = mVpns.get(userId);
3642             if (vpn != null) {
3643                 return vpn.prepare(oldPackage, newPackage);
3644             } else {
3645                 return false;
3646             }
3647         }
3648     }
3649 
3650     /**
3651      * Set whether the VPN package has the ability to launch VPNs without user intervention.
3652      * This method is used by system-privileged apps.
3653      * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId},
3654      * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
3655      *
3656      * @param packageName The package for which authorization state should change.
3657      * @param userId User for whom {@code packageName} is installed.
3658      * @param authorized {@code true} if this app should be able to start a VPN connection without
3659      *                   explicit user approval, {@code false} if not.
3660      *
3661      * @hide
3662      */
3663     @Override
setVpnPackageAuthorization(String packageName, int userId, boolean authorized)3664     public void setVpnPackageAuthorization(String packageName, int userId, boolean authorized) {
3665         enforceCrossUserPermission(userId);
3666 
3667         synchronized (mVpns) {
3668             Vpn vpn = mVpns.get(userId);
3669             if (vpn != null) {
3670                 vpn.setPackageAuthorization(packageName, authorized);
3671             }
3672         }
3673     }
3674 
3675     /**
3676      * Configure a TUN interface and return its file descriptor. Parameters
3677      * are encoded and opaque to this class. This method is used by VpnBuilder
3678      * and not available in ConnectivityManager. Permissions are checked in
3679      * Vpn class.
3680      * @hide
3681      */
3682     @Override
establishVpn(VpnConfig config)3683     public ParcelFileDescriptor establishVpn(VpnConfig config) {
3684         int user = UserHandle.getUserId(Binder.getCallingUid());
3685         synchronized (mVpns) {
3686             throwIfLockdownEnabled();
3687             return mVpns.get(user).establish(config);
3688         }
3689     }
3690 
3691     /**
3692      * Start legacy VPN, controlling native daemons as needed. Creates a
3693      * secondary thread to perform connection work, returning quickly.
3694      */
3695     @Override
startLegacyVpn(VpnProfile profile)3696     public void startLegacyVpn(VpnProfile profile) {
3697         int user = UserHandle.getUserId(Binder.getCallingUid());
3698         final LinkProperties egress = getActiveLinkProperties();
3699         if (egress == null) {
3700             throw new IllegalStateException("Missing active network connection");
3701         }
3702         synchronized (mVpns) {
3703             throwIfLockdownEnabled();
3704             mVpns.get(user).startLegacyVpn(profile, mKeyStore, egress);
3705         }
3706     }
3707 
3708     /**
3709      * Return the information of the ongoing legacy VPN. This method is used
3710      * by VpnSettings and not available in ConnectivityManager. Permissions
3711      * are checked in Vpn class.
3712      */
3713     @Override
getLegacyVpnInfo(int userId)3714     public LegacyVpnInfo getLegacyVpnInfo(int userId) {
3715         enforceCrossUserPermission(userId);
3716 
3717         synchronized (mVpns) {
3718             return mVpns.get(userId).getLegacyVpnInfo();
3719         }
3720     }
3721 
3722     /**
3723      * Return the information of all ongoing VPNs. This method is used by NetworkStatsService
3724      * and not available in ConnectivityManager.
3725      */
3726     @Override
getAllVpnInfo()3727     public VpnInfo[] getAllVpnInfo() {
3728         enforceConnectivityInternalPermission();
3729         synchronized (mVpns) {
3730             if (mLockdownEnabled) {
3731                 return new VpnInfo[0];
3732             }
3733 
3734             List<VpnInfo> infoList = new ArrayList<>();
3735             for (int i = 0; i < mVpns.size(); i++) {
3736                 VpnInfo info = createVpnInfo(mVpns.valueAt(i));
3737                 if (info != null) {
3738                     infoList.add(info);
3739                 }
3740             }
3741             return infoList.toArray(new VpnInfo[infoList.size()]);
3742         }
3743     }
3744 
3745     /**
3746      * @return VPN information for accounting, or null if we can't retrieve all required
3747      *         information, e.g primary underlying iface.
3748      */
3749     @Nullable
createVpnInfo(Vpn vpn)3750     private VpnInfo createVpnInfo(Vpn vpn) {
3751         VpnInfo info = vpn.getVpnInfo();
3752         if (info == null) {
3753             return null;
3754         }
3755         Network[] underlyingNetworks = vpn.getUnderlyingNetworks();
3756         // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret
3757         // the underlyingNetworks list.
3758         if (underlyingNetworks == null) {
3759             NetworkAgentInfo defaultNetwork = getDefaultNetwork();
3760             if (defaultNetwork != null && defaultNetwork.linkProperties != null) {
3761                 info.primaryUnderlyingIface = getDefaultNetwork().linkProperties.getInterfaceName();
3762             }
3763         } else if (underlyingNetworks.length > 0) {
3764             LinkProperties linkProperties = getLinkProperties(underlyingNetworks[0]);
3765             if (linkProperties != null) {
3766                 info.primaryUnderlyingIface = linkProperties.getInterfaceName();
3767             }
3768         }
3769         return info.primaryUnderlyingIface == null ? null : info;
3770     }
3771 
3772     /**
3773      * Returns the information of the ongoing VPN for {@code userId}. This method is used by
3774      * VpnDialogs and not available in ConnectivityManager.
3775      * Permissions are checked in Vpn class.
3776      * @hide
3777      */
3778     @Override
getVpnConfig(int userId)3779     public VpnConfig getVpnConfig(int userId) {
3780         enforceCrossUserPermission(userId);
3781         synchronized (mVpns) {
3782             Vpn vpn = mVpns.get(userId);
3783             if (vpn != null) {
3784                 return vpn.getVpnConfig();
3785             } else {
3786                 return null;
3787             }
3788         }
3789     }
3790 
3791     /**
3792      * Ask all VPN objects to recompute and update their capabilities.
3793      *
3794      * When underlying networks change, VPNs may have to update capabilities to reflect things
3795      * like the metered bit, their transports, and so on. This asks the VPN objects to update
3796      * their capabilities, and as this will cause them to send messages to the ConnectivityService
3797      * handler thread through their agent, this is asynchronous. When the capabilities objects
3798      * are computed they will be up-to-date as they are computed synchronously from here and
3799      * this is running on the ConnectivityService thread.
3800      * TODO : Fix this and call updateCapabilities inline to remove out-of-order events.
3801      */
updateAllVpnsCapabilities()3802     private void updateAllVpnsCapabilities() {
3803         synchronized (mVpns) {
3804             for (int i = 0; i < mVpns.size(); i++) {
3805                 final Vpn vpn = mVpns.valueAt(i);
3806                 vpn.updateCapabilities();
3807             }
3808         }
3809     }
3810 
3811     @Override
updateLockdownVpn()3812     public boolean updateLockdownVpn() {
3813         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
3814             Slog.w(TAG, "Lockdown VPN only available to AID_SYSTEM");
3815             return false;
3816         }
3817 
3818         synchronized (mVpns) {
3819             // Tear down existing lockdown if profile was removed
3820             mLockdownEnabled = LockdownVpnTracker.isEnabled();
3821             if (mLockdownEnabled) {
3822                 byte[] profileTag = mKeyStore.get(Credentials.LOCKDOWN_VPN);
3823                 if (profileTag == null) {
3824                     Slog.e(TAG, "Lockdown VPN configured but cannot be read from keystore");
3825                     return false;
3826                 }
3827                 String profileName = new String(profileTag);
3828                 final VpnProfile profile = VpnProfile.decode(
3829                         profileName, mKeyStore.get(Credentials.VPN + profileName));
3830                 if (profile == null) {
3831                     Slog.e(TAG, "Lockdown VPN configured invalid profile " + profileName);
3832                     setLockdownTracker(null);
3833                     return true;
3834                 }
3835                 int user = UserHandle.getUserId(Binder.getCallingUid());
3836                 Vpn vpn = mVpns.get(user);
3837                 if (vpn == null) {
3838                     Slog.w(TAG, "VPN for user " + user + " not ready yet. Skipping lockdown");
3839                     return false;
3840                 }
3841                 setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, vpn, profile));
3842             } else {
3843                 setLockdownTracker(null);
3844             }
3845         }
3846 
3847         return true;
3848     }
3849 
3850     /**
3851      * Internally set new {@link LockdownVpnTracker}, shutting down any existing
3852      * {@link LockdownVpnTracker}. Can be {@code null} to disable lockdown.
3853      */
3854     @GuardedBy("mVpns")
setLockdownTracker(LockdownVpnTracker tracker)3855     private void setLockdownTracker(LockdownVpnTracker tracker) {
3856         // Shutdown any existing tracker
3857         final LockdownVpnTracker existing = mLockdownTracker;
3858         mLockdownTracker = null;
3859         if (existing != null) {
3860             existing.shutdown();
3861         }
3862 
3863         if (tracker != null) {
3864             mLockdownTracker = tracker;
3865             mLockdownTracker.init();
3866         }
3867     }
3868 
3869     @GuardedBy("mVpns")
throwIfLockdownEnabled()3870     private void throwIfLockdownEnabled() {
3871         if (mLockdownEnabled) {
3872             throw new IllegalStateException("Unavailable in lockdown mode");
3873         }
3874     }
3875 
3876     /**
3877      * Starts the always-on VPN {@link VpnService} for user {@param userId}, which should perform
3878      * some setup and then call {@code establish()} to connect.
3879      *
3880      * @return {@code true} if the service was started, the service was already connected, or there
3881      *         was no always-on VPN to start. {@code false} otherwise.
3882      */
startAlwaysOnVpn(int userId)3883     private boolean startAlwaysOnVpn(int userId) {
3884         synchronized (mVpns) {
3885             Vpn vpn = mVpns.get(userId);
3886             if (vpn == null) {
3887                 // Shouldn't happen as all codepaths that point here should have checked the Vpn
3888                 // exists already.
3889                 Slog.wtf(TAG, "User " + userId + " has no Vpn configuration");
3890                 return false;
3891             }
3892 
3893             return vpn.startAlwaysOnVpn();
3894         }
3895     }
3896 
3897     @Override
isAlwaysOnVpnPackageSupported(int userId, String packageName)3898     public boolean isAlwaysOnVpnPackageSupported(int userId, String packageName) {
3899         enforceSettingsPermission();
3900         enforceCrossUserPermission(userId);
3901 
3902         synchronized (mVpns) {
3903             Vpn vpn = mVpns.get(userId);
3904             if (vpn == null) {
3905                 Slog.w(TAG, "User " + userId + " has no Vpn configuration");
3906                 return false;
3907             }
3908             return vpn.isAlwaysOnPackageSupported(packageName);
3909         }
3910     }
3911 
3912     @Override
setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdown)3913     public boolean setAlwaysOnVpnPackage(int userId, String packageName, boolean lockdown) {
3914         enforceConnectivityInternalPermission();
3915         enforceCrossUserPermission(userId);
3916 
3917         synchronized (mVpns) {
3918             // Can't set always-on VPN if legacy VPN is already in lockdown mode.
3919             if (LockdownVpnTracker.isEnabled()) {
3920                 return false;
3921             }
3922 
3923             Vpn vpn = mVpns.get(userId);
3924             if (vpn == null) {
3925                 Slog.w(TAG, "User " + userId + " has no Vpn configuration");
3926                 return false;
3927             }
3928             if (!vpn.setAlwaysOnPackage(packageName, lockdown)) {
3929                 return false;
3930             }
3931             if (!startAlwaysOnVpn(userId)) {
3932                 vpn.setAlwaysOnPackage(null, false);
3933                 return false;
3934             }
3935         }
3936         return true;
3937     }
3938 
3939     @Override
getAlwaysOnVpnPackage(int userId)3940     public String getAlwaysOnVpnPackage(int userId) {
3941         enforceConnectivityInternalPermission();
3942         enforceCrossUserPermission(userId);
3943 
3944         synchronized (mVpns) {
3945             Vpn vpn = mVpns.get(userId);
3946             if (vpn == null) {
3947                 Slog.w(TAG, "User " + userId + " has no Vpn configuration");
3948                 return null;
3949             }
3950             return vpn.getAlwaysOnPackage();
3951         }
3952     }
3953 
3954     @Override
checkMobileProvisioning(int suggestedTimeOutMs)3955     public int checkMobileProvisioning(int suggestedTimeOutMs) {
3956         // TODO: Remove?  Any reason to trigger a provisioning check?
3957         return -1;
3958     }
3959 
3960     /** Location to an updatable file listing carrier provisioning urls.
3961      *  An example:
3962      *
3963      * <?xml version="1.0" encoding="utf-8"?>
3964      *  <provisioningUrls>
3965      *   <provisioningUrl mcc="310" mnc="4">http://myserver.com/foo?mdn=%3$s&amp;iccid=%1$s&amp;imei=%2$s</provisioningUrl>
3966      *  </provisioningUrls>
3967      */
3968     private static final String PROVISIONING_URL_PATH =
3969             "/data/misc/radio/provisioning_urls.xml";
3970     private final File mProvisioningUrlFile = new File(PROVISIONING_URL_PATH);
3971 
3972     /** XML tag for root element. */
3973     private static final String TAG_PROVISIONING_URLS = "provisioningUrls";
3974     /** XML tag for individual url */
3975     private static final String TAG_PROVISIONING_URL = "provisioningUrl";
3976     /** XML attribute for mcc */
3977     private static final String ATTR_MCC = "mcc";
3978     /** XML attribute for mnc */
3979     private static final String ATTR_MNC = "mnc";
3980 
getProvisioningUrlBaseFromFile()3981     private String getProvisioningUrlBaseFromFile() {
3982         FileReader fileReader = null;
3983         XmlPullParser parser = null;
3984         Configuration config = mContext.getResources().getConfiguration();
3985 
3986         try {
3987             fileReader = new FileReader(mProvisioningUrlFile);
3988             parser = Xml.newPullParser();
3989             parser.setInput(fileReader);
3990             XmlUtils.beginDocument(parser, TAG_PROVISIONING_URLS);
3991 
3992             while (true) {
3993                 XmlUtils.nextElement(parser);
3994 
3995                 String element = parser.getName();
3996                 if (element == null) break;
3997 
3998                 if (element.equals(TAG_PROVISIONING_URL)) {
3999                     String mcc = parser.getAttributeValue(null, ATTR_MCC);
4000                     try {
4001                         if (mcc != null && Integer.parseInt(mcc) == config.mcc) {
4002                             String mnc = parser.getAttributeValue(null, ATTR_MNC);
4003                             if (mnc != null && Integer.parseInt(mnc) == config.mnc) {
4004                                 parser.next();
4005                                 if (parser.getEventType() == XmlPullParser.TEXT) {
4006                                     return parser.getText();
4007                                 }
4008                             }
4009                         }
4010                     } catch (NumberFormatException e) {
4011                         loge("NumberFormatException in getProvisioningUrlBaseFromFile: " + e);
4012                     }
4013                 }
4014             }
4015             return null;
4016         } catch (FileNotFoundException e) {
4017             loge("Carrier Provisioning Urls file not found");
4018         } catch (XmlPullParserException e) {
4019             loge("Xml parser exception reading Carrier Provisioning Urls file: " + e);
4020         } catch (IOException e) {
4021             loge("I/O exception reading Carrier Provisioning Urls file: " + e);
4022         } finally {
4023             if (fileReader != null) {
4024                 try {
4025                     fileReader.close();
4026                 } catch (IOException e) {}
4027             }
4028         }
4029         return null;
4030     }
4031 
4032     @Override
getMobileProvisioningUrl()4033     public String getMobileProvisioningUrl() {
4034         enforceConnectivityInternalPermission();
4035         String url = getProvisioningUrlBaseFromFile();
4036         if (TextUtils.isEmpty(url)) {
4037             url = mContext.getResources().getString(R.string.mobile_provisioning_url);
4038             log("getMobileProvisioningUrl: mobile_provisioining_url from resource =" + url);
4039         } else {
4040             log("getMobileProvisioningUrl: mobile_provisioning_url from File =" + url);
4041         }
4042         // populate the iccid, imei and phone number in the provisioning url.
4043         if (!TextUtils.isEmpty(url)) {
4044             String phoneNumber = mTelephonyManager.getLine1Number();
4045             if (TextUtils.isEmpty(phoneNumber)) {
4046                 phoneNumber = "0000000000";
4047             }
4048             url = String.format(url,
4049                     mTelephonyManager.getSimSerialNumber() /* ICCID */,
4050                     mTelephonyManager.getDeviceId() /* IMEI */,
4051                     phoneNumber /* Phone numer */);
4052         }
4053 
4054         return url;
4055     }
4056 
4057     @Override
setProvisioningNotificationVisible(boolean visible, int networkType, String action)4058     public void setProvisioningNotificationVisible(boolean visible, int networkType,
4059             String action) {
4060         enforceConnectivityInternalPermission();
4061         if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
4062             return;
4063         }
4064         final long ident = Binder.clearCallingIdentity();
4065         try {
4066             // Concatenate the range of types onto the range of NetIDs.
4067             int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE);
4068             mNotifier.setProvNotificationVisible(visible, id, action);
4069         } finally {
4070             Binder.restoreCallingIdentity(ident);
4071         }
4072     }
4073 
4074     @Override
setAirplaneMode(boolean enable)4075     public void setAirplaneMode(boolean enable) {
4076         enforceConnectivityInternalPermission();
4077         final long ident = Binder.clearCallingIdentity();
4078         try {
4079             final ContentResolver cr = mContext.getContentResolver();
4080             Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, encodeBool(enable));
4081             Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
4082             intent.putExtra("state", enable);
4083             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
4084         } finally {
4085             Binder.restoreCallingIdentity(ident);
4086         }
4087     }
4088 
onUserStart(int userId)4089     private void onUserStart(int userId) {
4090         synchronized (mVpns) {
4091             Vpn userVpn = mVpns.get(userId);
4092             if (userVpn != null) {
4093                 loge("Starting user already has a VPN");
4094                 return;
4095             }
4096             userVpn = new Vpn(mHandler.getLooper(), mContext, mNetd, userId);
4097             mVpns.put(userId, userVpn);
4098             if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) {
4099                 updateLockdownVpn();
4100             }
4101         }
4102     }
4103 
onUserStop(int userId)4104     private void onUserStop(int userId) {
4105         synchronized (mVpns) {
4106             Vpn userVpn = mVpns.get(userId);
4107             if (userVpn == null) {
4108                 loge("Stopped user has no VPN");
4109                 return;
4110             }
4111             userVpn.onUserStopped();
4112             mVpns.delete(userId);
4113         }
4114     }
4115 
onUserAdded(int userId)4116     private void onUserAdded(int userId) {
4117         synchronized (mVpns) {
4118             final int vpnsSize = mVpns.size();
4119             for (int i = 0; i < vpnsSize; i++) {
4120                 Vpn vpn = mVpns.valueAt(i);
4121                 vpn.onUserAdded(userId);
4122             }
4123         }
4124     }
4125 
onUserRemoved(int userId)4126     private void onUserRemoved(int userId) {
4127         synchronized (mVpns) {
4128             final int vpnsSize = mVpns.size();
4129             for (int i = 0; i < vpnsSize; i++) {
4130                 Vpn vpn = mVpns.valueAt(i);
4131                 vpn.onUserRemoved(userId);
4132             }
4133         }
4134     }
4135 
onUserUnlocked(int userId)4136     private void onUserUnlocked(int userId) {
4137         synchronized (mVpns) {
4138             // User present may be sent because of an unlock, which might mean an unlocked keystore.
4139             if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) {
4140                 updateLockdownVpn();
4141             } else {
4142                 startAlwaysOnVpn(userId);
4143             }
4144         }
4145     }
4146 
4147     private BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
4148         @Override
4149         public void onReceive(Context context, Intent intent) {
4150             final String action = intent.getAction();
4151             final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
4152             if (userId == UserHandle.USER_NULL) return;
4153 
4154             if (Intent.ACTION_USER_STARTED.equals(action)) {
4155                 onUserStart(userId);
4156             } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
4157                 onUserStop(userId);
4158             } else if (Intent.ACTION_USER_ADDED.equals(action)) {
4159                 onUserAdded(userId);
4160             } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
4161                 onUserRemoved(userId);
4162             } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
4163                 onUserUnlocked(userId);
4164             }
4165         }
4166     };
4167 
4168     private BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() {
4169         @Override
4170         public void onReceive(Context context, Intent intent) {
4171             // Try creating lockdown tracker, since user present usually means
4172             // unlocked keystore.
4173             updateLockdownVpn();
4174             mContext.unregisterReceiver(this);
4175         }
4176     };
4177 
4178     private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos =
4179             new HashMap<Messenger, NetworkFactoryInfo>();
4180     private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
4181             new HashMap<NetworkRequest, NetworkRequestInfo>();
4182 
4183     private static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
4184     // Map from UID to number of NetworkRequests that UID has filed.
4185     @GuardedBy("mUidToNetworkRequestCount")
4186     private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray();
4187 
4188     private static class NetworkFactoryInfo {
4189         public final String name;
4190         public final Messenger messenger;
4191         public final AsyncChannel asyncChannel;
4192 
NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel)4193         public NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel) {
4194             this.name = name;
4195             this.messenger = messenger;
4196             this.asyncChannel = asyncChannel;
4197         }
4198     }
4199 
ensureNetworkRequestHasType(NetworkRequest request)4200     private void ensureNetworkRequestHasType(NetworkRequest request) {
4201         if (request.type == NetworkRequest.Type.NONE) {
4202             throw new IllegalArgumentException(
4203                     "All NetworkRequests in ConnectivityService must have a type");
4204         }
4205     }
4206 
4207     /**
4208      * Tracks info about the requester.
4209      * Also used to notice when the calling process dies so we can self-expire
4210      */
4211     private class NetworkRequestInfo implements IBinder.DeathRecipient {
4212         final NetworkRequest request;
4213         final PendingIntent mPendingIntent;
4214         boolean mPendingIntentSent;
4215         private final IBinder mBinder;
4216         final int mPid;
4217         final int mUid;
4218         final Messenger messenger;
4219 
NetworkRequestInfo(NetworkRequest r, PendingIntent pi)4220         NetworkRequestInfo(NetworkRequest r, PendingIntent pi) {
4221             request = r;
4222             ensureNetworkRequestHasType(request);
4223             mPendingIntent = pi;
4224             messenger = null;
4225             mBinder = null;
4226             mPid = getCallingPid();
4227             mUid = getCallingUid();
4228             enforceRequestCountLimit();
4229         }
4230 
NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder)4231         NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder) {
4232             super();
4233             messenger = m;
4234             request = r;
4235             ensureNetworkRequestHasType(request);
4236             mBinder = binder;
4237             mPid = getCallingPid();
4238             mUid = getCallingUid();
4239             mPendingIntent = null;
4240             enforceRequestCountLimit();
4241 
4242             try {
4243                 mBinder.linkToDeath(this, 0);
4244             } catch (RemoteException e) {
4245                 binderDied();
4246             }
4247         }
4248 
enforceRequestCountLimit()4249         private void enforceRequestCountLimit() {
4250             synchronized (mUidToNetworkRequestCount) {
4251                 int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1;
4252                 if (networkRequests >= MAX_NETWORK_REQUESTS_PER_UID) {
4253                     throw new ServiceSpecificException(
4254                             ConnectivityManager.Errors.TOO_MANY_REQUESTS);
4255                 }
4256                 mUidToNetworkRequestCount.put(mUid, networkRequests);
4257             }
4258         }
4259 
unlinkDeathRecipient()4260         void unlinkDeathRecipient() {
4261             if (mBinder != null) {
4262                 mBinder.unlinkToDeath(this, 0);
4263             }
4264         }
4265 
binderDied()4266         public void binderDied() {
4267             log("ConnectivityService NetworkRequestInfo binderDied(" +
4268                     request + ", " + mBinder + ")");
4269             releaseNetworkRequest(request);
4270         }
4271 
toString()4272         public String toString() {
4273             return "uid/pid:" + mUid + "/" + mPid + " " + request +
4274                     (mPendingIntent == null ? "" : " to trigger " + mPendingIntent);
4275         }
4276     }
4277 
ensureRequestableCapabilities(NetworkCapabilities networkCapabilities)4278     private void ensureRequestableCapabilities(NetworkCapabilities networkCapabilities) {
4279         final String badCapability = networkCapabilities.describeFirstNonRequestableCapability();
4280         if (badCapability != null) {
4281             throw new IllegalArgumentException("Cannot request network with " + badCapability);
4282         }
4283     }
4284 
4285     // This checks that the passed capabilities either do not request a specific SSID, or the
4286     // calling app has permission to do so.
ensureSufficientPermissionsForRequest(NetworkCapabilities nc, int callerPid, int callerUid)4287     private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
4288             int callerPid, int callerUid) {
4289         if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) {
4290             throw new SecurityException("Insufficient permissions to request a specific SSID");
4291         }
4292     }
4293 
getSignalStrengthThresholds(NetworkAgentInfo nai)4294     private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) {
4295         final SortedSet<Integer> thresholds = new TreeSet();
4296         synchronized (nai) {
4297             for (NetworkRequestInfo nri : mNetworkRequests.values()) {
4298                 if (nri.request.networkCapabilities.hasSignalStrength() &&
4299                         nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
4300                     thresholds.add(nri.request.networkCapabilities.getSignalStrength());
4301                 }
4302             }
4303         }
4304         return new ArrayList<Integer>(thresholds);
4305     }
4306 
updateSignalStrengthThresholds( NetworkAgentInfo nai, String reason, NetworkRequest request)4307     private void updateSignalStrengthThresholds(
4308             NetworkAgentInfo nai, String reason, NetworkRequest request) {
4309         ArrayList<Integer> thresholdsArray = getSignalStrengthThresholds(nai);
4310         Bundle thresholds = new Bundle();
4311         thresholds.putIntegerArrayList("thresholds", thresholdsArray);
4312 
4313         if (VDBG || (DBG && !"CONNECT".equals(reason))) {
4314             String detail;
4315             if (request != null && request.networkCapabilities.hasSignalStrength()) {
4316                 detail = reason + " " + request.networkCapabilities.getSignalStrength();
4317             } else {
4318                 detail = reason;
4319             }
4320             log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s",
4321                     detail, Arrays.toString(thresholdsArray.toArray()), nai.name()));
4322         }
4323 
4324         nai.asyncChannel.sendMessage(
4325                 android.net.NetworkAgent.CMD_SET_SIGNAL_STRENGTH_THRESHOLDS,
4326                 0, 0, thresholds);
4327     }
4328 
ensureValidNetworkSpecifier(NetworkCapabilities nc)4329     private void ensureValidNetworkSpecifier(NetworkCapabilities nc) {
4330         if (nc == null) {
4331             return;
4332         }
4333         NetworkSpecifier ns = nc.getNetworkSpecifier();
4334         if (ns == null) {
4335             return;
4336         }
4337         MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(ns);
4338         ns.assertValidFromUid(Binder.getCallingUid());
4339     }
4340 
4341     @Override
requestNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, int timeoutMs, IBinder binder, int legacyType)4342     public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
4343             Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
4344         final NetworkRequest.Type type = (networkCapabilities == null)
4345                 ? NetworkRequest.Type.TRACK_DEFAULT
4346                 : NetworkRequest.Type.REQUEST;
4347         // If the requested networkCapabilities is null, take them instead from
4348         // the default network request. This allows callers to keep track of
4349         // the system default network.
4350         if (type == NetworkRequest.Type.TRACK_DEFAULT) {
4351             networkCapabilities = createDefaultNetworkCapabilitiesForUid(Binder.getCallingUid());
4352             enforceAccessPermission();
4353         } else {
4354             networkCapabilities = new NetworkCapabilities(networkCapabilities);
4355             enforceNetworkRequestPermissions(networkCapabilities);
4356             // TODO: this is incorrect. We mark the request as metered or not depending on the state
4357             // of the app when the request is filed, but we never change the request if the app
4358             // changes network state. http://b/29964605
4359             enforceMeteredApnPolicy(networkCapabilities);
4360         }
4361         ensureRequestableCapabilities(networkCapabilities);
4362         ensureSufficientPermissionsForRequest(networkCapabilities,
4363                 Binder.getCallingPid(), Binder.getCallingUid());
4364         // Set the UID range for this request to the single UID of the requester, or to an empty
4365         // set of UIDs if the caller has the appropriate permission and UIDs have not been set.
4366         // This will overwrite any allowed UIDs in the requested capabilities. Though there
4367         // are no visible methods to set the UIDs, an app could use reflection to try and get
4368         // networks for other apps so it's essential that the UIDs are overwritten.
4369         restrictRequestUidsForCaller(networkCapabilities);
4370 
4371         if (timeoutMs < 0) {
4372             throw new IllegalArgumentException("Bad timeout specified");
4373         }
4374         ensureValidNetworkSpecifier(networkCapabilities);
4375 
4376         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
4377                 nextNetworkRequestId(), type);
4378         NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder);
4379         if (DBG) log("requestNetwork for " + nri);
4380 
4381         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
4382         if (timeoutMs > 0) {
4383             mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST,
4384                     nri), timeoutMs);
4385         }
4386         return networkRequest;
4387     }
4388 
enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities)4389     private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) {
4390         if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
4391             enforceConnectivityRestrictedNetworksPermission();
4392         } else {
4393             enforceChangePermission();
4394         }
4395     }
4396 
4397     @Override
requestBandwidthUpdate(Network network)4398     public boolean requestBandwidthUpdate(Network network) {
4399         enforceAccessPermission();
4400         NetworkAgentInfo nai = null;
4401         if (network == null) {
4402             return false;
4403         }
4404         synchronized (mNetworkForNetId) {
4405             nai = mNetworkForNetId.get(network.netId);
4406         }
4407         if (nai != null) {
4408             nai.asyncChannel.sendMessage(android.net.NetworkAgent.CMD_REQUEST_BANDWIDTH_UPDATE);
4409             return true;
4410         }
4411         return false;
4412     }
4413 
isSystem(int uid)4414     private boolean isSystem(int uid) {
4415         return uid < Process.FIRST_APPLICATION_UID;
4416     }
4417 
enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities)4418     private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) {
4419         final int uid = Binder.getCallingUid();
4420         if (isSystem(uid)) {
4421             // Exemption for system uid.
4422             return;
4423         }
4424         if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
4425             // Policy already enforced.
4426             return;
4427         }
4428         if (mPolicyManagerInternal.isUidRestrictedOnMeteredNetworks(uid)) {
4429             // If UID is restricted, don't allow them to bring up metered APNs.
4430             networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
4431         }
4432     }
4433 
4434     @Override
pendingRequestForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation)4435     public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
4436             PendingIntent operation) {
4437         checkNotNull(operation, "PendingIntent cannot be null.");
4438         networkCapabilities = new NetworkCapabilities(networkCapabilities);
4439         enforceNetworkRequestPermissions(networkCapabilities);
4440         enforceMeteredApnPolicy(networkCapabilities);
4441         ensureRequestableCapabilities(networkCapabilities);
4442         ensureSufficientPermissionsForRequest(networkCapabilities,
4443                 Binder.getCallingPid(), Binder.getCallingUid());
4444         ensureValidNetworkSpecifier(networkCapabilities);
4445         restrictRequestUidsForCaller(networkCapabilities);
4446 
4447         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
4448                 nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
4449         NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation);
4450         if (DBG) log("pendingRequest for " + nri);
4451         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT,
4452                 nri));
4453         return networkRequest;
4454     }
4455 
releasePendingNetworkRequestWithDelay(PendingIntent operation)4456     private void releasePendingNetworkRequestWithDelay(PendingIntent operation) {
4457         mHandler.sendMessageDelayed(
4458                 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
4459                 getCallingUid(), 0, operation), mReleasePendingIntentDelayMs);
4460     }
4461 
4462     @Override
releasePendingNetworkRequest(PendingIntent operation)4463     public void releasePendingNetworkRequest(PendingIntent operation) {
4464         checkNotNull(operation, "PendingIntent cannot be null.");
4465         mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
4466                 getCallingUid(), 0, operation));
4467     }
4468 
4469     // In order to implement the compatibility measure for pre-M apps that call
4470     // WifiManager.enableNetwork(..., true) without also binding to that network explicitly,
4471     // WifiManager registers a network listen for the purpose of calling setProcessDefaultNetwork.
4472     // This ensures it has permission to do so.
hasWifiNetworkListenPermission(NetworkCapabilities nc)4473     private boolean hasWifiNetworkListenPermission(NetworkCapabilities nc) {
4474         if (nc == null) {
4475             return false;
4476         }
4477         int[] transportTypes = nc.getTransportTypes();
4478         if (transportTypes.length != 1 || transportTypes[0] != NetworkCapabilities.TRANSPORT_WIFI) {
4479             return false;
4480         }
4481         try {
4482             mContext.enforceCallingOrSelfPermission(
4483                     android.Manifest.permission.ACCESS_WIFI_STATE,
4484                     "ConnectivityService");
4485         } catch (SecurityException e) {
4486             return false;
4487         }
4488         return true;
4489     }
4490 
4491     @Override
listenForNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, IBinder binder)4492     public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
4493             Messenger messenger, IBinder binder) {
4494         if (!hasWifiNetworkListenPermission(networkCapabilities)) {
4495             enforceAccessPermission();
4496         }
4497 
4498         NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
4499         ensureSufficientPermissionsForRequest(networkCapabilities,
4500                 Binder.getCallingPid(), Binder.getCallingUid());
4501         restrictRequestUidsForCaller(nc);
4502         // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so
4503         // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get
4504         // onLost and onAvailable callbacks when networks move in and out of the background.
4505         // There is no need to do this for requests because an app without CHANGE_NETWORK_STATE
4506         // can't request networks.
4507         restrictBackgroundRequestForCaller(nc);
4508         ensureValidNetworkSpecifier(nc);
4509 
4510         NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
4511                 NetworkRequest.Type.LISTEN);
4512         NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder);
4513         if (VDBG) log("listenForNetwork for " + nri);
4514 
4515         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
4516         return networkRequest;
4517     }
4518 
4519     @Override
pendingListenForNetwork(NetworkCapabilities networkCapabilities, PendingIntent operation)4520     public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
4521             PendingIntent operation) {
4522         checkNotNull(operation, "PendingIntent cannot be null.");
4523         if (!hasWifiNetworkListenPermission(networkCapabilities)) {
4524             enforceAccessPermission();
4525         }
4526         ensureValidNetworkSpecifier(networkCapabilities);
4527         ensureSufficientPermissionsForRequest(networkCapabilities,
4528                 Binder.getCallingPid(), Binder.getCallingUid());
4529 
4530         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
4531         restrictRequestUidsForCaller(nc);
4532 
4533         NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
4534                 NetworkRequest.Type.LISTEN);
4535         NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation);
4536         if (VDBG) log("pendingListenForNetwork for " + nri);
4537 
4538         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
4539     }
4540 
4541     @Override
releaseNetworkRequest(NetworkRequest networkRequest)4542     public void releaseNetworkRequest(NetworkRequest networkRequest) {
4543         ensureNetworkRequestHasType(networkRequest);
4544         mHandler.sendMessage(mHandler.obtainMessage(
4545                 EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(), 0, networkRequest));
4546     }
4547 
4548     @Override
registerNetworkFactory(Messenger messenger, String name)4549     public void registerNetworkFactory(Messenger messenger, String name) {
4550         enforceConnectivityInternalPermission();
4551         NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel());
4552         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi));
4553     }
4554 
handleRegisterNetworkFactory(NetworkFactoryInfo nfi)4555     private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) {
4556         if (DBG) log("Got NetworkFactory Messenger for " + nfi.name);
4557         mNetworkFactoryInfos.put(nfi.messenger, nfi);
4558         nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger);
4559     }
4560 
4561     @Override
unregisterNetworkFactory(Messenger messenger)4562     public void unregisterNetworkFactory(Messenger messenger) {
4563         enforceConnectivityInternalPermission();
4564         mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger));
4565     }
4566 
handleUnregisterNetworkFactory(Messenger messenger)4567     private void handleUnregisterNetworkFactory(Messenger messenger) {
4568         NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger);
4569         if (nfi == null) {
4570             loge("Failed to find Messenger in unregisterNetworkFactory");
4571             return;
4572         }
4573         if (DBG) log("unregisterNetworkFactory for " + nfi.name);
4574     }
4575 
4576     /**
4577      * NetworkAgentInfo supporting a request by requestId.
4578      * These have already been vetted (their Capabilities satisfy the request)
4579      * and the are the highest scored network available.
4580      * the are keyed off the Requests requestId.
4581      */
4582     // NOTE: Accessed on multiple threads, must be synchronized on itself.
4583     @GuardedBy("mNetworkForRequestId")
4584     private final SparseArray<NetworkAgentInfo> mNetworkForRequestId =
4585             new SparseArray<NetworkAgentInfo>();
4586 
4587     // NOTE: Accessed on multiple threads, must be synchronized on itself.
4588     @GuardedBy("mNetworkForNetId")
4589     private final SparseArray<NetworkAgentInfo> mNetworkForNetId =
4590             new SparseArray<NetworkAgentInfo>();
4591     // NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId.
4592     // An entry is first added to mNetIdInUse, prior to mNetworkForNetId, so
4593     // there may not be a strict 1:1 correlation between the two.
4594     @GuardedBy("mNetworkForNetId")
4595     private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray();
4596 
4597     // NetworkAgentInfo keyed off its connecting messenger
4598     // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays
4599     // NOTE: Only should be accessed on ConnectivityServiceThread, except dump().
4600     private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos =
4601             new HashMap<Messenger, NetworkAgentInfo>();
4602 
4603     @GuardedBy("mBlockedAppUids")
4604     private final HashSet<Integer> mBlockedAppUids = new HashSet();
4605 
4606     // Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
4607     private final NetworkRequest mDefaultRequest;
4608 
4609     // Request used to optionally keep mobile data active even when higher
4610     // priority networks like Wi-Fi are active.
4611     private final NetworkRequest mDefaultMobileDataRequest;
4612 
getNetworkForRequest(int requestId)4613     private NetworkAgentInfo getNetworkForRequest(int requestId) {
4614         synchronized (mNetworkForRequestId) {
4615             return mNetworkForRequestId.get(requestId);
4616         }
4617     }
4618 
clearNetworkForRequest(int requestId)4619     private void clearNetworkForRequest(int requestId) {
4620         synchronized (mNetworkForRequestId) {
4621             mNetworkForRequestId.remove(requestId);
4622         }
4623     }
4624 
setNetworkForRequest(int requestId, NetworkAgentInfo nai)4625     private void setNetworkForRequest(int requestId, NetworkAgentInfo nai) {
4626         synchronized (mNetworkForRequestId) {
4627             mNetworkForRequestId.put(requestId, nai);
4628         }
4629     }
4630 
getDefaultNetwork()4631     private NetworkAgentInfo getDefaultNetwork() {
4632         return getNetworkForRequest(mDefaultRequest.requestId);
4633     }
4634 
isDefaultNetwork(NetworkAgentInfo nai)4635     private boolean isDefaultNetwork(NetworkAgentInfo nai) {
4636         return nai == getDefaultNetwork();
4637     }
4638 
isDefaultRequest(NetworkRequestInfo nri)4639     private boolean isDefaultRequest(NetworkRequestInfo nri) {
4640         return nri.request.requestId == mDefaultRequest.requestId;
4641     }
4642 
registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int currentScore, NetworkMisc networkMisc)4643     public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
4644             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
4645             int currentScore, NetworkMisc networkMisc) {
4646         enforceConnectivityInternalPermission();
4647 
4648         LinkProperties lp = new LinkProperties(linkProperties);
4649         lp.ensureDirectlyConnectedRoutes();
4650         // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
4651         // satisfies mDefaultRequest.
4652         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
4653         final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
4654                 new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore,
4655                 mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this);
4656         // Make sure the network capabilities reflect what the agent info says.
4657         nai.networkCapabilities = mixInCapabilities(nai, nc);
4658         synchronized (this) {
4659             nai.networkMonitor.systemReady = mSystemReady;
4660         }
4661         final String extraInfo = networkInfo.getExtraInfo();
4662         final String name = TextUtils.isEmpty(extraInfo)
4663                 ? nai.networkCapabilities.getSSID() : extraInfo;
4664         addValidationLogs(nai.networkMonitor.getValidationLogs(), nai.network, name);
4665         if (DBG) log("registerNetworkAgent " + nai);
4666         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
4667         return nai.network.netId;
4668     }
4669 
handleRegisterNetworkAgent(NetworkAgentInfo nai)4670     private void handleRegisterNetworkAgent(NetworkAgentInfo nai) {
4671         if (VDBG) log("Got NetworkAgent Messenger");
4672         mNetworkAgentInfos.put(nai.messenger, nai);
4673         synchronized (mNetworkForNetId) {
4674             mNetworkForNetId.put(nai.network.netId, nai);
4675         }
4676         nai.asyncChannel.connect(mContext, mTrackerHandler, nai.messenger);
4677         NetworkInfo networkInfo = nai.networkInfo;
4678         nai.networkInfo = null;
4679         updateNetworkInfo(nai, networkInfo);
4680         updateUids(nai, null, nai.networkCapabilities);
4681     }
4682 
updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties oldLp)4683     private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties oldLp) {
4684         LinkProperties newLp = new LinkProperties(networkAgent.linkProperties);
4685         int netId = networkAgent.network.netId;
4686 
4687         // The NetworkAgentInfo does not know whether clatd is running on its network or not. Before
4688         // we do anything else, make sure its LinkProperties are accurate.
4689         if (networkAgent.clatd != null) {
4690             networkAgent.clatd.fixupLinkProperties(oldLp, newLp);
4691         }
4692 
4693         updateInterfaces(newLp, oldLp, netId, networkAgent.networkCapabilities);
4694         updateMtu(newLp, oldLp);
4695         // TODO - figure out what to do for clat
4696 //        for (LinkProperties lp : newLp.getStackedLinks()) {
4697 //            updateMtu(lp, null);
4698 //        }
4699         updateTcpBufferSizes(networkAgent);
4700 
4701         updateRoutes(newLp, oldLp, netId);
4702         updateDnses(newLp, oldLp, netId);
4703         // Make sure LinkProperties represents the latest private DNS status.
4704         // This does not need to be done before updateDnses because the
4705         // LinkProperties are not the source of the private DNS configuration.
4706         // updateDnses will fetch the private DNS configuration from DnsManager.
4707         mDnsManager.updatePrivateDnsStatus(netId, newLp);
4708 
4709         // Start or stop clat accordingly to network state.
4710         networkAgent.updateClat(mNetd);
4711         if (isDefaultNetwork(networkAgent)) {
4712             handleApplyDefaultProxy(newLp.getHttpProxy());
4713         } else {
4714             updateProxy(newLp, oldLp, networkAgent);
4715         }
4716         // TODO - move this check to cover the whole function
4717         if (!Objects.equals(newLp, oldLp)) {
4718             synchronized (networkAgent) {
4719                 networkAgent.linkProperties = newLp;
4720             }
4721             notifyIfacesChangedForNetworkStats();
4722             notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
4723         }
4724 
4725         mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent);
4726     }
4727 
wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add)4728     private void wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add) {
4729         // Marks are only available on WiFi interaces. Checking for
4730         // marks on unsupported interfaces is harmless.
4731         if (!caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
4732             return;
4733         }
4734 
4735         int mark = mContext.getResources().getInteger(
4736             com.android.internal.R.integer.config_networkWakeupPacketMark);
4737         int mask = mContext.getResources().getInteger(
4738             com.android.internal.R.integer.config_networkWakeupPacketMask);
4739 
4740         // Mask/mark of zero will not detect anything interesting.
4741         // Don't install rules unless both values are nonzero.
4742         if (mark == 0 || mask == 0) {
4743             return;
4744         }
4745 
4746         final String prefix = "iface:" + iface;
4747         try {
4748             if (add) {
4749                 mNetd.getNetdService().wakeupAddInterface(iface, prefix, mark, mask);
4750             } else {
4751                 mNetd.getNetdService().wakeupDelInterface(iface, prefix, mark, mask);
4752             }
4753         } catch (Exception e) {
4754             loge("Exception modifying wakeup packet monitoring: " + e);
4755         }
4756 
4757     }
4758 
updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId, NetworkCapabilities caps)4759     private void updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId,
4760                                   NetworkCapabilities caps) {
4761         CompareResult<String> interfaceDiff = new CompareResult<String>(
4762                 oldLp != null ? oldLp.getAllInterfaceNames() : null,
4763                 newLp != null ? newLp.getAllInterfaceNames() : null);
4764         for (String iface : interfaceDiff.added) {
4765             try {
4766                 if (DBG) log("Adding iface " + iface + " to network " + netId);
4767                 mNetd.addInterfaceToNetwork(iface, netId);
4768                 wakeupModifyInterface(iface, caps, true);
4769             } catch (Exception e) {
4770                 loge("Exception adding interface: " + e);
4771             }
4772         }
4773         for (String iface : interfaceDiff.removed) {
4774             try {
4775                 if (DBG) log("Removing iface " + iface + " from network " + netId);
4776                 wakeupModifyInterface(iface, caps, false);
4777                 mNetd.removeInterfaceFromNetwork(iface, netId);
4778             } catch (Exception e) {
4779                 loge("Exception removing interface: " + e);
4780             }
4781         }
4782     }
4783 
4784     /**
4785      * Have netd update routes from oldLp to newLp.
4786      * @return true if routes changed between oldLp and newLp
4787      */
updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId)4788     private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
4789         // Compare the route diff to determine which routes should be added and removed.
4790         CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>(
4791                 oldLp != null ? oldLp.getAllRoutes() : null,
4792                 newLp != null ? newLp.getAllRoutes() : null);
4793 
4794         // add routes before removing old in case it helps with continuous connectivity
4795 
4796         // do this twice, adding non-nexthop routes first, then routes they are dependent on
4797         for (RouteInfo route : routeDiff.added) {
4798             if (route.hasGateway()) continue;
4799             if (VDBG) log("Adding Route [" + route + "] to network " + netId);
4800             try {
4801                 mNetd.addRoute(netId, route);
4802             } catch (Exception e) {
4803                 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) {
4804                     loge("Exception in addRoute for non-gateway: " + e);
4805                 }
4806             }
4807         }
4808         for (RouteInfo route : routeDiff.added) {
4809             if (route.hasGateway() == false) continue;
4810             if (VDBG) log("Adding Route [" + route + "] to network " + netId);
4811             try {
4812                 mNetd.addRoute(netId, route);
4813             } catch (Exception e) {
4814                 if ((route.getGateway() instanceof Inet4Address) || VDBG) {
4815                     loge("Exception in addRoute for gateway: " + e);
4816                 }
4817             }
4818         }
4819 
4820         for (RouteInfo route : routeDiff.removed) {
4821             if (VDBG) log("Removing Route [" + route + "] from network " + netId);
4822             try {
4823                 mNetd.removeRoute(netId, route);
4824             } catch (Exception e) {
4825                 loge("Exception in removeRoute: " + e);
4826             }
4827         }
4828         return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty();
4829     }
4830 
updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId)4831     private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
4832         if (oldLp != null && newLp.isIdenticalDnses(oldLp)) {
4833             return;  // no updating necessary
4834         }
4835 
4836         final NetworkAgentInfo defaultNai = getDefaultNetwork();
4837         final boolean isDefaultNetwork = (defaultNai != null && defaultNai.network.netId == netId);
4838 
4839         if (DBG) {
4840             final Collection<InetAddress> dnses = newLp.getDnsServers();
4841             log("Setting DNS servers for network " + netId + " to " + dnses);
4842         }
4843         try {
4844             mDnsManager.setDnsConfigurationForNetwork(netId, newLp, isDefaultNetwork);
4845         } catch (Exception e) {
4846             loge("Exception in setDnsConfigurationForNetwork: " + e);
4847         }
4848     }
4849 
getNetworkPermission(NetworkCapabilities nc)4850     private String getNetworkPermission(NetworkCapabilities nc) {
4851         // TODO: make these permission strings AIDL constants instead.
4852         if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
4853             return NetworkManagementService.PERMISSION_SYSTEM;
4854         }
4855         if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) {
4856             return NetworkManagementService.PERMISSION_NETWORK;
4857         }
4858         return null;
4859     }
4860 
4861     /**
4862      * Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are
4863      * maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal,
4864      * and foreground status).
4865      */
mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc)4866     private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) {
4867         // Once a NetworkAgent is connected, complain if some immutable capabilities are removed.
4868          // Don't complain for VPNs since they're not driven by requests and there is no risk of
4869          // causing a connect/teardown loop.
4870          // TODO: remove this altogether and make it the responsibility of the NetworkFactories to
4871          // avoid connect/teardown loops.
4872         if (nai.everConnected &&
4873                 !nai.isVPN() &&
4874                 !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) {
4875             // TODO: consider not complaining when a network agent degrades its capabilities if this
4876             // does not cause any request (that is not a listen) currently matching that agent to
4877             // stop being matched by the updated agent.
4878             String diff = nai.networkCapabilities.describeImmutableDifferences(nc);
4879             if (!TextUtils.isEmpty(diff)) {
4880                 Slog.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff);
4881             }
4882         }
4883 
4884         // Don't modify caller's NetworkCapabilities.
4885         NetworkCapabilities newNc = new NetworkCapabilities(nc);
4886         if (nai.lastValidated) {
4887             newNc.addCapability(NET_CAPABILITY_VALIDATED);
4888         } else {
4889             newNc.removeCapability(NET_CAPABILITY_VALIDATED);
4890         }
4891         if (nai.lastCaptivePortalDetected) {
4892             newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
4893         } else {
4894             newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
4895         }
4896         if (nai.isBackgroundNetwork()) {
4897             newNc.removeCapability(NET_CAPABILITY_FOREGROUND);
4898         } else {
4899             newNc.addCapability(NET_CAPABILITY_FOREGROUND);
4900         }
4901         if (nai.isSuspended()) {
4902             newNc.removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
4903         } else {
4904             newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
4905         }
4906 
4907         return newNc;
4908     }
4909 
4910     /**
4911      * Update the NetworkCapabilities for {@code nai} to {@code nc}. Specifically:
4912      *
4913      * 1. Calls mixInCapabilities to merge the passed-in NetworkCapabilities {@code nc} with the
4914      *    capabilities we manage and store in {@code nai}, such as validated status and captive
4915      *    portal status)
4916      * 2. Takes action on the result: changes network permissions, sends CAP_CHANGED callbacks, and
4917      *    potentially triggers rematches.
4918      * 3. Directly informs other network stack components (NetworkStatsService, VPNs, etc. of the
4919      *    change.)
4920      *
4921      * @param oldScore score of the network before any of the changes that prompted us
4922      *                 to call this function.
4923      * @param nai the network having its capabilities updated.
4924      * @param nc the new network capabilities.
4925      */
updateCapabilities(int oldScore, NetworkAgentInfo nai, NetworkCapabilities nc)4926     private void updateCapabilities(int oldScore, NetworkAgentInfo nai, NetworkCapabilities nc) {
4927         NetworkCapabilities newNc = mixInCapabilities(nai, nc);
4928 
4929         if (Objects.equals(nai.networkCapabilities, newNc)) return;
4930 
4931         final String oldPermission = getNetworkPermission(nai.networkCapabilities);
4932         final String newPermission = getNetworkPermission(newNc);
4933         if (!Objects.equals(oldPermission, newPermission) && nai.created && !nai.isVPN()) {
4934             try {
4935                 mNetd.setNetworkPermission(nai.network.netId, newPermission);
4936             } catch (RemoteException e) {
4937                 loge("Exception in setNetworkPermission: " + e);
4938             }
4939         }
4940 
4941         final NetworkCapabilities prevNc;
4942         synchronized (nai) {
4943             prevNc = nai.networkCapabilities;
4944             nai.networkCapabilities = newNc;
4945         }
4946 
4947         updateUids(nai, prevNc, newNc);
4948 
4949         if (nai.getCurrentScore() == oldScore && newNc.equalRequestableCapabilities(prevNc)) {
4950             // If the requestable capabilities haven't changed, and the score hasn't changed, then
4951             // the change we're processing can't affect any requests, it can only affect the listens
4952             // on this network. We might have been called by rematchNetworkAndRequests when a
4953             // network changed foreground state.
4954             processListenRequests(nai, true);
4955         } else {
4956             // If the requestable capabilities have changed or the score changed, we can't have been
4957             // called by rematchNetworkAndRequests, so it's safe to start a rematch.
4958             rematchAllNetworksAndRequests(nai, oldScore);
4959             notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
4960         }
4961 
4962         // Report changes that are interesting for network statistics tracking.
4963         if (prevNc != null) {
4964             final boolean meteredChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_METERED) !=
4965                     newNc.hasCapability(NET_CAPABILITY_NOT_METERED);
4966             final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) !=
4967                     newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
4968             if (meteredChanged || roamingChanged) {
4969                 notifyIfacesChangedForNetworkStats();
4970             }
4971         }
4972 
4973         if (!newNc.hasTransport(TRANSPORT_VPN)) {
4974             // Tell VPNs about updated capabilities, since they may need to
4975             // bubble those changes through.
4976             updateAllVpnsCapabilities();
4977         }
4978     }
4979 
updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc, NetworkCapabilities newNc)4980     private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc,
4981             NetworkCapabilities newNc) {
4982         Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUids();
4983         Set<UidRange> newRanges = null == newNc ? null : newNc.getUids();
4984         if (null == prevRanges) prevRanges = new ArraySet<>();
4985         if (null == newRanges) newRanges = new ArraySet<>();
4986         final Set<UidRange> prevRangesCopy = new ArraySet<>(prevRanges);
4987 
4988         prevRanges.removeAll(newRanges);
4989         newRanges.removeAll(prevRangesCopy);
4990 
4991         try {
4992             if (!newRanges.isEmpty()) {
4993                 final UidRange[] addedRangesArray = new UidRange[newRanges.size()];
4994                 newRanges.toArray(addedRangesArray);
4995                 mNetd.addVpnUidRanges(nai.network.netId, addedRangesArray);
4996             }
4997             if (!prevRanges.isEmpty()) {
4998                 final UidRange[] removedRangesArray = new UidRange[prevRanges.size()];
4999                 prevRanges.toArray(removedRangesArray);
5000                 mNetd.removeVpnUidRanges(nai.network.netId, removedRangesArray);
5001             }
5002         } catch (Exception e) {
5003             // Never crash!
5004             loge("Exception in updateUids: " + e);
5005         }
5006     }
5007 
handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp)5008     public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) {
5009         if (getNetworkAgentInfoForNetId(nai.network.netId) != nai) {
5010             // Ignore updates for disconnected networks
5011             return;
5012         }
5013         // newLp is already a defensive copy.
5014         newLp.ensureDirectlyConnectedRoutes();
5015         if (VDBG) {
5016             log("Update of LinkProperties for " + nai.name() +
5017                     "; created=" + nai.created +
5018                     "; everConnected=" + nai.everConnected);
5019         }
5020         LinkProperties oldLp = nai.linkProperties;
5021         synchronized (nai) {
5022             nai.linkProperties = newLp;
5023         }
5024         if (nai.everConnected) {
5025             updateLinkProperties(nai, oldLp);
5026         }
5027     }
5028 
sendUpdatedScoreToFactories(NetworkAgentInfo nai)5029     private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) {
5030         for (int i = 0; i < nai.numNetworkRequests(); i++) {
5031             NetworkRequest nr = nai.requestAt(i);
5032             // Don't send listening requests to factories. b/17393458
5033             if (nr.isListen()) continue;
5034             sendUpdatedScoreToFactories(nr, nai.getCurrentScore());
5035         }
5036     }
5037 
sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score)5038     private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) {
5039         if (VDBG) log("sending new Min Network Score(" + score + "): " + networkRequest.toString());
5040         for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
5041             nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, 0,
5042                     networkRequest);
5043         }
5044     }
5045 
sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, int notificationType)5046     private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent,
5047             int notificationType) {
5048         if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) {
5049             Intent intent = new Intent();
5050             intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network);
5051             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, nri.request);
5052             nri.mPendingIntentSent = true;
5053             sendIntent(nri.mPendingIntent, intent);
5054         }
5055         // else not handled
5056     }
5057 
sendIntent(PendingIntent pendingIntent, Intent intent)5058     private void sendIntent(PendingIntent pendingIntent, Intent intent) {
5059         mPendingIntentWakeLock.acquire();
5060         try {
5061             if (DBG) log("Sending " + pendingIntent);
5062             pendingIntent.send(mContext, 0, intent, this /* onFinished */, null /* Handler */);
5063         } catch (PendingIntent.CanceledException e) {
5064             if (DBG) log(pendingIntent + " was not sent, it had been canceled.");
5065             mPendingIntentWakeLock.release();
5066             releasePendingNetworkRequest(pendingIntent);
5067         }
5068         // ...otherwise, mPendingIntentWakeLock.release() gets called by onSendFinished()
5069     }
5070 
5071     @Override
onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras)5072     public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
5073             String resultData, Bundle resultExtras) {
5074         if (DBG) log("Finished sending " + pendingIntent);
5075         mPendingIntentWakeLock.release();
5076         // Release with a delay so the receiving client has an opportunity to put in its
5077         // own request.
5078         releasePendingNetworkRequestWithDelay(pendingIntent);
5079     }
5080 
callCallbackForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent, int notificationType, int arg1)5081     private void callCallbackForRequest(NetworkRequestInfo nri,
5082             NetworkAgentInfo networkAgent, int notificationType, int arg1) {
5083         if (nri.messenger == null) {
5084             return;  // Default request has no msgr
5085         }
5086         Bundle bundle = new Bundle();
5087         // TODO: check if defensive copies of data is needed.
5088         putParcelable(bundle, new NetworkRequest(nri.request));
5089         Message msg = Message.obtain();
5090         if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) {
5091             putParcelable(bundle, networkAgent.network);
5092         }
5093         switch (notificationType) {
5094             case ConnectivityManager.CALLBACK_AVAILABLE: {
5095                 putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities));
5096                 putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
5097                 break;
5098             }
5099             case ConnectivityManager.CALLBACK_LOSING: {
5100                 msg.arg1 = arg1;
5101                 break;
5102             }
5103             case ConnectivityManager.CALLBACK_CAP_CHANGED: {
5104                 // networkAgent can't be null as it has been accessed a few lines above.
5105                 final NetworkCapabilities nc = networkCapabilitiesRestrictedForCallerPermissions(
5106                         networkAgent.networkCapabilities, nri.mPid, nri.mUid);
5107                 putParcelable(bundle, nc);
5108                 break;
5109             }
5110             case ConnectivityManager.CALLBACK_IP_CHANGED: {
5111                 putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
5112                 break;
5113             }
5114         }
5115         msg.what = notificationType;
5116         msg.setData(bundle);
5117         try {
5118             if (VDBG) {
5119                 String notification = ConnectivityManager.getCallbackName(notificationType);
5120                 log("sending notification " + notification + " for " + nri.request);
5121             }
5122             nri.messenger.send(msg);
5123         } catch (RemoteException e) {
5124             // may occur naturally in the race of binder death.
5125             loge("RemoteException caught trying to send a callback msg for " + nri.request);
5126         }
5127     }
5128 
putParcelable(Bundle bundle, T t)5129     private static <T extends Parcelable> void putParcelable(Bundle bundle, T t) {
5130         bundle.putParcelable(t.getClass().getSimpleName(), t);
5131     }
5132 
teardownUnneededNetwork(NetworkAgentInfo nai)5133     private void teardownUnneededNetwork(NetworkAgentInfo nai) {
5134         if (nai.numRequestNetworkRequests() != 0) {
5135             for (int i = 0; i < nai.numNetworkRequests(); i++) {
5136                 NetworkRequest nr = nai.requestAt(i);
5137                 // Ignore listening requests.
5138                 if (nr.isListen()) continue;
5139                 loge("Dead network still had at least " + nr);
5140                 break;
5141             }
5142         }
5143         nai.asyncChannel.disconnect();
5144     }
5145 
handleLingerComplete(NetworkAgentInfo oldNetwork)5146     private void handleLingerComplete(NetworkAgentInfo oldNetwork) {
5147         if (oldNetwork == null) {
5148             loge("Unknown NetworkAgentInfo in handleLingerComplete");
5149             return;
5150         }
5151         if (DBG) log("handleLingerComplete for " + oldNetwork.name());
5152 
5153         // If we get here it means that the last linger timeout for this network expired. So there
5154         // must be no other active linger timers, and we must stop lingering.
5155         oldNetwork.clearLingerState();
5156 
5157         if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) {
5158             // Tear the network down.
5159             teardownUnneededNetwork(oldNetwork);
5160         } else {
5161             // Put the network in the background.
5162             updateCapabilities(oldNetwork.getCurrentScore(), oldNetwork,
5163                     oldNetwork.networkCapabilities);
5164         }
5165     }
5166 
makeDefault(NetworkAgentInfo newNetwork)5167     private void makeDefault(NetworkAgentInfo newNetwork) {
5168         if (DBG) log("Switching to new default network: " + newNetwork);
5169         setupDataActivityTracking(newNetwork);
5170         try {
5171             mNetd.setDefaultNetId(newNetwork.network.netId);
5172         } catch (Exception e) {
5173             loge("Exception setting default network :" + e);
5174         }
5175 
5176         notifyLockdownVpn(newNetwork);
5177         handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy());
5178         updateTcpBufferSizes(newNetwork);
5179         mDnsManager.setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers());
5180         notifyIfacesChangedForNetworkStats();
5181     }
5182 
processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged)5183     private void processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged) {
5184         // For consistency with previous behaviour, send onLost callbacks before onAvailable.
5185         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
5186             NetworkRequest nr = nri.request;
5187             if (!nr.isListen()) continue;
5188             if (nai.isSatisfyingRequest(nr.requestId) && !nai.satisfies(nr)) {
5189                 nai.removeRequest(nri.request.requestId);
5190                 callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_LOST, 0);
5191             }
5192         }
5193 
5194         if (capabilitiesChanged) {
5195             notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
5196         }
5197 
5198         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
5199             NetworkRequest nr = nri.request;
5200             if (!nr.isListen()) continue;
5201             if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) {
5202                 nai.addRequest(nr);
5203                 notifyNetworkAvailable(nai, nri);
5204             }
5205         }
5206     }
5207 
5208     // Handles a network appearing or improving its score.
5209     //
5210     // - Evaluates all current NetworkRequests that can be
5211     //   satisfied by newNetwork, and reassigns to newNetwork
5212     //   any such requests for which newNetwork is the best.
5213     //
5214     // - Lingers any validated Networks that as a result are no longer
5215     //   needed. A network is needed if it is the best network for
5216     //   one or more NetworkRequests, or if it is a VPN.
5217     //
5218     // - Tears down newNetwork if it just became validated
5219     //   but turns out to be unneeded.
5220     //
5221     // - If reapUnvalidatedNetworks==REAP, tears down unvalidated
5222     //   networks that have no chance (i.e. even if validated)
5223     //   of becoming the highest scoring network.
5224     //
5225     // NOTE: This function only adds NetworkRequests that "newNetwork" could satisfy,
5226     // it does not remove NetworkRequests that other Networks could better satisfy.
5227     // If you need to handle decreases in score, use {@link rematchAllNetworksAndRequests}.
5228     // This function should be used when possible instead of {@code rematchAllNetworksAndRequests}
5229     // as it performs better by a factor of the number of Networks.
5230     //
5231     // @param newNetwork is the network to be matched against NetworkRequests.
5232     // @param reapUnvalidatedNetworks indicates if an additional pass over all networks should be
5233     //               performed to tear down unvalidated networks that have no chance (i.e. even if
5234     //               validated) of becoming the highest scoring network.
rematchNetworkAndRequests(NetworkAgentInfo newNetwork, ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now)5235     private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork,
5236             ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now) {
5237         if (!newNetwork.everConnected) return;
5238         boolean keep = newNetwork.isVPN();
5239         boolean isNewDefault = false;
5240         NetworkAgentInfo oldDefaultNetwork = null;
5241 
5242         final boolean wasBackgroundNetwork = newNetwork.isBackgroundNetwork();
5243         final int score = newNetwork.getCurrentScore();
5244 
5245         if (VDBG) log("rematching " + newNetwork.name());
5246 
5247         // Find and migrate to this Network any NetworkRequests for
5248         // which this network is now the best.
5249         ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<NetworkAgentInfo>();
5250         ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<NetworkRequestInfo>();
5251         NetworkCapabilities nc = newNetwork.networkCapabilities;
5252         if (VDBG) log(" network has: " + nc);
5253         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
5254             // Process requests in the first pass and listens in the second pass. This allows us to
5255             // change a network's capabilities depending on which requests it has. This is only
5256             // correct if the change in capabilities doesn't affect whether the network satisfies
5257             // requests or not, and doesn't affect the network's score.
5258             if (nri.request.isListen()) continue;
5259 
5260             final NetworkAgentInfo currentNetwork = getNetworkForRequest(nri.request.requestId);
5261             final boolean satisfies = newNetwork.satisfies(nri.request);
5262             if (newNetwork == currentNetwork && satisfies) {
5263                 if (VDBG) {
5264                     log("Network " + newNetwork.name() + " was already satisfying" +
5265                             " request " + nri.request.requestId + ". No change.");
5266                 }
5267                 keep = true;
5268                 continue;
5269             }
5270 
5271             // check if it satisfies the NetworkCapabilities
5272             if (VDBG) log("  checking if request is satisfied: " + nri.request);
5273             if (satisfies) {
5274                 // next check if it's better than any current network we're using for
5275                 // this request
5276                 if (VDBG) {
5277                     log("currentScore = " +
5278                             (currentNetwork != null ? currentNetwork.getCurrentScore() : 0) +
5279                             ", newScore = " + score);
5280                 }
5281                 if (currentNetwork == null || currentNetwork.getCurrentScore() < score) {
5282                     if (VDBG) log("rematch for " + newNetwork.name());
5283                     if (currentNetwork != null) {
5284                         if (VDBG) log("   accepting network in place of " + currentNetwork.name());
5285                         currentNetwork.removeRequest(nri.request.requestId);
5286                         currentNetwork.lingerRequest(nri.request, now, mLingerDelayMs);
5287                         affectedNetworks.add(currentNetwork);
5288                     } else {
5289                         if (VDBG) log("   accepting network in place of null");
5290                     }
5291                     newNetwork.unlingerRequest(nri.request);
5292                     setNetworkForRequest(nri.request.requestId, newNetwork);
5293                     if (!newNetwork.addRequest(nri.request)) {
5294                         Slog.wtf(TAG, "BUG: " + newNetwork.name() + " already has " + nri.request);
5295                     }
5296                     addedRequests.add(nri);
5297                     keep = true;
5298                     // Tell NetworkFactories about the new score, so they can stop
5299                     // trying to connect if they know they cannot match it.
5300                     // TODO - this could get expensive if we have alot of requests for this
5301                     // network.  Think about if there is a way to reduce this.  Push
5302                     // netid->request mapping to each factory?
5303                     sendUpdatedScoreToFactories(nri.request, score);
5304                     if (isDefaultRequest(nri)) {
5305                         isNewDefault = true;
5306                         oldDefaultNetwork = currentNetwork;
5307                         if (currentNetwork != null) {
5308                             mLingerMonitor.noteLingerDefaultNetwork(currentNetwork, newNetwork);
5309                         }
5310                     }
5311                 }
5312             } else if (newNetwork.isSatisfyingRequest(nri.request.requestId)) {
5313                 // If "newNetwork" is listed as satisfying "nri" but no longer satisfies "nri",
5314                 // mark it as no longer satisfying "nri".  Because networks are processed by
5315                 // rematchAllNetworksAndRequests() in descending score order, "currentNetwork" will
5316                 // match "newNetwork" before this loop will encounter a "currentNetwork" with higher
5317                 // score than "newNetwork" and where "currentNetwork" no longer satisfies "nri".
5318                 // This means this code doesn't have to handle the case where "currentNetwork" no
5319                 // longer satisfies "nri" when "currentNetwork" does not equal "newNetwork".
5320                 if (DBG) {
5321                     log("Network " + newNetwork.name() + " stopped satisfying" +
5322                             " request " + nri.request.requestId);
5323                 }
5324                 newNetwork.removeRequest(nri.request.requestId);
5325                 if (currentNetwork == newNetwork) {
5326                     clearNetworkForRequest(nri.request.requestId);
5327                     sendUpdatedScoreToFactories(nri.request, 0);
5328                 } else {
5329                     Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " +
5330                             newNetwork.name() +
5331                             " without updating mNetworkForRequestId or factories!");
5332                 }
5333                 // TODO: Technically, sending CALLBACK_LOST here is
5334                 // incorrect if there is a replacement network currently
5335                 // connected that can satisfy nri, which is a request
5336                 // (not a listen). However, the only capability that can both
5337                 // a) be requested and b) change is NET_CAPABILITY_TRUSTED,
5338                 // so this code is only incorrect for a network that loses
5339                 // the TRUSTED capability, which is a rare case.
5340                 callCallbackForRequest(nri, newNetwork, ConnectivityManager.CALLBACK_LOST, 0);
5341             }
5342         }
5343         if (isNewDefault) {
5344             // Notify system services that this network is up.
5345             makeDefault(newNetwork);
5346             // Log 0 -> X and Y -> X default network transitions, where X is the new default.
5347             metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(
5348                     now, newNetwork, oldDefaultNetwork);
5349             // Have a new default network, release the transition wakelock in
5350             scheduleReleaseNetworkTransitionWakelock();
5351         }
5352 
5353         if (!newNetwork.networkCapabilities.equalRequestableCapabilities(nc)) {
5354             Slog.wtf(TAG, String.format(
5355                     "BUG: %s changed requestable capabilities during rematch: %s -> %s",
5356                     newNetwork.name(), nc, newNetwork.networkCapabilities));
5357         }
5358         if (newNetwork.getCurrentScore() != score) {
5359             Slog.wtf(TAG, String.format(
5360                     "BUG: %s changed score during rematch: %d -> %d",
5361                    newNetwork.name(), score, newNetwork.getCurrentScore()));
5362         }
5363 
5364         // Second pass: process all listens.
5365         if (wasBackgroundNetwork != newNetwork.isBackgroundNetwork()) {
5366             // If the network went from background to foreground or vice versa, we need to update
5367             // its foreground state. It is safe to do this after rematching the requests because
5368             // NET_CAPABILITY_FOREGROUND does not affect requests, as is not a requestable
5369             // capability and does not affect the network's score (see the Slog.wtf call above).
5370             updateCapabilities(score, newNetwork, newNetwork.networkCapabilities);
5371         } else {
5372             processListenRequests(newNetwork, false);
5373         }
5374 
5375         // do this after the default net is switched, but
5376         // before LegacyTypeTracker sends legacy broadcasts
5377         for (NetworkRequestInfo nri : addedRequests) notifyNetworkAvailable(newNetwork, nri);
5378 
5379         // Linger any networks that are no longer needed. This should be done after sending the
5380         // available callback for newNetwork.
5381         for (NetworkAgentInfo nai : affectedNetworks) {
5382             updateLingerState(nai, now);
5383         }
5384         // Possibly unlinger newNetwork. Unlingering a network does not send any callbacks so it
5385         // does not need to be done in any particular order.
5386         updateLingerState(newNetwork, now);
5387 
5388         if (isNewDefault) {
5389             // Maintain the illusion: since the legacy API only
5390             // understands one network at a time, we must pretend
5391             // that the current default network disconnected before
5392             // the new one connected.
5393             if (oldDefaultNetwork != null) {
5394                 mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
5395                                           oldDefaultNetwork, true);
5396             }
5397             mDefaultInetConditionPublished = newNetwork.lastValidated ? 100 : 0;
5398             mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork);
5399             notifyLockdownVpn(newNetwork);
5400         }
5401 
5402         if (keep) {
5403             // Notify battery stats service about this network, both the normal
5404             // interface and any stacked links.
5405             // TODO: Avoid redoing this; this must only be done once when a network comes online.
5406             try {
5407                 final IBatteryStats bs = BatteryStatsService.getService();
5408                 final int type = newNetwork.networkInfo.getType();
5409 
5410                 final String baseIface = newNetwork.linkProperties.getInterfaceName();
5411                 bs.noteNetworkInterfaceType(baseIface, type);
5412                 for (LinkProperties stacked : newNetwork.linkProperties.getStackedLinks()) {
5413                     final String stackedIface = stacked.getInterfaceName();
5414                     bs.noteNetworkInterfaceType(stackedIface, type);
5415                 }
5416             } catch (RemoteException ignored) {
5417             }
5418 
5419             // This has to happen after the notifyNetworkCallbacks as that tickles each
5420             // ConnectivityManager instance so that legacy requests correctly bind dns
5421             // requests to this network.  The legacy users are listening for this bcast
5422             // and will generally do a dns request so they can ensureRouteToHost and if
5423             // they do that before the callbacks happen they'll use the default network.
5424             //
5425             // TODO: Is there still a race here? We send the broadcast
5426             // after sending the callback, but if the app can receive the
5427             // broadcast before the callback, it might still break.
5428             //
5429             // This *does* introduce a race where if the user uses the new api
5430             // (notification callbacks) and then uses the old api (getNetworkInfo(type))
5431             // they may get old info.  Reverse this after the old startUsing api is removed.
5432             // This is on top of the multiple intent sequencing referenced in the todo above.
5433             for (int i = 0; i < newNetwork.numNetworkRequests(); i++) {
5434                 NetworkRequest nr = newNetwork.requestAt(i);
5435                 if (nr.legacyType != TYPE_NONE && nr.isRequest()) {
5436                     // legacy type tracker filters out repeat adds
5437                     mLegacyTypeTracker.add(nr.legacyType, newNetwork);
5438                 }
5439             }
5440 
5441             // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above,
5442             // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest
5443             // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the
5444             // newNetwork to the tracker explicitly (it's a no-op if it has already been added).
5445             if (newNetwork.isVPN()) {
5446                 mLegacyTypeTracker.add(TYPE_VPN, newNetwork);
5447             }
5448         }
5449         if (reapUnvalidatedNetworks == ReapUnvalidatedNetworks.REAP) {
5450             for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
5451                 if (unneeded(nai, UnneededFor.TEARDOWN)) {
5452                     if (nai.getLingerExpiry() > 0) {
5453                         // This network has active linger timers and no requests, but is not
5454                         // lingering. Linger it.
5455                         //
5456                         // One way (the only way?) this can happen if this network is unvalidated
5457                         // and became unneeded due to another network improving its score to the
5458                         // point where this network will no longer be able to satisfy any requests
5459                         // even if it validates.
5460                         updateLingerState(nai, now);
5461                     } else {
5462                         if (DBG) log("Reaping " + nai.name());
5463                         teardownUnneededNetwork(nai);
5464                     }
5465                 }
5466             }
5467         }
5468     }
5469 
5470     /**
5471      * Attempt to rematch all Networks with NetworkRequests.  This may result in Networks
5472      * being disconnected.
5473      * @param changed If only one Network's score or capabilities have been modified since the last
5474      *         time this function was called, pass this Network in this argument, otherwise pass
5475      *         null.
5476      * @param oldScore If only one Network has been changed but its NetworkCapabilities have not
5477      *         changed, pass in the Network's score (from getCurrentScore()) prior to the change via
5478      *         this argument, otherwise pass {@code changed.getCurrentScore()} or 0 if
5479      *         {@code changed} is {@code null}. This is because NetworkCapabilities influence a
5480      *         network's score.
5481      */
rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore)5482     private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore) {
5483         // TODO: This may get slow.  The "changed" parameter is provided for future optimization
5484         // to avoid the slowness.  It is not simply enough to process just "changed", for
5485         // example in the case where "changed"'s score decreases and another network should begin
5486         // satifying a NetworkRequest that "changed" currently satisfies.
5487 
5488         // Optimization: Only reprocess "changed" if its score improved.  This is safe because it
5489         // can only add more NetworkRequests satisfied by "changed", and this is exactly what
5490         // rematchNetworkAndRequests() handles.
5491         final long now = SystemClock.elapsedRealtime();
5492         if (changed != null && oldScore < changed.getCurrentScore()) {
5493             rematchNetworkAndRequests(changed, ReapUnvalidatedNetworks.REAP, now);
5494         } else {
5495             final NetworkAgentInfo[] nais = mNetworkAgentInfos.values().toArray(
5496                     new NetworkAgentInfo[mNetworkAgentInfos.size()]);
5497             // Rematch higher scoring networks first to prevent requests first matching a lower
5498             // scoring network and then a higher scoring network, which could produce multiple
5499             // callbacks and inadvertently unlinger networks.
5500             Arrays.sort(nais);
5501             for (NetworkAgentInfo nai : nais) {
5502                 rematchNetworkAndRequests(nai,
5503                         // Only reap the last time through the loop.  Reaping before all rematching
5504                         // is complete could incorrectly teardown a network that hasn't yet been
5505                         // rematched.
5506                         (nai != nais[nais.length-1]) ? ReapUnvalidatedNetworks.DONT_REAP
5507                                 : ReapUnvalidatedNetworks.REAP,
5508                         now);
5509             }
5510         }
5511     }
5512 
updateInetCondition(NetworkAgentInfo nai)5513     private void updateInetCondition(NetworkAgentInfo nai) {
5514         // Don't bother updating until we've graduated to validated at least once.
5515         if (!nai.everValidated) return;
5516         // For now only update icons for default connection.
5517         // TODO: Update WiFi and cellular icons separately. b/17237507
5518         if (!isDefaultNetwork(nai)) return;
5519 
5520         int newInetCondition = nai.lastValidated ? 100 : 0;
5521         // Don't repeat publish.
5522         if (newInetCondition == mDefaultInetConditionPublished) return;
5523 
5524         mDefaultInetConditionPublished = newInetCondition;
5525         sendInetConditionBroadcast(nai.networkInfo);
5526     }
5527 
notifyLockdownVpn(NetworkAgentInfo nai)5528     private void notifyLockdownVpn(NetworkAgentInfo nai) {
5529         synchronized (mVpns) {
5530             if (mLockdownTracker != null) {
5531                 if (nai != null && nai.isVPN()) {
5532                     mLockdownTracker.onVpnStateChanged(nai.networkInfo);
5533                 } else {
5534                     mLockdownTracker.onNetworkInfoChanged();
5535                 }
5536             }
5537         }
5538     }
5539 
updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo)5540     private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo) {
5541         final NetworkInfo.State state = newInfo.getState();
5542         NetworkInfo oldInfo = null;
5543         final int oldScore = networkAgent.getCurrentScore();
5544         synchronized (networkAgent) {
5545             oldInfo = networkAgent.networkInfo;
5546             networkAgent.networkInfo = newInfo;
5547         }
5548         notifyLockdownVpn(networkAgent);
5549 
5550         if (DBG) {
5551             log(networkAgent.name() + " EVENT_NETWORK_INFO_CHANGED, going from " +
5552                     (oldInfo == null ? "null" : oldInfo.getState()) +
5553                     " to " + state);
5554         }
5555 
5556         if (!networkAgent.created
5557                 && (state == NetworkInfo.State.CONNECTED
5558                 || (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) {
5559 
5560             // A network that has just connected has zero requests and is thus a foreground network.
5561             networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND);
5562 
5563             try {
5564                 // This should never fail.  Specifying an already in use NetID will cause failure.
5565                 if (networkAgent.isVPN()) {
5566                     mNetd.createVirtualNetwork(networkAgent.network.netId,
5567                             !networkAgent.linkProperties.getDnsServers().isEmpty(),
5568                             (networkAgent.networkMisc == null ||
5569                                 !networkAgent.networkMisc.allowBypass));
5570                 } else {
5571                     mNetd.createPhysicalNetwork(networkAgent.network.netId,
5572                             getNetworkPermission(networkAgent.networkCapabilities));
5573                 }
5574             } catch (Exception e) {
5575                 loge("Error creating network " + networkAgent.network.netId + ": "
5576                         + e.getMessage());
5577                 return;
5578             }
5579             networkAgent.created = true;
5580         }
5581 
5582         if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) {
5583             networkAgent.everConnected = true;
5584 
5585             handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig());
5586             updateLinkProperties(networkAgent, null);
5587             notifyIfacesChangedForNetworkStats();
5588 
5589             networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
5590             scheduleUnvalidatedPrompt(networkAgent);
5591 
5592             if (networkAgent.isVPN()) {
5593                 // Temporarily disable the default proxy (not global).
5594                 synchronized (mProxyLock) {
5595                     if (!mDefaultProxyDisabled) {
5596                         mDefaultProxyDisabled = true;
5597                         if (mGlobalProxy == null && mDefaultProxy != null) {
5598                             sendProxyBroadcast(null);
5599                         }
5600                     }
5601                 }
5602                 // TODO: support proxy per network.
5603             }
5604 
5605             // Whether a particular NetworkRequest listen should cause signal strength thresholds to
5606             // be communicated to a particular NetworkAgent depends only on the network's immutable,
5607             // capabilities, so it only needs to be done once on initial connect, not every time the
5608             // network's capabilities change. Note that we do this before rematching the network,
5609             // so we could decide to tear it down immediately afterwards. That's fine though - on
5610             // disconnection NetworkAgents should stop any signal strength monitoring they have been
5611             // doing.
5612             updateSignalStrengthThresholds(networkAgent, "CONNECT", null);
5613 
5614             // Consider network even though it is not yet validated.
5615             final long now = SystemClock.elapsedRealtime();
5616             rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP, now);
5617 
5618             // This has to happen after matching the requests, because callbacks are just requests.
5619             notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
5620         } else if (state == NetworkInfo.State.DISCONNECTED) {
5621             networkAgent.asyncChannel.disconnect();
5622             if (networkAgent.isVPN()) {
5623                 synchronized (mProxyLock) {
5624                     if (mDefaultProxyDisabled) {
5625                         mDefaultProxyDisabled = false;
5626                         if (mGlobalProxy == null && mDefaultProxy != null) {
5627                             sendProxyBroadcast(mDefaultProxy);
5628                         }
5629                     }
5630                 }
5631                 updateUids(networkAgent, networkAgent.networkCapabilities, null);
5632             }
5633             disconnectAndDestroyNetwork(networkAgent);
5634         } else if ((oldInfo != null && oldInfo.getState() == NetworkInfo.State.SUSPENDED) ||
5635                 state == NetworkInfo.State.SUSPENDED) {
5636             // going into or coming out of SUSPEND: rescore and notify
5637             if (networkAgent.getCurrentScore() != oldScore) {
5638                 rematchAllNetworksAndRequests(networkAgent, oldScore);
5639             }
5640             updateCapabilities(networkAgent.getCurrentScore(), networkAgent,
5641                     networkAgent.networkCapabilities);
5642             // TODO (b/73132094) : remove this call once the few users of onSuspended and
5643             // onResumed have been removed.
5644             notifyNetworkCallbacks(networkAgent, (state == NetworkInfo.State.SUSPENDED ?
5645                     ConnectivityManager.CALLBACK_SUSPENDED :
5646                     ConnectivityManager.CALLBACK_RESUMED));
5647             mLegacyTypeTracker.update(networkAgent);
5648         }
5649     }
5650 
updateNetworkScore(NetworkAgentInfo nai, int score)5651     private void updateNetworkScore(NetworkAgentInfo nai, int score) {
5652         if (VDBG) log("updateNetworkScore for " + nai.name() + " to " + score);
5653         if (score < 0) {
5654             loge("updateNetworkScore for " + nai.name() + " got a negative score (" + score +
5655                     ").  Bumping score to min of 0");
5656             score = 0;
5657         }
5658 
5659         final int oldScore = nai.getCurrentScore();
5660         nai.setCurrentScore(score);
5661 
5662         rematchAllNetworksAndRequests(nai, oldScore);
5663 
5664         sendUpdatedScoreToFactories(nai);
5665     }
5666 
5667     // Notify only this one new request of the current state. Transfer all the
5668     // current state by calling NetworkCapabilities and LinkProperties callbacks
5669     // so that callers can be guaranteed to have as close to atomicity in state
5670     // transfer as can be supported by this current API.
notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri)5671     protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) {
5672         mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri);
5673         if (nri.mPendingIntent != null) {
5674             sendPendingIntentForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE);
5675             // Attempt no subsequent state pushes where intents are involved.
5676             return;
5677         }
5678 
5679         callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, 0);
5680     }
5681 
sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type)5682     private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
5683         // The NetworkInfo we actually send out has no bearing on the real
5684         // state of affairs. For example, if the default connection is mobile,
5685         // and a request for HIPRI has just gone away, we need to pretend that
5686         // HIPRI has just disconnected. So we need to set the type to HIPRI and
5687         // the state to DISCONNECTED, even though the network is of type MOBILE
5688         // and is still connected.
5689         NetworkInfo info = new NetworkInfo(nai.networkInfo);
5690         info.setType(type);
5691         if (state != DetailedState.DISCONNECTED) {
5692             info.setDetailedState(state, null, info.getExtraInfo());
5693             sendConnectedBroadcast(info);
5694         } else {
5695             info.setDetailedState(state, info.getReason(), info.getExtraInfo());
5696             Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
5697             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
5698             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
5699             if (info.isFailover()) {
5700                 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
5701                 nai.networkInfo.setFailover(false);
5702             }
5703             if (info.getReason() != null) {
5704                 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
5705             }
5706             if (info.getExtraInfo() != null) {
5707                 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
5708             }
5709             NetworkAgentInfo newDefaultAgent = null;
5710             if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
5711                 newDefaultAgent = getDefaultNetwork();
5712                 if (newDefaultAgent != null) {
5713                     intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
5714                             newDefaultAgent.networkInfo);
5715                 } else {
5716                     intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
5717                 }
5718             }
5719             intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
5720                     mDefaultInetConditionPublished);
5721             sendStickyBroadcast(intent);
5722             if (newDefaultAgent != null) {
5723                 sendConnectedBroadcast(newDefaultAgent.networkInfo);
5724             }
5725         }
5726     }
5727 
notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1)5728     protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType, int arg1) {
5729         if (VDBG) {
5730             String notification = ConnectivityManager.getCallbackName(notifyType);
5731             log("notifyType " + notification + " for " + networkAgent.name());
5732         }
5733         for (int i = 0; i < networkAgent.numNetworkRequests(); i++) {
5734             NetworkRequest nr = networkAgent.requestAt(i);
5735             NetworkRequestInfo nri = mNetworkRequests.get(nr);
5736             if (VDBG) log(" sending notification for " + nr);
5737             // TODO: if we're in the middle of a rematch, can we send a CAP_CHANGED callback for
5738             // a network that no longer satisfies the listen?
5739             if (nri.mPendingIntent == null) {
5740                 callCallbackForRequest(nri, networkAgent, notifyType, arg1);
5741             } else {
5742                 sendPendingIntentForRequest(nri, networkAgent, notifyType);
5743             }
5744         }
5745     }
5746 
notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType)5747     protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
5748         notifyNetworkCallbacks(networkAgent, notifyType, 0);
5749     }
5750 
5751     /**
5752      * Returns the list of all interfaces that could be used by network traffic that does not
5753      * explicitly specify a network. This includes the default network, but also all VPNs that are
5754      * currently connected.
5755      *
5756      * Must be called on the handler thread.
5757      */
getDefaultNetworks()5758     private Network[] getDefaultNetworks() {
5759         ArrayList<Network> defaultNetworks = new ArrayList<>();
5760         NetworkAgentInfo defaultNetwork = getDefaultNetwork();
5761         for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
5762             if (nai.everConnected && (nai == defaultNetwork || nai.isVPN())) {
5763                 defaultNetworks.add(nai.network);
5764             }
5765         }
5766         return defaultNetworks.toArray(new Network[0]);
5767     }
5768 
5769     /**
5770      * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the
5771      * properties tracked by NetworkStatsService on an active iface has changed.
5772      */
notifyIfacesChangedForNetworkStats()5773     private void notifyIfacesChangedForNetworkStats() {
5774         try {
5775             mStatsService.forceUpdateIfaces(getDefaultNetworks());
5776         } catch (Exception ignored) {
5777         }
5778     }
5779 
5780     @Override
addVpnAddress(String address, int prefixLength)5781     public boolean addVpnAddress(String address, int prefixLength) {
5782         int user = UserHandle.getUserId(Binder.getCallingUid());
5783         synchronized (mVpns) {
5784             throwIfLockdownEnabled();
5785             return mVpns.get(user).addAddress(address, prefixLength);
5786         }
5787     }
5788 
5789     @Override
removeVpnAddress(String address, int prefixLength)5790     public boolean removeVpnAddress(String address, int prefixLength) {
5791         int user = UserHandle.getUserId(Binder.getCallingUid());
5792         synchronized (mVpns) {
5793             throwIfLockdownEnabled();
5794             return mVpns.get(user).removeAddress(address, prefixLength);
5795         }
5796     }
5797 
5798     @Override
setUnderlyingNetworksForVpn(Network[] networks)5799     public boolean setUnderlyingNetworksForVpn(Network[] networks) {
5800         int user = UserHandle.getUserId(Binder.getCallingUid());
5801         final boolean success;
5802         synchronized (mVpns) {
5803             throwIfLockdownEnabled();
5804             success = mVpns.get(user).setUnderlyingNetworks(networks);
5805         }
5806         if (success) {
5807             mHandler.post(() -> notifyIfacesChangedForNetworkStats());
5808         }
5809         return success;
5810     }
5811 
5812     @Override
getCaptivePortalServerUrl()5813     public String getCaptivePortalServerUrl() {
5814         enforceConnectivityInternalPermission();
5815         return NetworkMonitor.getCaptivePortalServerHttpUrl(mContext);
5816     }
5817 
5818     @Override
startNattKeepalive(Network network, int intervalSeconds, Messenger messenger, IBinder binder, String srcAddr, int srcPort, String dstAddr)5819     public void startNattKeepalive(Network network, int intervalSeconds, Messenger messenger,
5820             IBinder binder, String srcAddr, int srcPort, String dstAddr) {
5821         enforceKeepalivePermission();
5822         mKeepaliveTracker.startNattKeepalive(
5823                 getNetworkAgentInfoForNetwork(network),
5824                 intervalSeconds, messenger, binder,
5825                 srcAddr, srcPort, dstAddr, ConnectivityManager.PacketKeepalive.NATT_PORT);
5826     }
5827 
5828     @Override
stopKeepalive(Network network, int slot)5829     public void stopKeepalive(Network network, int slot) {
5830         mHandler.sendMessage(mHandler.obtainMessage(
5831                 NetworkAgent.CMD_STOP_PACKET_KEEPALIVE, slot, PacketKeepalive.SUCCESS, network));
5832     }
5833 
5834     @Override
factoryReset()5835     public void factoryReset() {
5836         enforceConnectivityInternalPermission();
5837 
5838         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
5839             return;
5840         }
5841 
5842         final int userId = UserHandle.getCallingUserId();
5843 
5844         // Turn airplane mode off
5845         setAirplaneMode(false);
5846 
5847         if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) {
5848             // Untether
5849             String pkgName = mContext.getOpPackageName();
5850             for (String tether : getTetheredIfaces()) {
5851                 untether(tether, pkgName);
5852             }
5853         }
5854 
5855         if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) {
5856             // Remove always-on package
5857             synchronized (mVpns) {
5858                 final String alwaysOnPackage = getAlwaysOnVpnPackage(userId);
5859                 if (alwaysOnPackage != null) {
5860                     setAlwaysOnVpnPackage(userId, null, false);
5861                     setVpnPackageAuthorization(alwaysOnPackage, userId, false);
5862                 }
5863 
5864                 // Turn Always-on VPN off
5865                 if (mLockdownEnabled && userId == UserHandle.USER_SYSTEM) {
5866                     final long ident = Binder.clearCallingIdentity();
5867                     try {
5868                         mKeyStore.delete(Credentials.LOCKDOWN_VPN);
5869                         mLockdownEnabled = false;
5870                         setLockdownTracker(null);
5871                     } finally {
5872                         Binder.restoreCallingIdentity(ident);
5873                     }
5874                 }
5875 
5876                 // Turn VPN off
5877                 VpnConfig vpnConfig = getVpnConfig(userId);
5878                 if (vpnConfig != null) {
5879                     if (vpnConfig.legacy) {
5880                         prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, userId);
5881                     } else {
5882                         // Prevent this app (packagename = vpnConfig.user) from initiating
5883                         // VPN connections in the future without user intervention.
5884                         setVpnPackageAuthorization(vpnConfig.user, userId, false);
5885 
5886                         prepareVpn(null, VpnConfig.LEGACY_VPN, userId);
5887                     }
5888                 }
5889             }
5890         }
5891 
5892         Settings.Global.putString(mContext.getContentResolver(),
5893                 Settings.Global.NETWORK_AVOID_BAD_WIFI, null);
5894     }
5895 
5896     @Override
getNetworkWatchlistConfigHash()5897     public byte[] getNetworkWatchlistConfigHash() {
5898         NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class);
5899         if (nwm == null) {
5900             loge("Unable to get NetworkWatchlistManager");
5901             return null;
5902         }
5903         // Redirect it to network watchlist service to access watchlist file and calculate hash.
5904         return nwm.getWatchlistConfigHash();
5905     }
5906 
5907     @VisibleForTesting
createNetworkMonitor(Context context, Handler handler, NetworkAgentInfo nai, NetworkRequest defaultRequest)5908     public NetworkMonitor createNetworkMonitor(Context context, Handler handler,
5909             NetworkAgentInfo nai, NetworkRequest defaultRequest) {
5910         return new NetworkMonitor(context, handler, nai, defaultRequest);
5911     }
5912 
5913     @VisibleForTesting
createMultinetworkPolicyTracker(Context c, Handler h, Runnable r)5914     MultinetworkPolicyTracker createMultinetworkPolicyTracker(Context c, Handler h, Runnable r) {
5915         return new MultinetworkPolicyTracker(c, h, r);
5916     }
5917 
5918     @VisibleForTesting
makeWakeupMessage(Context c, Handler h, String s, int cmd, Object obj)5919     public WakeupMessage makeWakeupMessage(Context c, Handler h, String s, int cmd, Object obj) {
5920         return new WakeupMessage(c, h, s, cmd, 0, 0, obj);
5921     }
5922 
5923     @VisibleForTesting
hasService(String name)5924     public boolean hasService(String name) {
5925         return ServiceManager.checkService(name) != null;
5926     }
5927 
5928     @VisibleForTesting
metricsLogger()5929     protected IpConnectivityMetrics.Logger metricsLogger() {
5930         return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class),
5931                 "no IpConnectivityMetrics service");
5932     }
5933 
logNetworkEvent(NetworkAgentInfo nai, int evtype)5934     private void logNetworkEvent(NetworkAgentInfo nai, int evtype) {
5935         int[] transports = nai.networkCapabilities.getTransportTypes();
5936         mMetricsLog.log(nai.network.netId, transports, new NetworkEvent(evtype));
5937     }
5938 
toBool(int encodedBoolean)5939     private static boolean toBool(int encodedBoolean) {
5940         return encodedBoolean != 0; // Only 0 means false.
5941     }
5942 
encodeBool(boolean b)5943     private static int encodeBool(boolean b) {
5944         return b ? 1 : 0;
5945     }
5946 
5947     @Override
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)5948     public void onShellCommand(FileDescriptor in, FileDescriptor out,
5949             FileDescriptor err, String[] args, ShellCallback callback,
5950             ResultReceiver resultReceiver) {
5951         (new ShellCmd()).exec(this, in, out, err, args, callback, resultReceiver);
5952     }
5953 
5954     private class ShellCmd extends ShellCommand {
5955 
5956         @Override
onCommand(String cmd)5957         public int onCommand(String cmd) {
5958             if (cmd == null) {
5959                 return handleDefaultCommands(cmd);
5960             }
5961             final PrintWriter pw = getOutPrintWriter();
5962             try {
5963                 switch (cmd) {
5964                     case "airplane-mode":
5965                         final String action = getNextArg();
5966                         if ("enable".equals(action)) {
5967                             setAirplaneMode(true);
5968                             return 0;
5969                         } else if ("disable".equals(action)) {
5970                             setAirplaneMode(false);
5971                             return 0;
5972                         } else if (action == null) {
5973                             final ContentResolver cr = mContext.getContentResolver();
5974                             final int enabled = Settings.Global.getInt(cr,
5975                                     Settings.Global.AIRPLANE_MODE_ON);
5976                             pw.println(enabled == 0 ? "disabled" : "enabled");
5977                             return 0;
5978                         } else {
5979                             onHelp();
5980                             return -1;
5981                         }
5982                     default:
5983                         return handleDefaultCommands(cmd);
5984                 }
5985             } catch (Exception e) {
5986                 pw.println(e);
5987             }
5988             return -1;
5989         }
5990 
5991         @Override
onHelp()5992         public void onHelp() {
5993             PrintWriter pw = getOutPrintWriter();
5994             pw.println("Connectivity service commands:");
5995             pw.println("  help");
5996             pw.println("    Print this help text.");
5997             pw.println("  airplane-mode [enable|disable]");
5998             pw.println("    Turn airplane mode on or off.");
5999             pw.println("  airplane-mode");
6000             pw.println("    Get airplane mode.");
6001         }
6002     }
6003 }
6004