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