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