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.MANAGE_NETWORK_POLICY;
     20 import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
     21 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
     22 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
     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.NetworkPolicyManager.RULE_ALLOW_ALL;
     28 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
     29 
     30 import android.app.AlarmManager;
     31 import android.app.Notification;
     32 import android.app.NotificationManager;
     33 import android.app.PendingIntent;
     34 import android.content.BroadcastReceiver;
     35 import android.content.ContentResolver;
     36 import android.content.Context;
     37 import android.content.Intent;
     38 import android.content.IntentFilter;
     39 import android.content.pm.PackageManager;
     40 import android.content.res.Configuration;
     41 import android.content.res.Resources;
     42 import android.database.ContentObserver;
     43 import android.net.ConnectivityManager;
     44 import android.net.IConnectivityManager;
     45 import android.net.INetworkManagementEventObserver;
     46 import android.net.INetworkPolicyListener;
     47 import android.net.INetworkPolicyManager;
     48 import android.net.INetworkStatsService;
     49 import android.net.LinkProperties;
     50 import android.net.LinkProperties.CompareResult;
     51 import android.net.MobileDataStateTracker;
     52 import android.net.Network;
     53 import android.net.NetworkAgent;
     54 import android.net.NetworkCapabilities;
     55 import android.net.NetworkConfig;
     56 import android.net.NetworkInfo;
     57 import android.net.NetworkInfo.DetailedState;
     58 import android.net.NetworkMisc;
     59 import android.net.NetworkQuotaInfo;
     60 import android.net.NetworkRequest;
     61 import android.net.NetworkState;
     62 import android.net.NetworkStateTracker;
     63 import android.net.NetworkUtils;
     64 import android.net.Proxy;
     65 import android.net.ProxyInfo;
     66 import android.net.RouteInfo;
     67 import android.net.SamplingDataTracker;
     68 import android.net.UidRange;
     69 import android.net.Uri;
     70 import android.os.Binder;
     71 import android.os.Bundle;
     72 import android.os.FileUtils;
     73 import android.os.Handler;
     74 import android.os.HandlerThread;
     75 import android.os.IBinder;
     76 import android.os.INetworkManagementService;
     77 import android.os.Looper;
     78 import android.os.Message;
     79 import android.os.Messenger;
     80 import android.os.ParcelFileDescriptor;
     81 import android.os.PowerManager;
     82 import android.os.Process;
     83 import android.os.RemoteException;
     84 import android.os.SystemClock;
     85 import android.os.SystemProperties;
     86 import android.os.UserHandle;
     87 import android.os.UserManager;
     88 import android.provider.Settings;
     89 import android.security.Credentials;
     90 import android.security.KeyStore;
     91 import android.telephony.TelephonyManager;
     92 import android.text.TextUtils;
     93 import android.util.Slog;
     94 import android.util.SparseArray;
     95 import android.util.SparseIntArray;
     96 import android.util.Xml;
     97 
     98 import com.android.internal.R;
     99 import com.android.internal.annotations.GuardedBy;
    100 import com.android.internal.app.IBatteryStats;
    101 import com.android.internal.net.LegacyVpnInfo;
    102 import com.android.internal.net.NetworkStatsFactory;
    103 import com.android.internal.net.VpnConfig;
    104 import com.android.internal.net.VpnProfile;
    105 import com.android.internal.telephony.DctConstants;
    106 import com.android.internal.util.AsyncChannel;
    107 import com.android.internal.util.IndentingPrintWriter;
    108 import com.android.internal.util.XmlUtils;
    109 import com.android.server.am.BatteryStatsService;
    110 import com.android.server.connectivity.DataConnectionStats;
    111 import com.android.server.connectivity.Nat464Xlat;
    112 import com.android.server.connectivity.NetworkAgentInfo;
    113 import com.android.server.connectivity.NetworkMonitor;
    114 import com.android.server.connectivity.PacManager;
    115 import com.android.server.connectivity.PermissionMonitor;
    116 import com.android.server.connectivity.Tethering;
    117 import com.android.server.connectivity.Vpn;
    118 import com.android.server.net.BaseNetworkObserver;
    119 import com.android.server.net.LockdownVpnTracker;
    120 import com.google.android.collect.Lists;
    121 import com.google.android.collect.Sets;
    122 
    123 import org.xmlpull.v1.XmlPullParser;
    124 import org.xmlpull.v1.XmlPullParserException;
    125 
    126 import java.io.File;
    127 import java.io.FileDescriptor;
    128 import java.io.FileNotFoundException;
    129 import java.io.FileReader;
    130 import java.io.IOException;
    131 import java.io.PrintWriter;
    132 import java.net.Inet4Address;
    133 import java.net.InetAddress;
    134 import java.net.UnknownHostException;
    135 import java.util.ArrayList;
    136 import java.util.Arrays;
    137 import java.util.Collection;
    138 import java.util.HashMap;
    139 import java.util.HashSet;
    140 import java.util.Iterator;
    141 import java.util.List;
    142 import java.util.Map;
    143 import java.util.Objects;
    144 import java.util.concurrent.atomic.AtomicInteger;
    145 
    146 /**
    147  * @hide
    148  */
    149 public class ConnectivityService extends IConnectivityManager.Stub
    150         implements PendingIntent.OnFinished {
    151     private static final String TAG = "ConnectivityService";
    152 
    153     private static final boolean DBG = true;
    154     private static final boolean VDBG = false;
    155 
    156     // network sampling debugging
    157     private static final boolean SAMPLE_DBG = false;
    158 
    159     private static final boolean LOGD_RULES = false;
    160 
    161     // TODO: create better separation between radio types and network types
    162 
    163     // how long to wait before switching back to a radio's default network
    164     private static final int RESTORE_DEFAULT_NETWORK_DELAY = 1 * 60 * 1000;
    165     // system property that can override the above value
    166     private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
    167             "android.telephony.apn-restore";
    168 
    169     // Default value if FAIL_FAST_TIME_MS is not set
    170     private static final int DEFAULT_FAIL_FAST_TIME_MS = 1 * 60 * 1000;
    171     // system property that can override DEFAULT_FAIL_FAST_TIME_MS
    172     private static final String FAIL_FAST_TIME_MS =
    173             "persist.radio.fail_fast_time_ms";
    174 
    175     private static final String ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED =
    176             "android.net.ConnectivityService.action.PKT_CNT_SAMPLE_INTERVAL_ELAPSED";
    177 
    178     private static final int SAMPLE_INTERVAL_ELAPSED_REQUEST_CODE = 0;
    179 
    180     // How long to delay to removal of a pending intent based request.
    181     // See Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS
    182     private final int mReleasePendingIntentDelayMs;
    183 
    184     private PendingIntent mSampleIntervalElapsedIntent;
    185 
    186     // Set network sampling interval at 12 minutes, this way, even if the timers get
    187     // aggregated, it will fire at around 15 minutes, which should allow us to
    188     // aggregate this timer with other timers (specially the socket keep alive timers)
    189     private static final int DEFAULT_SAMPLING_INTERVAL_IN_SECONDS = (SAMPLE_DBG ? 30 : 12 * 60);
    190 
    191     // start network sampling a minute after booting ...
    192     private static final int DEFAULT_START_SAMPLING_INTERVAL_IN_SECONDS = (SAMPLE_DBG ? 30 : 60);
    193 
    194     AlarmManager mAlarmManager;
    195 
    196     private Tethering mTethering;
    197 
    198     private final PermissionMonitor mPermissionMonitor;
    199 
    200     private KeyStore mKeyStore;
    201 
    202     @GuardedBy("mVpns")
    203     private final SparseArray<Vpn> mVpns = new SparseArray<Vpn>();
    204 
    205     private boolean mLockdownEnabled;
    206     private LockdownVpnTracker mLockdownTracker;
    207 
    208     /** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */
    209     private Object mRulesLock = new Object();
    210     /** Currently active network rules by UID. */
    211     private SparseIntArray mUidRules = new SparseIntArray();
    212     /** Set of ifaces that are costly. */
    213     private HashSet<String> mMeteredIfaces = Sets.newHashSet();
    214 
    215     /**
    216      * Sometimes we want to refer to the individual network state
    217      * trackers separately, and sometimes we just want to treat them
    218      * abstractly.
    219      */
    220     private NetworkStateTracker mNetTrackers[];
    221 
    222     private Context mContext;
    223     private int mNetworkPreference;
    224     // 0 is full bad, 100 is full good
    225     private int mDefaultInetConditionPublished = 0;
    226 
    227     private Object mDnsLock = new Object();
    228     private int mNumDnsEntries;
    229 
    230     private boolean mTestMode;
    231     private static ConnectivityService sServiceInstance;
    232 
    233     private INetworkManagementService mNetd;
    234     private INetworkStatsService mStatsService;
    235     private INetworkPolicyManager mPolicyManager;
    236 
    237     private String mCurrentTcpBufferSizes;
    238 
    239     private static final int ENABLED  = 1;
    240     private static final int DISABLED = 0;
    241 
    242     // Arguments to rematchNetworkAndRequests()
    243     private enum NascentState {
    244         // Indicates a network was just validated for the first time.  If the network is found to
    245         // be unwanted (i.e. not satisfy any NetworkRequests) it is torn down.
    246         JUST_VALIDATED,
    247         // Indicates a network was not validated for the first time immediately prior to this call.
    248         NOT_JUST_VALIDATED
    249     };
    250     private enum ReapUnvalidatedNetworks {
    251         // Tear down unvalidated networks that have no chance (i.e. even if validated) of becoming
    252         // the highest scoring network satisfying a NetworkRequest.  This should be passed when it's
    253         // known that there may be unvalidated networks that could potentially be reaped, and when
    254         // all networks have been rematched against all NetworkRequests.
    255         REAP,
    256         // Don't reap unvalidated networks.  This should be passed when it's known that there are
    257         // no unvalidated networks that could potentially be reaped, and when some networks have
    258         // not yet been rematched against all NetworkRequests.
    259         DONT_REAP
    260     };
    261 
    262     /**
    263      * used internally to change our mobile data enabled flag
    264      */
    265     private static final int EVENT_CHANGE_MOBILE_DATA_ENABLED = 2;
    266 
    267     /**
    268      * used internally to clear a wakelock when transitioning
    269      * from one net to another.  Clear happens when we get a new
    270      * network - EVENT_EXPIRE_NET_TRANSITION_WAKELOCK happens
    271      * after a timeout if no network is found (typically 1 min).
    272      */
    273     private static final int EVENT_CLEAR_NET_TRANSITION_WAKELOCK = 8;
    274 
    275     /**
    276      * used internally to reload global proxy settings
    277      */
    278     private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9;
    279 
    280     /**
    281      * used internally to set external dependency met/unmet
    282      * arg1 = ENABLED (met) or DISABLED (unmet)
    283      * arg2 = NetworkType
    284      */
    285     private static final int EVENT_SET_DEPENDENCY_MET = 10;
    286 
    287     /**
    288      * used internally to send a sticky broadcast delayed.
    289      */
    290     private static final int EVENT_SEND_STICKY_BROADCAST_INTENT = 11;
    291 
    292     /**
    293      * Used internally to disable fail fast of mobile data
    294      */
    295     private static final int EVENT_ENABLE_FAIL_FAST_MOBILE_DATA = 14;
    296 
    297     /**
    298      * used internally to indicate that data sampling interval is up
    299      */
    300     private static final int EVENT_SAMPLE_INTERVAL_ELAPSED = 15;
    301 
    302     /**
    303      * PAC manager has received new port.
    304      */
    305     private static final int EVENT_PROXY_HAS_CHANGED = 16;
    306 
    307     /**
    308      * used internally when registering NetworkFactories
    309      * obj = NetworkFactoryInfo
    310      */
    311     private static final int EVENT_REGISTER_NETWORK_FACTORY = 17;
    312 
    313     /**
    314      * used internally when registering NetworkAgents
    315      * obj = Messenger
    316      */
    317     private static final int EVENT_REGISTER_NETWORK_AGENT = 18;
    318 
    319     /**
    320      * used to add a network request
    321      * includes a NetworkRequestInfo
    322      */
    323     private static final int EVENT_REGISTER_NETWORK_REQUEST = 19;
    324 
    325     /**
    326      * indicates a timeout period is over - check if we had a network yet or not
    327      * and if not, call the timeout calback (but leave the request live until they
    328      * cancel it.
    329      * includes a NetworkRequestInfo
    330      */
    331     private static final int EVENT_TIMEOUT_NETWORK_REQUEST = 20;
    332 
    333     /**
    334      * used to add a network listener - no request
    335      * includes a NetworkRequestInfo
    336      */
    337     private static final int EVENT_REGISTER_NETWORK_LISTENER = 21;
    338 
    339     /**
    340      * used to remove a network request, either a listener or a real request
    341      * arg1 = UID of caller
    342      * obj  = NetworkRequest
    343      */
    344     private static final int EVENT_RELEASE_NETWORK_REQUEST = 22;
    345 
    346     /**
    347      * used internally when registering NetworkFactories
    348      * obj = Messenger
    349      */
    350     private static final int EVENT_UNREGISTER_NETWORK_FACTORY = 23;
    351 
    352     /**
    353      * used internally to expire a wakelock when transitioning
    354      * from one net to another.  Expire happens when we fail to find
    355      * a new network (typically after 1 minute) -
    356      * EVENT_CLEAR_NET_TRANSITION_WAKELOCK happens if we had found
    357      * a replacement network.
    358      */
    359     private static final int EVENT_EXPIRE_NET_TRANSITION_WAKELOCK = 24;
    360 
    361     /**
    362      * Used internally to indicate the system is ready.
    363      */
    364     private static final int EVENT_SYSTEM_READY = 25;
    365 
    366     /**
    367      * used to add a network request with a pending intent
    368      * includes a NetworkRequestInfo
    369      */
    370     private static final int EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT = 26;
    371 
    372     /**
    373      * used to remove a pending intent and its associated network request.
    374      * arg1 = UID of caller
    375      * obj  = PendingIntent
    376      */
    377     private static final int EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT = 27;
    378 
    379 
    380     /** Handler used for internal events. */
    381     final private InternalHandler mHandler;
    382     /** Handler used for incoming {@link NetworkStateTracker} events. */
    383     final private NetworkStateTrackerHandler mTrackerHandler;
    384 
    385     private boolean mSystemReady;
    386     private Intent mInitialBroadcast;
    387 
    388     private PowerManager.WakeLock mNetTransitionWakeLock;
    389     private String mNetTransitionWakeLockCausedBy = "";
    390     private int mNetTransitionWakeLockSerialNumber;
    391     private int mNetTransitionWakeLockTimeout;
    392     private final PowerManager.WakeLock mPendingIntentWakeLock;
    393 
    394     private InetAddress mDefaultDns;
    395 
    396     // used in DBG mode to track inet condition reports
    397     private static final int INET_CONDITION_LOG_MAX_SIZE = 15;
    398     private ArrayList mInetLog;
    399 
    400     // track the current default http proxy - tell the world if we get a new one (real change)
    401     private volatile ProxyInfo mDefaultProxy = null;
    402     private Object mProxyLock = new Object();
    403     private boolean mDefaultProxyDisabled = false;
    404 
    405     // track the global proxy.
    406     private ProxyInfo mGlobalProxy = null;
    407 
    408     private PacManager mPacManager = null;
    409 
    410     private SettingsObserver mSettingsObserver;
    411 
    412     private UserManager mUserManager;
    413 
    414     NetworkConfig[] mNetConfigs;
    415     int mNetworksDefined;
    416 
    417     // the set of network types that can only be enabled by system/sig apps
    418     List mProtectedNetworks;
    419 
    420     private DataConnectionStats mDataConnectionStats;
    421 
    422     private AtomicInteger mEnableFailFastMobileDataTag = new AtomicInteger(0);
    423 
    424     TelephonyManager mTelephonyManager;
    425 
    426     // sequence number for Networks; keep in sync with system/netd/NetworkController.cpp
    427     private final static int MIN_NET_ID = 100; // some reserved marks
    428     private final static int MAX_NET_ID = 65535;
    429     private int mNextNetId = MIN_NET_ID;
    430 
    431     // sequence number of NetworkRequests
    432     private int mNextNetworkRequestId = 1;
    433 
    434     /**
    435      * Implements support for the legacy "one network per network type" model.
    436      *
    437      * We used to have a static array of NetworkStateTrackers, one for each
    438      * network type, but that doesn't work any more now that we can have,
    439      * for example, more that one wifi network. This class stores all the
    440      * NetworkAgentInfo objects that support a given type, but the legacy
    441      * API will only see the first one.
    442      *
    443      * It serves two main purposes:
    444      *
    445      * 1. Provide information about "the network for a given type" (since this
    446      *    API only supports one).
    447      * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if
    448      *    the first network for a given type changes, or if the default network
    449      *    changes.
    450      */
    451     private class LegacyTypeTracker {
    452 
    453         private static final boolean DBG = true;
    454         private static final boolean VDBG = false;
    455         private static final String TAG = "CSLegacyTypeTracker";
    456 
    457         /**
    458          * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS).
    459          * Each list holds references to all NetworkAgentInfos that are used to
    460          * satisfy requests for that network type.
    461          *
    462          * This array is built out at startup such that an unsupported network
    463          * doesn't get an ArrayList instance, making this a tristate:
    464          * unsupported, supported but not active and active.
    465          *
    466          * The actual lists are populated when we scan the network types that
    467          * are supported on this device.
    468          */
    469         private ArrayList<NetworkAgentInfo> mTypeLists[];
    470 
    471         public LegacyTypeTracker() {
    472             mTypeLists = (ArrayList<NetworkAgentInfo>[])
    473                     new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
    474         }
    475 
    476         public void addSupportedType(int type) {
    477             if (mTypeLists[type] != null) {
    478                 throw new IllegalStateException(
    479                         "legacy list for type " + type + "already initialized");
    480             }
    481             mTypeLists[type] = new ArrayList<NetworkAgentInfo>();
    482         }
    483 
    484         public boolean isTypeSupported(int type) {
    485             return isNetworkTypeValid(type) && mTypeLists[type] != null;
    486         }
    487 
    488         public NetworkAgentInfo getNetworkForType(int type) {
    489             if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) {
    490                 return mTypeLists[type].get(0);
    491             } else {
    492                 return null;
    493             }
    494         }
    495 
    496         private void maybeLogBroadcast(NetworkAgentInfo nai, boolean connected, int type) {
    497             if (DBG) {
    498                 log("Sending " + (connected ? "connected" : "disconnected") +
    499                         " broadcast for type " + type + " " + nai.name() +
    500                         " isDefaultNetwork=" + isDefaultNetwork(nai));
    501             }
    502         }
    503 
    504         /** Adds the given network to the specified legacy type list. */
    505         public void add(int type, NetworkAgentInfo nai) {
    506             if (!isTypeSupported(type)) {
    507                 return;  // Invalid network type.
    508             }
    509             if (VDBG) log("Adding agent " + nai + " for legacy network type " + type);
    510 
    511             ArrayList<NetworkAgentInfo> list = mTypeLists[type];
    512             if (list.contains(nai)) {
    513                 loge("Attempting to register duplicate agent for type " + type + ": " + nai);
    514                 return;
    515             }
    516 
    517             list.add(nai);
    518 
    519             // Send a broadcast if this is the first network of its type or if it's the default.
    520             if (list.size() == 1 || isDefaultNetwork(nai)) {
    521                 maybeLogBroadcast(nai, true, type);
    522                 sendLegacyNetworkBroadcast(nai, true, type);
    523             }
    524         }
    525 
    526         /** Removes the given network from the specified legacy type list. */
    527         public void remove(int type, NetworkAgentInfo nai) {
    528             ArrayList<NetworkAgentInfo> list = mTypeLists[type];
    529             if (list == null || list.isEmpty()) {
    530                 return;
    531             }
    532 
    533             boolean wasFirstNetwork = list.get(0).equals(nai);
    534 
    535             if (!list.remove(nai)) {
    536                 return;
    537             }
    538 
    539             if (wasFirstNetwork || isDefaultNetwork(nai)) {
    540                 maybeLogBroadcast(nai, false, type);
    541                 sendLegacyNetworkBroadcast(nai, false, type);
    542             }
    543 
    544             if (!list.isEmpty() && wasFirstNetwork) {
    545                 if (DBG) log("Other network available for type " + type +
    546                               ", sending connected broadcast");
    547                 maybeLogBroadcast(list.get(0), false, type);
    548                 sendLegacyNetworkBroadcast(list.get(0), false, type);
    549             }
    550         }
    551 
    552         /** Removes the given network from all legacy type lists. */
    553         public void remove(NetworkAgentInfo nai) {
    554             if (VDBG) log("Removing agent " + nai);
    555             for (int type = 0; type < mTypeLists.length; type++) {
    556                 remove(type, nai);
    557             }
    558         }
    559 
    560         private String naiToString(NetworkAgentInfo nai) {
    561             String name = (nai != null) ? nai.name() : "null";
    562             String state = (nai.networkInfo != null) ?
    563                     nai.networkInfo.getState() + "/" + nai.networkInfo.getDetailedState() :
    564                     "???/???";
    565             return name + " " + state;
    566         }
    567 
    568         public void dump(IndentingPrintWriter pw) {
    569             for (int type = 0; type < mTypeLists.length; type++) {
    570                 if (mTypeLists[type] == null) continue;
    571                 pw.print(type + " ");
    572                 pw.increaseIndent();
    573                 if (mTypeLists[type].size() == 0) pw.println("none");
    574                 for (NetworkAgentInfo nai : mTypeLists[type]) {
    575                     pw.println(naiToString(nai));
    576                 }
    577                 pw.decreaseIndent();
    578             }
    579         }
    580 
    581         // This class needs its own log method because it has a different TAG.
    582         private void log(String s) {
    583             Slog.d(TAG, s);
    584         }
    585 
    586     }
    587     private LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker();
    588 
    589     public ConnectivityService(Context context, INetworkManagementService netManager,
    590             INetworkStatsService statsService, INetworkPolicyManager policyManager) {
    591         if (DBG) log("ConnectivityService starting up");
    592 
    593         NetworkCapabilities netCap = new NetworkCapabilities();
    594         netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
    595         netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
    596         mDefaultRequest = new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId());
    597         NetworkRequestInfo nri = new NetworkRequestInfo(null, mDefaultRequest, new Binder(),
    598                 NetworkRequestInfo.REQUEST);
    599         mNetworkRequests.put(mDefaultRequest, nri);
    600 
    601         HandlerThread handlerThread = new HandlerThread("ConnectivityServiceThread");
    602         handlerThread.start();
    603         mHandler = new InternalHandler(handlerThread.getLooper());
    604         mTrackerHandler = new NetworkStateTrackerHandler(handlerThread.getLooper());
    605 
    606         // setup our unique device name
    607         if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) {
    608             String id = Settings.Secure.getString(context.getContentResolver(),
    609                     Settings.Secure.ANDROID_ID);
    610             if (id != null && id.length() > 0) {
    611                 String name = new String("android-").concat(id);
    612                 SystemProperties.set("net.hostname", name);
    613             }
    614         }
    615 
    616         // read our default dns server ip
    617         String dns = Settings.Global.getString(context.getContentResolver(),
    618                 Settings.Global.DEFAULT_DNS_SERVER);
    619         if (dns == null || dns.length() == 0) {
    620             dns = context.getResources().getString(
    621                     com.android.internal.R.string.config_default_dns_server);
    622         }
    623         try {
    624             mDefaultDns = NetworkUtils.numericToInetAddress(dns);
    625         } catch (IllegalArgumentException e) {
    626             loge("Error setting defaultDns using " + dns);
    627         }
    628 
    629         mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(),
    630                 Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000);
    631 
    632         mContext = checkNotNull(context, "missing Context");
    633         mNetd = checkNotNull(netManager, "missing INetworkManagementService");
    634         mStatsService = checkNotNull(statsService, "missing INetworkStatsService");
    635         mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
    636         mKeyStore = KeyStore.getInstance();
    637         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
    638 
    639         try {
    640             mPolicyManager.registerListener(mPolicyListener);
    641         } catch (RemoteException e) {
    642             // ouch, no rules updates means some processes may never get network
    643             loge("unable to register INetworkPolicyListener" + e.toString());
    644         }
    645 
    646         final PowerManager powerManager = (PowerManager) context.getSystemService(
    647                 Context.POWER_SERVICE);
    648         mNetTransitionWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
    649         mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
    650                 com.android.internal.R.integer.config_networkTransitionTimeout);
    651         mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
    652 
    653         mNetTrackers = new NetworkStateTracker[
    654                 ConnectivityManager.MAX_NETWORK_TYPE+1];
    655 
    656         mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
    657 
    658         // TODO: What is the "correct" way to do determine if this is a wifi only device?
    659         boolean wifiOnly = SystemProperties.getBoolean("ro.radio.noril", false);
    660         log("wifiOnly=" + wifiOnly);
    661         String[] naStrings = context.getResources().getStringArray(
    662                 com.android.internal.R.array.networkAttributes);
    663         for (String naString : naStrings) {
    664             try {
    665                 NetworkConfig n = new NetworkConfig(naString);
    666                 if (VDBG) log("naString=" + naString + " config=" + n);
    667                 if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) {
    668                     loge("Error in networkAttributes - ignoring attempt to define type " +
    669                             n.type);
    670                     continue;
    671                 }
    672                 if (wifiOnly && ConnectivityManager.isNetworkTypeMobile(n.type)) {
    673                     log("networkAttributes - ignoring mobile as this dev is wifiOnly " +
    674                             n.type);
    675                     continue;
    676                 }
    677                 if (mNetConfigs[n.type] != null) {
    678                     loge("Error in networkAttributes - ignoring attempt to redefine type " +
    679                             n.type);
    680                     continue;
    681                 }
    682                 mLegacyTypeTracker.addSupportedType(n.type);
    683 
    684                 mNetConfigs[n.type] = n;
    685                 mNetworksDefined++;
    686             } catch(Exception e) {
    687                 // ignore it - leave the entry null
    688             }
    689         }
    690 
    691         // Forcibly add TYPE_VPN as a supported type, if it has not already been added via config.
    692         if (mNetConfigs[TYPE_VPN] == null) {
    693             // mNetConfigs is used only for "restore time", which isn't applicable to VPNs, so we
    694             // don't need to add TYPE_VPN to mNetConfigs.
    695             mLegacyTypeTracker.addSupportedType(TYPE_VPN);
    696             mNetworksDefined++;  // used only in the log() statement below.
    697         }
    698 
    699         if (VDBG) log("mNetworksDefined=" + mNetworksDefined);
    700 
    701         mProtectedNetworks = new ArrayList<Integer>();
    702         int[] protectedNetworks = context.getResources().getIntArray(
    703                 com.android.internal.R.array.config_protectedNetworks);
    704         for (int p : protectedNetworks) {
    705             if ((mNetConfigs[p] != null) && (mProtectedNetworks.contains(p) == false)) {
    706                 mProtectedNetworks.add(p);
    707             } else {
    708                 if (DBG) loge("Ignoring protectedNetwork " + p);
    709             }
    710         }
    711 
    712         mTestMode = SystemProperties.get("cm.test.mode").equals("true")
    713                 && SystemProperties.get("ro.build.type").equals("eng");
    714 
    715         mTethering = new Tethering(mContext, mNetd, statsService, mHandler.getLooper());
    716 
    717         mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
    718 
    719         //set up the listener for user state for creating user VPNs
    720         IntentFilter intentFilter = new IntentFilter();
    721         intentFilter.addAction(Intent.ACTION_USER_STARTING);
    722         intentFilter.addAction(Intent.ACTION_USER_STOPPING);
    723         mContext.registerReceiverAsUser(
    724                 mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);
    725 
    726         try {
    727             mNetd.registerObserver(mTethering);
    728             mNetd.registerObserver(mDataActivityObserver);
    729         } catch (RemoteException e) {
    730             loge("Error registering observer :" + e);
    731         }
    732 
    733         if (DBG) {
    734             mInetLog = new ArrayList();
    735         }
    736 
    737         mSettingsObserver = new SettingsObserver(mHandler, EVENT_APPLY_GLOBAL_HTTP_PROXY);
    738         mSettingsObserver.observe(mContext);
    739 
    740         mDataConnectionStats = new DataConnectionStats(mContext);
    741         mDataConnectionStats.startMonitoring();
    742 
    743         mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
    744 
    745         IntentFilter filter = new IntentFilter();
    746         filter.addAction(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED);
    747         mContext.registerReceiver(
    748                 new BroadcastReceiver() {
    749                     @Override
    750                     public void onReceive(Context context, Intent intent) {
    751                         String action = intent.getAction();
    752                         if (action.equals(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED)) {
    753                             mHandler.sendMessage(mHandler.obtainMessage
    754                                     (EVENT_SAMPLE_INTERVAL_ELAPSED));
    755                         }
    756                     }
    757                 },
    758                 new IntentFilter(filter));
    759 
    760         mPacManager = new PacManager(mContext, mHandler, EVENT_PROXY_HAS_CHANGED);
    761 
    762         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
    763     }
    764 
    765     private synchronized int nextNetworkRequestId() {
    766         return mNextNetworkRequestId++;
    767     }
    768 
    769     private void assignNextNetId(NetworkAgentInfo nai) {
    770         synchronized (mNetworkForNetId) {
    771             for (int i = MIN_NET_ID; i <= MAX_NET_ID; i++) {
    772                 int netId = mNextNetId;
    773                 if (++mNextNetId > MAX_NET_ID) mNextNetId = MIN_NET_ID;
    774                 // Make sure NetID unused.  http://b/16815182
    775                 if (mNetworkForNetId.get(netId) == null) {
    776                     nai.network = new Network(netId);
    777                     mNetworkForNetId.put(netId, nai);
    778                     return;
    779                 }
    780             }
    781         }
    782         throw new IllegalStateException("No free netIds");
    783     }
    784 
    785     private boolean teardown(NetworkStateTracker netTracker) {
    786         if (netTracker.teardown()) {
    787             netTracker.setTeardownRequested(true);
    788             return true;
    789         } else {
    790             return false;
    791         }
    792     }
    793 
    794     private NetworkState getFilteredNetworkState(int networkType, int uid) {
    795         NetworkInfo info = null;
    796         LinkProperties lp = null;
    797         NetworkCapabilities nc = null;
    798         Network network = null;
    799         String subscriberId = null;
    800 
    801         if (mLegacyTypeTracker.isTypeSupported(networkType)) {
    802             NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
    803             if (nai != null) {
    804                 synchronized (nai) {
    805                     info = new NetworkInfo(nai.networkInfo);
    806                     lp = new LinkProperties(nai.linkProperties);
    807                     nc = new NetworkCapabilities(nai.networkCapabilities);
    808                     network = new Network(nai.network);
    809                     subscriberId = (nai.networkMisc != null) ? nai.networkMisc.subscriberId : null;
    810                 }
    811                 info.setType(networkType);
    812             } else {
    813                 info = new NetworkInfo(networkType, 0, getNetworkTypeName(networkType), "");
    814                 info.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
    815                 info.setIsAvailable(true);
    816                 lp = new LinkProperties();
    817                 nc = new NetworkCapabilities();
    818                 network = null;
    819             }
    820             info = getFilteredNetworkInfo(info, lp, uid);
    821         }
    822 
    823         return new NetworkState(info, lp, nc, network, subscriberId, null);
    824     }
    825 
    826     private NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
    827         if (network == null) {
    828             return null;
    829         }
    830         synchronized (mNetworkForNetId) {
    831             return mNetworkForNetId.get(network.netId);
    832         }
    833     };
    834 
    835     private Network[] getVpnUnderlyingNetworks(int uid) {
    836         if (!mLockdownEnabled) {
    837             int user = UserHandle.getUserId(uid);
    838             synchronized (mVpns) {
    839                 Vpn vpn = mVpns.get(user);
    840                 if (vpn != null && vpn.appliesToUid(uid)) {
    841                     return vpn.getUnderlyingNetworks();
    842                 }
    843             }
    844         }
    845         return null;
    846     }
    847 
    848     private NetworkState getUnfilteredActiveNetworkState(int uid) {
    849         NetworkInfo info = null;
    850         LinkProperties lp = null;
    851         NetworkCapabilities nc = null;
    852         Network network = null;
    853         String subscriberId = null;
    854 
    855         NetworkAgentInfo nai = mNetworkForRequestId.get(mDefaultRequest.requestId);
    856 
    857         final Network[] networks = getVpnUnderlyingNetworks(uid);
    858         if (networks != null) {
    859             // getUnderlyingNetworks() returns:
    860             // null => there was no VPN, or the VPN didn't specify anything, so we use the default.
    861             // empty array => the VPN explicitly said "no default network".
    862             // non-empty array => the VPN specified one or more default networks; we use the
    863             //                    first one.
    864             if (networks.length > 0) {
    865                 nai = getNetworkAgentInfoForNetwork(networks[0]);
    866             } else {
    867                 nai = null;
    868             }
    869         }
    870 
    871         if (nai != null) {
    872             synchronized (nai) {
    873                 info = new NetworkInfo(nai.networkInfo);
    874                 lp = new LinkProperties(nai.linkProperties);
    875                 nc = new NetworkCapabilities(nai.networkCapabilities);
    876                 network = new Network(nai.network);
    877                 subscriberId = (nai.networkMisc != null) ? nai.networkMisc.subscriberId : null;
    878             }
    879         }
    880 
    881         return new NetworkState(info, lp, nc, network, subscriberId, null);
    882     }
    883 
    884     /**
    885      * Check if UID should be blocked from using the network with the given LinkProperties.
    886      */
    887     private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid) {
    888         final boolean networkCostly;
    889         final int uidRules;
    890 
    891         final String iface = (lp == null ? "" : lp.getInterfaceName());
    892         synchronized (mRulesLock) {
    893             networkCostly = mMeteredIfaces.contains(iface);
    894             uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
    895         }
    896 
    897         if (networkCostly && (uidRules & RULE_REJECT_METERED) != 0) {
    898             return true;
    899         }
    900 
    901         // no restrictive rules; network is visible
    902         return false;
    903     }
    904 
    905     /**
    906      * Return a filtered {@link NetworkInfo}, potentially marked
    907      * {@link DetailedState#BLOCKED} based on
    908      * {@link #isNetworkWithLinkPropertiesBlocked}.
    909      */
    910     private NetworkInfo getFilteredNetworkInfo(NetworkInfo info, LinkProperties lp, int uid) {
    911         if (info != null && isNetworkWithLinkPropertiesBlocked(lp, uid)) {
    912             // network is blocked; clone and override state
    913             info = new NetworkInfo(info);
    914             info.setDetailedState(DetailedState.BLOCKED, null, null);
    915             if (DBG) {
    916                 log("returning Blocked NetworkInfo for ifname=" +
    917                         lp.getInterfaceName() + ", uid=" + uid);
    918             }
    919         }
    920         if (info != null && mLockdownTracker != null) {
    921             info = mLockdownTracker.augmentNetworkInfo(info);
    922             if (DBG) log("returning Locked NetworkInfo");
    923         }
    924         return info;
    925     }
    926 
    927     /**
    928      * Return NetworkInfo for the active (i.e., connected) network interface.
    929      * It is assumed that at most one network is active at a time. If more
    930      * than one is active, it is indeterminate which will be returned.
    931      * @return the info for the active network, or {@code null} if none is
    932      * active
    933      */
    934     @Override
    935     public NetworkInfo getActiveNetworkInfo() {
    936         enforceAccessPermission();
    937         final int uid = Binder.getCallingUid();
    938         NetworkState state = getUnfilteredActiveNetworkState(uid);
    939         return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
    940     }
    941 
    942     /**
    943      * Find the first Provisioning network.
    944      *
    945      * @return NetworkInfo or null if none.
    946      */
    947     private NetworkInfo getProvisioningNetworkInfo() {
    948         enforceAccessPermission();
    949 
    950         // Find the first Provisioning Network
    951         NetworkInfo provNi = null;
    952         for (NetworkInfo ni : getAllNetworkInfo()) {
    953             if (ni.isConnectedToProvisioningNetwork()) {
    954                 provNi = ni;
    955                 break;
    956             }
    957         }
    958         if (DBG) log("getProvisioningNetworkInfo: X provNi=" + provNi);
    959         return provNi;
    960     }
    961 
    962     /**
    963      * Find the first Provisioning network or the ActiveDefaultNetwork
    964      * if there is no Provisioning network
    965      *
    966      * @return NetworkInfo or null if none.
    967      */
    968     @Override
    969     public NetworkInfo getProvisioningOrActiveNetworkInfo() {
    970         enforceAccessPermission();
    971 
    972         NetworkInfo provNi = getProvisioningNetworkInfo();
    973         if (provNi == null) {
    974             provNi = getActiveNetworkInfo();
    975         }
    976         if (DBG) log("getProvisioningOrActiveNetworkInfo: X provNi=" + provNi);
    977         return provNi;
    978     }
    979 
    980     public NetworkInfo getActiveNetworkInfoUnfiltered() {
    981         enforceAccessPermission();
    982         final int uid = Binder.getCallingUid();
    983         NetworkState state = getUnfilteredActiveNetworkState(uid);
    984         return state.networkInfo;
    985     }
    986 
    987     @Override
    988     public NetworkInfo getActiveNetworkInfoForUid(int uid) {
    989         enforceConnectivityInternalPermission();
    990         NetworkState state = getUnfilteredActiveNetworkState(uid);
    991         return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
    992     }
    993 
    994     @Override
    995     public NetworkInfo getNetworkInfo(int networkType) {
    996         enforceAccessPermission();
    997         final int uid = Binder.getCallingUid();
    998         if (getVpnUnderlyingNetworks(uid) != null) {
    999             // A VPN is active, so we may need to return one of its underlying networks. This
   1000             // information is not available in LegacyTypeTracker, so we have to get it from
   1001             // getUnfilteredActiveNetworkState.
   1002             NetworkState state = getUnfilteredActiveNetworkState(uid);
   1003             if (state.networkInfo != null && state.networkInfo.getType() == networkType) {
   1004                 return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
   1005             }
   1006         }
   1007         NetworkState state = getFilteredNetworkState(networkType, uid);
   1008         return state.networkInfo;
   1009     }
   1010 
   1011     @Override
   1012     public NetworkInfo getNetworkInfoForNetwork(Network network) {
   1013         enforceAccessPermission();
   1014         final int uid = Binder.getCallingUid();
   1015         NetworkInfo info = null;
   1016         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
   1017         if (nai != null) {
   1018             synchronized (nai) {
   1019                 info = new NetworkInfo(nai.networkInfo);
   1020                 info = getFilteredNetworkInfo(info, nai.linkProperties, uid);
   1021             }
   1022         }
   1023         return info;
   1024     }
   1025 
   1026     @Override
   1027     public NetworkInfo[] getAllNetworkInfo() {
   1028         enforceAccessPermission();
   1029         final ArrayList<NetworkInfo> result = Lists.newArrayList();
   1030         for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE;
   1031                 networkType++) {
   1032             NetworkInfo info = getNetworkInfo(networkType);
   1033             if (info != null) {
   1034                 result.add(info);
   1035             }
   1036         }
   1037         return result.toArray(new NetworkInfo[result.size()]);
   1038     }
   1039 
   1040     @Override
   1041     public Network getNetworkForType(int networkType) {
   1042         enforceAccessPermission();
   1043         final int uid = Binder.getCallingUid();
   1044         NetworkState state = getFilteredNetworkState(networkType, uid);
   1045         if (!isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid)) {
   1046             return state.network;
   1047         }
   1048         return null;
   1049     }
   1050 
   1051     @Override
   1052     public Network[] getAllNetworks() {
   1053         enforceAccessPermission();
   1054         final ArrayList<Network> result = new ArrayList();
   1055         synchronized (mNetworkForNetId) {
   1056             for (int i = 0; i < mNetworkForNetId.size(); i++) {
   1057                 result.add(new Network(mNetworkForNetId.valueAt(i).network));
   1058             }
   1059         }
   1060         return result.toArray(new Network[result.size()]);
   1061     }
   1062 
   1063     private NetworkCapabilities getNetworkCapabilitiesAndValidation(NetworkAgentInfo nai) {
   1064         if (nai != null) {
   1065             synchronized (nai) {
   1066                 if (nai.created) {
   1067                     NetworkCapabilities nc = new NetworkCapabilities(nai.networkCapabilities);
   1068                     if (nai.lastValidated) {
   1069                         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
   1070                     } else {
   1071                         nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
   1072                     }
   1073                     return nc;
   1074                 }
   1075             }
   1076         }
   1077         return null;
   1078     }
   1079 
   1080     @Override
   1081     public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
   1082         // The basic principle is: if an app's traffic could possibly go over a
   1083         // network, without the app doing anything multinetwork-specific,
   1084         // (hence, by "default"), then include that network's capabilities in
   1085         // the array.
   1086         //
   1087         // In the normal case, app traffic only goes over the system's default
   1088         // network connection, so that's the only network returned.
   1089         //
   1090         // With a VPN in force, some app traffic may go into the VPN, and thus
   1091         // over whatever underlying networks the VPN specifies, while other app
   1092         // traffic may go over the system default network (e.g.: a split-tunnel
   1093         // VPN, or an app disallowed by the VPN), so the set of networks
   1094         // returned includes the VPN's underlying networks and the system
   1095         // default.
   1096         enforceAccessPermission();
   1097 
   1098         HashMap<Network, NetworkCapabilities> result = new HashMap<Network, NetworkCapabilities>();
   1099 
   1100         NetworkAgentInfo nai = getDefaultNetwork();
   1101         NetworkCapabilities nc = getNetworkCapabilitiesAndValidation(getDefaultNetwork());
   1102         if (nc != null) {
   1103             result.put(nai.network, nc);
   1104         }
   1105 
   1106         if (!mLockdownEnabled) {
   1107             synchronized (mVpns) {
   1108                 Vpn vpn = mVpns.get(userId);
   1109                 if (vpn != null) {
   1110                     Network[] networks = vpn.getUnderlyingNetworks();
   1111                     if (networks != null) {
   1112                         for (Network network : networks) {
   1113                             nai = getNetworkAgentInfoForNetwork(network);
   1114                             nc = getNetworkCapabilitiesAndValidation(nai);
   1115                             if (nc != null) {
   1116                                 result.put(nai.network, nc);
   1117                             }
   1118                         }
   1119                     }
   1120                 }
   1121             }
   1122         }
   1123 
   1124         NetworkCapabilities[] out = new NetworkCapabilities[result.size()];
   1125         out = result.values().toArray(out);
   1126         return out;
   1127     }
   1128 
   1129     @Override
   1130     public boolean isNetworkSupported(int networkType) {
   1131         enforceAccessPermission();
   1132         return mLegacyTypeTracker.isTypeSupported(networkType);
   1133     }
   1134 
   1135     /**
   1136      * Return LinkProperties for the active (i.e., connected) default
   1137      * network interface.  It is assumed that at most one default network
   1138      * is active at a time. If more than one is active, it is indeterminate
   1139      * which will be returned.
   1140      * @return the ip properties for the active network, or {@code null} if
   1141      * none is active
   1142      */
   1143     @Override
   1144     public LinkProperties getActiveLinkProperties() {
   1145         enforceAccessPermission();
   1146         final int uid = Binder.getCallingUid();
   1147         NetworkState state = getUnfilteredActiveNetworkState(uid);
   1148         return state.linkProperties;
   1149     }
   1150 
   1151     @Override
   1152     public LinkProperties getLinkPropertiesForType(int networkType) {
   1153         enforceAccessPermission();
   1154         NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
   1155         if (nai != null) {
   1156             synchronized (nai) {
   1157                 return new LinkProperties(nai.linkProperties);
   1158             }
   1159         }
   1160         return null;
   1161     }
   1162 
   1163     // TODO - this should be ALL networks
   1164     @Override
   1165     public LinkProperties getLinkProperties(Network network) {
   1166         enforceAccessPermission();
   1167         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
   1168         if (nai != null) {
   1169             synchronized (nai) {
   1170                 return new LinkProperties(nai.linkProperties);
   1171             }
   1172         }
   1173         return null;
   1174     }
   1175 
   1176     @Override
   1177     public NetworkCapabilities getNetworkCapabilities(Network network) {
   1178         enforceAccessPermission();
   1179         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
   1180         if (nai != null) {
   1181             synchronized (nai) {
   1182                 return new NetworkCapabilities(nai.networkCapabilities);
   1183             }
   1184         }
   1185         return null;
   1186     }
   1187 
   1188     @Override
   1189     public NetworkState[] getAllNetworkState() {
   1190         // Require internal since we're handing out IMSI details
   1191         enforceConnectivityInternalPermission();
   1192 
   1193         final ArrayList<NetworkState> result = Lists.newArrayList();
   1194         for (Network network : getAllNetworks()) {
   1195             final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
   1196             if (nai != null) {
   1197                 synchronized (nai) {
   1198                     final String subscriberId = (nai.networkMisc != null)
   1199                             ? nai.networkMisc.subscriberId : null;
   1200                     result.add(new NetworkState(nai.networkInfo, nai.linkProperties,
   1201                             nai.networkCapabilities, network, subscriberId, null));
   1202                 }
   1203             }
   1204         }
   1205         return result.toArray(new NetworkState[result.size()]);
   1206     }
   1207 
   1208     @Override
   1209     public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
   1210         enforceAccessPermission();
   1211         final int uid = Binder.getCallingUid();
   1212         final long token = Binder.clearCallingIdentity();
   1213         try {
   1214             final NetworkState state = getUnfilteredActiveNetworkState(uid);
   1215             if (state.networkInfo != null) {
   1216                 try {
   1217                     return mPolicyManager.getNetworkQuotaInfo(state);
   1218                 } catch (RemoteException e) {
   1219                 }
   1220             }
   1221             return null;
   1222         } finally {
   1223             Binder.restoreCallingIdentity(token);
   1224         }
   1225     }
   1226 
   1227     @Override
   1228     public boolean isActiveNetworkMetered() {
   1229         enforceAccessPermission();
   1230         final int uid = Binder.getCallingUid();
   1231         final long token = Binder.clearCallingIdentity();
   1232         try {
   1233             return isActiveNetworkMeteredUnchecked(uid);
   1234         } finally {
   1235             Binder.restoreCallingIdentity(token);
   1236         }
   1237     }
   1238 
   1239     private boolean isActiveNetworkMeteredUnchecked(int uid) {
   1240         final NetworkState state = getUnfilteredActiveNetworkState(uid);
   1241         if (state.networkInfo != null) {
   1242             try {
   1243                 return mPolicyManager.isNetworkMetered(state);
   1244             } catch (RemoteException e) {
   1245             }
   1246         }
   1247         return false;
   1248     }
   1249 
   1250     private INetworkManagementEventObserver mDataActivityObserver = new BaseNetworkObserver() {
   1251         @Override
   1252         public void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos) {
   1253             int deviceType = Integer.parseInt(label);
   1254             sendDataActivityBroadcast(deviceType, active, tsNanos);
   1255         }
   1256     };
   1257 
   1258     /**
   1259      * Ensure that a network route exists to deliver traffic to the specified
   1260      * host via the specified network interface.
   1261      * @param networkType the type of the network over which traffic to the
   1262      * specified host is to be routed
   1263      * @param hostAddress the IP address of the host to which the route is
   1264      * desired
   1265      * @return {@code true} on success, {@code false} on failure
   1266      */
   1267     public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
   1268         enforceChangePermission();
   1269         if (mProtectedNetworks.contains(networkType)) {
   1270             enforceConnectivityInternalPermission();
   1271         }
   1272 
   1273         InetAddress addr;
   1274         try {
   1275             addr = InetAddress.getByAddress(hostAddress);
   1276         } catch (UnknownHostException e) {
   1277             if (DBG) log("requestRouteToHostAddress got " + e.toString());
   1278             return false;
   1279         }
   1280 
   1281         if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
   1282             if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
   1283             return false;
   1284         }
   1285 
   1286         NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
   1287         if (nai == null) {
   1288             if (mLegacyTypeTracker.isTypeSupported(networkType) == false) {
   1289                 if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType);
   1290             } else {
   1291                 if (DBG) log("requestRouteToHostAddress on down network: " + networkType);
   1292             }
   1293             return false;
   1294         }
   1295 
   1296         DetailedState netState;
   1297         synchronized (nai) {
   1298             netState = nai.networkInfo.getDetailedState();
   1299         }
   1300 
   1301         if (netState != DetailedState.CONNECTED && netState != DetailedState.CAPTIVE_PORTAL_CHECK) {
   1302             if (VDBG) {
   1303                 log("requestRouteToHostAddress on down network "
   1304                         + "(" + networkType + ") - dropped"
   1305                         + " netState=" + netState);
   1306             }
   1307             return false;
   1308         }
   1309 
   1310         final int uid = Binder.getCallingUid();
   1311         final long token = Binder.clearCallingIdentity();
   1312         try {
   1313             LinkProperties lp;
   1314             int netId;
   1315             synchronized (nai) {
   1316                 lp = nai.linkProperties;
   1317                 netId = nai.network.netId;
   1318             }
   1319             boolean ok = addLegacyRouteToHost(lp, addr, netId, uid);
   1320             if (DBG) log("requestRouteToHostAddress ok=" + ok);
   1321             return ok;
   1322         } finally {
   1323             Binder.restoreCallingIdentity(token);
   1324         }
   1325     }
   1326 
   1327     private boolean addLegacyRouteToHost(LinkProperties lp, InetAddress addr, int netId, int uid) {
   1328         RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr);
   1329         if (bestRoute == null) {
   1330             bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName());
   1331         } else {
   1332             String iface = bestRoute.getInterface();
   1333             if (bestRoute.getGateway().equals(addr)) {
   1334                 // if there is no better route, add the implied hostroute for our gateway
   1335                 bestRoute = RouteInfo.makeHostRoute(addr, iface);
   1336             } else {
   1337                 // if we will connect to this through another route, add a direct route
   1338                 // to it's gateway
   1339                 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface);
   1340             }
   1341         }
   1342         if (DBG) log("Adding " + bestRoute + " for interface " + bestRoute.getInterface());
   1343         try {
   1344             mNetd.addLegacyRouteForNetId(netId, bestRoute, uid);
   1345         } catch (Exception e) {
   1346             // never crash - catch them all
   1347             if (DBG) loge("Exception trying to add a route: " + e);
   1348             return false;
   1349         }
   1350         return true;
   1351     }
   1352 
   1353     public void setDataDependency(int networkType, boolean met) {
   1354         enforceConnectivityInternalPermission();
   1355 
   1356         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_DEPENDENCY_MET,
   1357                 (met ? ENABLED : DISABLED), networkType));
   1358     }
   1359 
   1360     private void handleSetDependencyMet(int networkType, boolean met) {
   1361         if (mNetTrackers[networkType] != null) {
   1362             if (DBG) {
   1363                 log("handleSetDependencyMet(" + networkType + ", " + met + ")");
   1364             }
   1365             mNetTrackers[networkType].setDependencyMet(met);
   1366         }
   1367     }
   1368 
   1369     private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
   1370         @Override
   1371         public void onUidRulesChanged(int uid, int uidRules) {
   1372             // caller is NPMS, since we only register with them
   1373             if (LOGD_RULES) {
   1374                 log("onUidRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")");
   1375             }
   1376 
   1377             synchronized (mRulesLock) {
   1378                 // skip update when we've already applied rules
   1379                 final int oldRules = mUidRules.get(uid, RULE_ALLOW_ALL);
   1380                 if (oldRules == uidRules) return;
   1381 
   1382                 mUidRules.put(uid, uidRules);
   1383             }
   1384 
   1385             // TODO: notify UID when it has requested targeted updates
   1386         }
   1387 
   1388         @Override
   1389         public void onMeteredIfacesChanged(String[] meteredIfaces) {
   1390             // caller is NPMS, since we only register with them
   1391             if (LOGD_RULES) {
   1392                 log("onMeteredIfacesChanged(ifaces=" + Arrays.toString(meteredIfaces) + ")");
   1393             }
   1394 
   1395             synchronized (mRulesLock) {
   1396                 mMeteredIfaces.clear();
   1397                 for (String iface : meteredIfaces) {
   1398                     mMeteredIfaces.add(iface);
   1399                 }
   1400             }
   1401         }
   1402 
   1403         @Override
   1404         public void onRestrictBackgroundChanged(boolean restrictBackground) {
   1405             // caller is NPMS, since we only register with them
   1406             if (LOGD_RULES) {
   1407                 log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
   1408             }
   1409 
   1410             // kick off connectivity change broadcast for active network, since
   1411             // global background policy change is radical.
   1412             // TODO: Dead code; remove.
   1413             //
   1414             // final int networkType = mActiveDefaultNetwork;
   1415             // if (isNetworkTypeValid(networkType)) {
   1416             //     final NetworkStateTracker tracker = mNetTrackers[networkType];
   1417             //     if (tracker != null) {
   1418             //         final NetworkInfo info = tracker.getNetworkInfo();
   1419             //         if (info != null && info.isConnected()) {
   1420             //             sendConnectedBroadcast(info);
   1421             //         }
   1422             //     }
   1423             // }
   1424         }
   1425     };
   1426 
   1427     private void enforceInternetPermission() {
   1428         mContext.enforceCallingOrSelfPermission(
   1429                 android.Manifest.permission.INTERNET,
   1430                 "ConnectivityService");
   1431     }
   1432 
   1433     private void enforceAccessPermission() {
   1434         mContext.enforceCallingOrSelfPermission(
   1435                 android.Manifest.permission.ACCESS_NETWORK_STATE,
   1436                 "ConnectivityService");
   1437     }
   1438 
   1439     private void enforceChangePermission() {
   1440         mContext.enforceCallingOrSelfPermission(
   1441                 android.Manifest.permission.CHANGE_NETWORK_STATE,
   1442                 "ConnectivityService");
   1443     }
   1444 
   1445     private void enforceTetherAccessPermission() {
   1446         mContext.enforceCallingOrSelfPermission(
   1447                 android.Manifest.permission.ACCESS_NETWORK_STATE,
   1448                 "ConnectivityService");
   1449     }
   1450 
   1451     private void enforceConnectivityInternalPermission() {
   1452         mContext.enforceCallingOrSelfPermission(
   1453                 android.Manifest.permission.CONNECTIVITY_INTERNAL,
   1454                 "ConnectivityService");
   1455     }
   1456 
   1457     public void sendConnectedBroadcast(NetworkInfo info) {
   1458         enforceConnectivityInternalPermission();
   1459         sendGeneralBroadcast(info, CONNECTIVITY_ACTION_IMMEDIATE);
   1460         sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
   1461     }
   1462 
   1463     private void sendInetConditionBroadcast(NetworkInfo info) {
   1464         sendGeneralBroadcast(info, ConnectivityManager.INET_CONDITION_ACTION);
   1465     }
   1466 
   1467     private Intent makeGeneralIntent(NetworkInfo info, String bcastType) {
   1468         if (mLockdownTracker != null) {
   1469             info = mLockdownTracker.augmentNetworkInfo(info);
   1470         }
   1471 
   1472         Intent intent = new Intent(bcastType);
   1473         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, new NetworkInfo(info));
   1474         intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
   1475         if (info.isFailover()) {
   1476             intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
   1477             info.setFailover(false);
   1478         }
   1479         if (info.getReason() != null) {
   1480             intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
   1481         }
   1482         if (info.getExtraInfo() != null) {
   1483             intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
   1484                     info.getExtraInfo());
   1485         }
   1486         intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
   1487         return intent;
   1488     }
   1489 
   1490     private void sendGeneralBroadcast(NetworkInfo info, String bcastType) {
   1491         sendStickyBroadcast(makeGeneralIntent(info, bcastType));
   1492     }
   1493 
   1494     private void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) {
   1495         Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE);
   1496         intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType);
   1497         intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active);
   1498         intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos);
   1499         final long ident = Binder.clearCallingIdentity();
   1500         try {
   1501             mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL,
   1502                     RECEIVE_DATA_ACTIVITY_CHANGE, null, null, 0, null, null);
   1503         } finally {
   1504             Binder.restoreCallingIdentity(ident);
   1505         }
   1506     }
   1507 
   1508     private void sendStickyBroadcast(Intent intent) {
   1509         synchronized(this) {
   1510             if (!mSystemReady) {
   1511                 mInitialBroadcast = new Intent(intent);
   1512             }
   1513             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
   1514             if (DBG) {
   1515                 log("sendStickyBroadcast: action=" + intent.getAction());
   1516             }
   1517 
   1518             final long ident = Binder.clearCallingIdentity();
   1519             if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
   1520                 final IBatteryStats bs = BatteryStatsService.getService();
   1521                 try {
   1522                     NetworkInfo ni = intent.getParcelableExtra(
   1523                             ConnectivityManager.EXTRA_NETWORK_INFO);
   1524                     bs.noteConnectivityChanged(intent.getIntExtra(
   1525                             ConnectivityManager.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_NONE),
   1526                             ni != null ? ni.getState().toString() : "?");
   1527                 } catch (RemoteException e) {
   1528                 }
   1529             }
   1530             try {
   1531                 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
   1532             } finally {
   1533                 Binder.restoreCallingIdentity(ident);
   1534             }
   1535         }
   1536     }
   1537 
   1538     void systemReady() {
   1539         // start network sampling ..
   1540         Intent intent = new Intent(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED);
   1541         intent.setPackage(mContext.getPackageName());
   1542 
   1543         mSampleIntervalElapsedIntent = PendingIntent.getBroadcast(mContext,
   1544                 SAMPLE_INTERVAL_ELAPSED_REQUEST_CODE, intent, 0);
   1545         setAlarm(DEFAULT_START_SAMPLING_INTERVAL_IN_SECONDS * 1000, mSampleIntervalElapsedIntent);
   1546 
   1547         loadGlobalProxy();
   1548 
   1549         synchronized(this) {
   1550             mSystemReady = true;
   1551             if (mInitialBroadcast != null) {
   1552                 mContext.sendStickyBroadcastAsUser(mInitialBroadcast, UserHandle.ALL);
   1553                 mInitialBroadcast = null;
   1554             }
   1555         }
   1556         // load the global proxy at startup
   1557         mHandler.sendMessage(mHandler.obtainMessage(EVENT_APPLY_GLOBAL_HTTP_PROXY));
   1558 
   1559         // Try bringing up tracker, but if KeyStore isn't ready yet, wait
   1560         // for user to unlock device.
   1561         if (!updateLockdownVpn()) {
   1562             final IntentFilter filter = new IntentFilter(Intent.ACTION_USER_PRESENT);
   1563             mContext.registerReceiver(mUserPresentReceiver, filter);
   1564         }
   1565 
   1566         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_READY));
   1567 
   1568         mPermissionMonitor.startMonitoring();
   1569     }
   1570 
   1571     private BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() {
   1572         @Override
   1573         public void onReceive(Context context, Intent intent) {
   1574             // Try creating lockdown tracker, since user present usually means
   1575             // unlocked keystore.
   1576             if (updateLockdownVpn()) {
   1577                 mContext.unregisterReceiver(this);
   1578             }
   1579         }
   1580     };
   1581 
   1582     /** @hide */
   1583     @Override
   1584     public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
   1585         enforceConnectivityInternalPermission();
   1586         if (DBG) log("captivePortalCheckCompleted: ni=" + info + " captive=" + isCaptivePortal);
   1587 //        mNetTrackers[info.getType()].captivePortalCheckCompleted(isCaptivePortal);
   1588     }
   1589 
   1590     /**
   1591      * Setup data activity tracking for the given network.
   1592      *
   1593      * Every {@code setupDataActivityTracking} should be paired with a
   1594      * {@link #removeDataActivityTracking} for cleanup.
   1595      */
   1596     private void setupDataActivityTracking(NetworkAgentInfo networkAgent) {
   1597         final String iface = networkAgent.linkProperties.getInterfaceName();
   1598 
   1599         final int timeout;
   1600         int type = ConnectivityManager.TYPE_NONE;
   1601 
   1602         if (networkAgent.networkCapabilities.hasTransport(
   1603                 NetworkCapabilities.TRANSPORT_CELLULAR)) {
   1604             timeout = Settings.Global.getInt(mContext.getContentResolver(),
   1605                                              Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE,
   1606                                              5);
   1607             type = ConnectivityManager.TYPE_MOBILE;
   1608         } else if (networkAgent.networkCapabilities.hasTransport(
   1609                 NetworkCapabilities.TRANSPORT_WIFI)) {
   1610             timeout = Settings.Global.getInt(mContext.getContentResolver(),
   1611                                              Settings.Global.DATA_ACTIVITY_TIMEOUT_WIFI,
   1612                                              0);
   1613             type = ConnectivityManager.TYPE_WIFI;
   1614         } else {
   1615             // do not track any other networks
   1616             timeout = 0;
   1617         }
   1618 
   1619         if (timeout > 0 && iface != null && type != ConnectivityManager.TYPE_NONE) {
   1620             try {
   1621                 mNetd.addIdleTimer(iface, timeout, type);
   1622             } catch (Exception e) {
   1623                 // You shall not crash!
   1624                 loge("Exception in setupDataActivityTracking " + e);
   1625             }
   1626         }
   1627     }
   1628 
   1629     /**
   1630      * Remove data activity tracking when network disconnects.
   1631      */
   1632     private void removeDataActivityTracking(NetworkAgentInfo networkAgent) {
   1633         final String iface = networkAgent.linkProperties.getInterfaceName();
   1634         final NetworkCapabilities caps = networkAgent.networkCapabilities;
   1635 
   1636         if (iface != null && (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
   1637                               caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))) {
   1638             try {
   1639                 // the call fails silently if no idletimer setup for this interface
   1640                 mNetd.removeIdleTimer(iface);
   1641             } catch (Exception e) {
   1642                 loge("Exception in removeDataActivityTracking " + e);
   1643             }
   1644         }
   1645     }
   1646 
   1647     /**
   1648      * Reads the network specific MTU size from reources.
   1649      * and set it on it's iface.
   1650      */
   1651     private void updateMtu(LinkProperties newLp, LinkProperties oldLp) {
   1652         final String iface = newLp.getInterfaceName();
   1653         final int mtu = newLp.getMtu();
   1654         if (oldLp != null && newLp.isIdenticalMtu(oldLp)) {
   1655             if (VDBG) log("identical MTU - not setting");
   1656             return;
   1657         }
   1658 
   1659         if (LinkProperties.isValidMtu(mtu, newLp.hasGlobalIPv6Address()) == false) {
   1660             loge("Unexpected mtu value: " + mtu + ", " + iface);
   1661             return;
   1662         }
   1663 
   1664         // Cannot set MTU without interface name
   1665         if (TextUtils.isEmpty(iface)) {
   1666             loge("Setting MTU size with null iface.");
   1667             return;
   1668         }
   1669 
   1670         try {
   1671             if (DBG) log("Setting MTU size: " + iface + ", " + mtu);
   1672             mNetd.setMtu(iface, mtu);
   1673         } catch (Exception e) {
   1674             Slog.e(TAG, "exception in setMtu()" + e);
   1675         }
   1676     }
   1677 
   1678     private static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208";
   1679 
   1680     private void updateTcpBufferSizes(NetworkAgentInfo nai) {
   1681         if (isDefaultNetwork(nai) == false) {
   1682             return;
   1683         }
   1684 
   1685         String tcpBufferSizes = nai.linkProperties.getTcpBufferSizes();
   1686         String[] values = null;
   1687         if (tcpBufferSizes != null) {
   1688             values = tcpBufferSizes.split(",");
   1689         }
   1690 
   1691         if (values == null || values.length != 6) {
   1692             if (DBG) log("Invalid tcpBufferSizes string: " + tcpBufferSizes +", using defaults");
   1693             tcpBufferSizes = DEFAULT_TCP_BUFFER_SIZES;
   1694             values = tcpBufferSizes.split(",");
   1695         }
   1696 
   1697         if (tcpBufferSizes.equals(mCurrentTcpBufferSizes)) return;
   1698 
   1699         try {
   1700             if (DBG) Slog.d(TAG, "Setting tx/rx TCP buffers to " + tcpBufferSizes);
   1701 
   1702             final String prefix = "/sys/kernel/ipv4/tcp_";
   1703             FileUtils.stringToFile(prefix + "rmem_min", values[0]);
   1704             FileUtils.stringToFile(prefix + "rmem_def", values[1]);
   1705             FileUtils.stringToFile(prefix + "rmem_max", values[2]);
   1706             FileUtils.stringToFile(prefix + "wmem_min", values[3]);
   1707             FileUtils.stringToFile(prefix + "wmem_def", values[4]);
   1708             FileUtils.stringToFile(prefix + "wmem_max", values[5]);
   1709             mCurrentTcpBufferSizes = tcpBufferSizes;
   1710         } catch (IOException e) {
   1711             loge("Can't set TCP buffer sizes:" + e);
   1712         }
   1713 
   1714         final String defaultRwndKey = "net.tcp.default_init_rwnd";
   1715         int defaultRwndValue = SystemProperties.getInt(defaultRwndKey, 0);
   1716         Integer rwndValue = Settings.Global.getInt(mContext.getContentResolver(),
   1717             Settings.Global.TCP_DEFAULT_INIT_RWND, defaultRwndValue);
   1718         final String sysctlKey = "sys.sysctl.tcp_def_init_rwnd";
   1719         if (rwndValue != 0) {
   1720             SystemProperties.set(sysctlKey, rwndValue.toString());
   1721         }
   1722     }
   1723 
   1724     private void flushVmDnsCache() {
   1725         /*
   1726          * Tell the VMs to toss their DNS caches
   1727          */
   1728         Intent intent = new Intent(Intent.ACTION_CLEAR_DNS_CACHE);
   1729         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
   1730         /*
   1731          * Connectivity events can happen before boot has completed ...
   1732          */
   1733         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
   1734         final long ident = Binder.clearCallingIdentity();
   1735         try {
   1736             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
   1737         } finally {
   1738             Binder.restoreCallingIdentity(ident);
   1739         }
   1740     }
   1741 
   1742     @Override
   1743     public int getRestoreDefaultNetworkDelay(int networkType) {
   1744         String restoreDefaultNetworkDelayStr = SystemProperties.get(
   1745                 NETWORK_RESTORE_DELAY_PROP_NAME);
   1746         if(restoreDefaultNetworkDelayStr != null &&
   1747                 restoreDefaultNetworkDelayStr.length() != 0) {
   1748             try {
   1749                 return Integer.valueOf(restoreDefaultNetworkDelayStr);
   1750             } catch (NumberFormatException e) {
   1751             }
   1752         }
   1753         // if the system property isn't set, use the value for the apn type
   1754         int ret = RESTORE_DEFAULT_NETWORK_DELAY;
   1755 
   1756         if ((networkType <= ConnectivityManager.MAX_NETWORK_TYPE) &&
   1757                 (mNetConfigs[networkType] != null)) {
   1758             ret = mNetConfigs[networkType].restoreTime;
   1759         }
   1760         return ret;
   1761     }
   1762 
   1763     @Override
   1764     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
   1765         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
   1766         if (mContext.checkCallingOrSelfPermission(
   1767                 android.Manifest.permission.DUMP)
   1768                 != PackageManager.PERMISSION_GRANTED) {
   1769             pw.println("Permission Denial: can't dump ConnectivityService " +
   1770                     "from from pid=" + Binder.getCallingPid() + ", uid=" +
   1771                     Binder.getCallingUid());
   1772             return;
   1773         }
   1774 
   1775         pw.println("NetworkFactories for:");
   1776         pw.increaseIndent();
   1777         for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
   1778             pw.println(nfi.name);
   1779         }
   1780         pw.decreaseIndent();
   1781         pw.println();
   1782 
   1783         NetworkAgentInfo defaultNai = mNetworkForRequestId.get(mDefaultRequest.requestId);
   1784         pw.print("Active default network: ");
   1785         if (defaultNai == null) {
   1786             pw.println("none");
   1787         } else {
   1788             pw.println(defaultNai.network.netId);
   1789         }
   1790         pw.println();
   1791 
   1792         pw.println("Current Networks:");
   1793         pw.increaseIndent();
   1794         for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
   1795             pw.println(nai.toString());
   1796             pw.increaseIndent();
   1797             pw.println("Requests:");
   1798             pw.increaseIndent();
   1799             for (int i = 0; i < nai.networkRequests.size(); i++) {
   1800                 pw.println(nai.networkRequests.valueAt(i).toString());
   1801             }
   1802             pw.decreaseIndent();
   1803             pw.println("Lingered:");
   1804             pw.increaseIndent();
   1805             for (NetworkRequest nr : nai.networkLingered) pw.println(nr.toString());
   1806             pw.decreaseIndent();
   1807             pw.decreaseIndent();
   1808         }
   1809         pw.decreaseIndent();
   1810         pw.println();
   1811 
   1812         pw.println("Network Requests:");
   1813         pw.increaseIndent();
   1814         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
   1815             pw.println(nri.toString());
   1816         }
   1817         pw.println();
   1818         pw.decreaseIndent();
   1819 
   1820         pw.println("mLegacyTypeTracker:");
   1821         pw.increaseIndent();
   1822         mLegacyTypeTracker.dump(pw);
   1823         pw.decreaseIndent();
   1824         pw.println();
   1825 
   1826         synchronized (this) {
   1827             pw.println("NetworkTransitionWakeLock is currently " +
   1828                     (mNetTransitionWakeLock.isHeld() ? "" : "not ") + "held.");
   1829             pw.println("It was last requested for "+mNetTransitionWakeLockCausedBy);
   1830         }
   1831         pw.println();
   1832 
   1833         mTethering.dump(fd, pw, args);
   1834 
   1835         if (mInetLog != null) {
   1836             pw.println();
   1837             pw.println("Inet condition reports:");
   1838             pw.increaseIndent();
   1839             for(int i = 0; i < mInetLog.size(); i++) {
   1840                 pw.println(mInetLog.get(i));
   1841             }
   1842             pw.decreaseIndent();
   1843         }
   1844     }
   1845 
   1846     private boolean isLiveNetworkAgent(NetworkAgentInfo nai, String msg) {
   1847         if (nai.network == null) return false;
   1848         final NetworkAgentInfo officialNai = getNetworkAgentInfoForNetwork(nai.network);
   1849         if (officialNai != null && officialNai.equals(nai)) return true;
   1850         if (officialNai != null || VDBG) {
   1851             loge(msg + " - isLiveNetworkAgent found mismatched netId: " + officialNai +
   1852                 " - " + nai);
   1853         }
   1854         return false;
   1855     }
   1856 
   1857     private boolean isRequest(NetworkRequest request) {
   1858         return mNetworkRequests.get(request).isRequest;
   1859     }
   1860 
   1861     // must be stateless - things change under us.
   1862     private class NetworkStateTrackerHandler extends Handler {
   1863         public NetworkStateTrackerHandler(Looper looper) {
   1864             super(looper);
   1865         }
   1866 
   1867         @Override
   1868         public void handleMessage(Message msg) {
   1869             NetworkInfo info;
   1870             switch (msg.what) {
   1871                 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
   1872                     handleAsyncChannelHalfConnect(msg);
   1873                     break;
   1874                 }
   1875                 case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
   1876                     NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
   1877                     if (nai != null) nai.asyncChannel.disconnect();
   1878                     break;
   1879                 }
   1880                 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
   1881                     handleAsyncChannelDisconnected(msg);
   1882                     break;
   1883                 }
   1884                 case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
   1885                     NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
   1886                     if (nai == null) {
   1887                         loge("EVENT_NETWORK_CAPABILITIES_CHANGED from unknown NetworkAgent");
   1888                     } else {
   1889                         updateCapabilities(nai, (NetworkCapabilities)msg.obj);
   1890                     }
   1891                     break;
   1892                 }
   1893                 case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: {
   1894                     NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
   1895                     if (nai == null) {
   1896                         loge("NetworkAgent not found for EVENT_NETWORK_PROPERTIES_CHANGED");
   1897                     } else {
   1898                         if (VDBG) {
   1899                             log("Update of LinkProperties for " + nai.name() +
   1900                                     "; created=" + nai.created);
   1901                         }
   1902                         LinkProperties oldLp = nai.linkProperties;
   1903                         synchronized (nai) {
   1904                             nai.linkProperties = (LinkProperties)msg.obj;
   1905                         }
   1906                         if (nai.created) updateLinkProperties(nai, oldLp);
   1907                     }
   1908                     break;
   1909                 }
   1910                 case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {
   1911                     NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
   1912                     if (nai == null) {
   1913                         loge("EVENT_NETWORK_INFO_CHANGED from unknown NetworkAgent");
   1914                         break;
   1915                     }
   1916                     info = (NetworkInfo) msg.obj;
   1917                     updateNetworkInfo(nai, info);
   1918                     break;
   1919                 }
   1920                 case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
   1921                     NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
   1922                     if (nai == null) {
   1923                         loge("EVENT_NETWORK_SCORE_CHANGED from unknown NetworkAgent");
   1924                         break;
   1925                     }
   1926                     Integer score = (Integer) msg.obj;
   1927                     if (score != null) updateNetworkScore(nai, score.intValue());
   1928                     break;
   1929                 }
   1930                 case NetworkAgent.EVENT_UID_RANGES_ADDED: {
   1931                     NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
   1932                     if (nai == null) {
   1933                         loge("EVENT_UID_RANGES_ADDED from unknown NetworkAgent");
   1934                         break;
   1935                     }
   1936                     try {
   1937                         mNetd.addVpnUidRanges(nai.network.netId, (UidRange[])msg.obj);
   1938                     } catch (Exception e) {
   1939                         // Never crash!
   1940                         loge("Exception in addVpnUidRanges: " + e);
   1941                     }
   1942                     break;
   1943                 }
   1944                 case NetworkAgent.EVENT_UID_RANGES_REMOVED: {
   1945                     NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
   1946                     if (nai == null) {
   1947                         loge("EVENT_UID_RANGES_REMOVED from unknown NetworkAgent");
   1948                         break;
   1949                     }
   1950                     try {
   1951                         mNetd.removeVpnUidRanges(nai.network.netId, (UidRange[])msg.obj);
   1952                     } catch (Exception e) {
   1953                         // Never crash!
   1954                         loge("Exception in removeVpnUidRanges: " + e);
   1955                     }
   1956                     break;
   1957                 }
   1958                 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
   1959                     NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
   1960                     if (nai == null) {
   1961                         loge("EVENT_SET_EXPLICITLY_SELECTED from unknown NetworkAgent");
   1962                         break;
   1963                     }
   1964                     if (nai.created && !nai.networkMisc.explicitlySelected) {
   1965                         loge("ERROR: created network explicitly selected.");
   1966                     }
   1967                     nai.networkMisc.explicitlySelected = true;
   1968                     break;
   1969                 }
   1970                 case NetworkMonitor.EVENT_NETWORK_TESTED: {
   1971                     NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;
   1972                     if (isLiveNetworkAgent(nai, "EVENT_NETWORK_VALIDATED")) {
   1973                         boolean valid = (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID);
   1974                         nai.lastValidated = valid;
   1975                         if (valid) {
   1976                             if (DBG) log("Validated " + nai.name());
   1977                             if (!nai.everValidated) {
   1978                                 nai.everValidated = true;
   1979                                 rematchNetworkAndRequests(nai, NascentState.JUST_VALIDATED,
   1980                                     ReapUnvalidatedNetworks.REAP);
   1981                                 // If score has changed, rebroadcast to NetworkFactories. b/17726566
   1982                                 sendUpdatedScoreToFactories(nai);
   1983                             }
   1984                         }
   1985                         updateInetCondition(nai);
   1986                         // Let the NetworkAgent know the state of its network
   1987                         nai.asyncChannel.sendMessage(
   1988                                 android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS,
   1989                                 (valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK),
   1990                                 0, null);
   1991                     }
   1992                     break;
   1993                 }
   1994                 case NetworkMonitor.EVENT_NETWORK_LINGER_COMPLETE: {
   1995                     NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;
   1996                     if (isLiveNetworkAgent(nai, "EVENT_NETWORK_LINGER_COMPLETE")) {
   1997                         handleLingerComplete(nai);
   1998                     }
   1999                     break;
   2000                 }
   2001                 case NetworkMonitor.EVENT_PROVISIONING_NOTIFICATION: {
   2002                     if (msg.arg1 == 0) {
   2003                         setProvNotificationVisibleIntent(false, msg.arg2, 0, null, null);
   2004                     } else {
   2005                         NetworkAgentInfo nai = null;
   2006                         synchronized (mNetworkForNetId) {
   2007                             nai = mNetworkForNetId.get(msg.arg2);
   2008                         }
   2009                         if (nai == null) {
   2010                             loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
   2011                             break;
   2012                         }
   2013                         setProvNotificationVisibleIntent(true, msg.arg2, nai.networkInfo.getType(),
   2014                                 nai.networkInfo.getExtraInfo(), (PendingIntent)msg.obj);
   2015                     }
   2016                     break;
   2017                 }
   2018                 case NetworkStateTracker.EVENT_STATE_CHANGED: {
   2019                     info = (NetworkInfo) msg.obj;
   2020                     NetworkInfo.State state = info.getState();
   2021 
   2022                     if (VDBG || (state == NetworkInfo.State.CONNECTED) ||
   2023                             (state == NetworkInfo.State.DISCONNECTED) ||
   2024                             (state == NetworkInfo.State.SUSPENDED)) {
   2025                         log("ConnectivityChange for " +
   2026                             info.getTypeName() + ": " +
   2027                             state + "/" + info.getDetailedState());
   2028                     }
   2029 
   2030                     EventLogTags.writeConnectivityStateChanged(
   2031                             info.getType(), info.getSubtype(), info.getDetailedState().ordinal());
   2032 
   2033                     if (info.isConnectedToProvisioningNetwork()) {
   2034                         /**
   2035                          * TODO: Create ConnectivityManager.TYPE_MOBILE_PROVISIONING
   2036                          * for now its an in between network, its a network that
   2037                          * is actually a default network but we don't want it to be
   2038                          * announced as such to keep background applications from
   2039                          * trying to use it. It turns out that some still try so we
   2040                          * take the additional step of clearing any default routes
   2041                          * to the link that may have incorrectly setup by the lower
   2042                          * levels.
   2043                          */
   2044                         LinkProperties lp = getLinkPropertiesForType(info.getType());
   2045                         if (DBG) {
   2046                             log("EVENT_STATE_CHANGED: connected to provisioning network, lp=" + lp);
   2047                         }
   2048 
   2049                         // Clear any default routes setup by the radio so
   2050                         // any activity by applications trying to use this
   2051                         // connection will fail until the provisioning network
   2052                         // is enabled.
   2053                         /*
   2054                         for (RouteInfo r : lp.getRoutes()) {
   2055                             removeRoute(lp, r, TO_DEFAULT_TABLE,
   2056                                         mNetTrackers[info.getType()].getNetwork().netId);
   2057                         }
   2058                         */
   2059                     } else if (state == NetworkInfo.State.DISCONNECTED) {
   2060                     } else if (state == NetworkInfo.State.SUSPENDED) {
   2061                     } else if (state == NetworkInfo.State.CONNECTED) {
   2062                     //    handleConnect(info);
   2063                     }
   2064                     notifyLockdownVpn(null);
   2065                     break;
   2066                 }
   2067                 case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED: {
   2068                     info = (NetworkInfo) msg.obj;
   2069                     // TODO: Temporary allowing network configuration
   2070                     //       change not resetting sockets.
   2071                     //       @see bug/4455071
   2072                     /*
   2073                     handleConnectivityChange(info.getType(), mCurrentLinkProperties[info.getType()],
   2074                             false);
   2075                     */
   2076                     break;
   2077                 }
   2078             }
   2079         }
   2080     }
   2081 
   2082     // Cancel any lingering so the linger timeout doesn't teardown a network.
   2083     // This should be called when a network begins satisfying a NetworkRequest.
   2084     // Note: depending on what state the NetworkMonitor is in (e.g.,
   2085     // if it's awaiting captive portal login, or if validation failed), this
   2086     // may trigger a re-evaluation of the network.
   2087     private void unlinger(NetworkAgentInfo nai) {
   2088         if (VDBG) log("Canceling linger of " + nai.name());
   2089         // If network has never been validated, it cannot have been lingered, so don't bother
   2090         // needlessly triggering a re-evaluation.
   2091         if (!nai.everValidated) return;
   2092         nai.networkLingered.clear();
   2093         nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
   2094     }
   2095 
   2096     private void handleAsyncChannelHalfConnect(Message msg) {
   2097         AsyncChannel ac = (AsyncChannel) msg.obj;
   2098         if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {
   2099             if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
   2100                 if (VDBG) log("NetworkFactory connected");
   2101                 // A network factory has connected.  Send it all current NetworkRequests.
   2102                 for (NetworkRequestInfo nri : mNetworkRequests.values()) {
   2103                     if (nri.isRequest == false) continue;
   2104                     NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
   2105                     ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK,
   2106                             (nai != null ? nai.getCurrentScore() : 0), 0, nri.request);
   2107                 }
   2108             } else {
   2109                 loge("Error connecting NetworkFactory");
   2110                 mNetworkFactoryInfos.remove(msg.obj);
   2111             }
   2112         } else if (mNetworkAgentInfos.containsKey(msg.replyTo)) {
   2113             if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
   2114                 if (VDBG) log("NetworkAgent connected");
   2115                 // A network agent has requested a connection.  Establish the connection.
   2116                 mNetworkAgentInfos.get(msg.replyTo).asyncChannel.
   2117                         sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
   2118             } else {
   2119                 loge("Error connecting NetworkAgent");
   2120                 NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo);
   2121                 if (nai != null) {
   2122                     synchronized (mNetworkForNetId) {
   2123                         mNetworkForNetId.remove(nai.network.netId);
   2124                     }
   2125                     // Just in case.
   2126                     mLegacyTypeTracker.remove(nai);
   2127                 }
   2128             }
   2129         }
   2130     }
   2131 
   2132     private void handleAsyncChannelDisconnected(Message msg) {
   2133         NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
   2134         if (nai != null) {
   2135             if (DBG) {
   2136                 log(nai.name() + " got DISCONNECTED, was satisfying " + nai.networkRequests.size());
   2137             }
   2138             // A network agent has disconnected.
   2139             if (nai.created) {
   2140                 // Tell netd to clean up the configuration for this network
   2141                 // (routing rules, DNS, etc).
   2142                 try {
   2143                     mNetd.removeNetwork(nai.network.netId);
   2144                 } catch (Exception e) {
   2145                     loge("Exception removing network: " + e);
   2146                 }
   2147             }
   2148             // TODO - if we move the logic to the network agent (have them disconnect
   2149             // because they lost all their requests or because their score isn't good)
   2150             // then they would disconnect organically, report their new state and then
   2151             // disconnect the channel.
   2152             if (nai.networkInfo.isConnected()) {
   2153                 nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
   2154                         null, null);
   2155             }
   2156             if (isDefaultNetwork(nai)) {
   2157                 mDefaultInetConditionPublished = 0;
   2158             }
   2159             notifyIfacesChanged();
   2160             notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
   2161             nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
   2162             mNetworkAgentInfos.remove(msg.replyTo);
   2163             updateClat(null, nai.linkProperties, nai);
   2164             mLegacyTypeTracker.remove(nai);
   2165             synchronized (mNetworkForNetId) {
   2166                 mNetworkForNetId.remove(nai.network.netId);
   2167             }
   2168             // Since we've lost the network, go through all the requests that
   2169             // it was satisfying and see if any other factory can satisfy them.
   2170             // TODO: This logic may be better replaced with a call to rematchAllNetworksAndRequests
   2171             final ArrayList<NetworkAgentInfo> toActivate = new ArrayList<NetworkAgentInfo>();
   2172             for (int i = 0; i < nai.networkRequests.size(); i++) {
   2173                 NetworkRequest request = nai.networkRequests.valueAt(i);
   2174                 NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(request.requestId);
   2175                 if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
   2176                     if (DBG) {
   2177                         log("Checking for replacement network to handle request " + request );
   2178                     }
   2179                     mNetworkForRequestId.remove(request.requestId);
   2180                     sendUpdatedScoreToFactories(request, 0);
   2181                     NetworkAgentInfo alternative = null;
   2182                     for (NetworkAgentInfo existing : mNetworkAgentInfos.values()) {
   2183                         if (existing.satisfies(request) &&
   2184                                 (alternative == null ||
   2185                                  alternative.getCurrentScore() < existing.getCurrentScore())) {
   2186                             alternative = existing;
   2187                         }
   2188                     }
   2189                     if (alternative != null) {
   2190                         if (DBG) log(" found replacement in " + alternative.name());
   2191                         if (!toActivate.contains(alternative)) {
   2192                             toActivate.add(alternative);
   2193                         }
   2194                     }
   2195                 }
   2196             }
   2197             if (nai.networkRequests.get(mDefaultRequest.requestId) != null) {
   2198                 removeDataActivityTracking(nai);
   2199                 notifyLockdownVpn(nai);
   2200                 requestNetworkTransitionWakelock(nai.name());
   2201             }
   2202             for (NetworkAgentInfo networkToActivate : toActivate) {
   2203                 unlinger(networkToActivate);
   2204                 rematchNetworkAndRequests(networkToActivate, NascentState.NOT_JUST_VALIDATED,
   2205                         ReapUnvalidatedNetworks.DONT_REAP);
   2206             }
   2207         }
   2208     }
   2209 
   2210     // If this method proves to be too slow then we can maintain a separate
   2211     // pendingIntent => NetworkRequestInfo map.
   2212     // This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo.
   2213     private NetworkRequestInfo findExistingNetworkRequestInfo(PendingIntent pendingIntent) {
   2214         Intent intent = pendingIntent.getIntent();
   2215         for (Map.Entry<NetworkRequest, NetworkRequestInfo> entry : mNetworkRequests.entrySet()) {
   2216             PendingIntent existingPendingIntent = entry.getValue().mPendingIntent;
   2217             if (existingPendingIntent != null &&
   2218                     existingPendingIntent.getIntent().filterEquals(intent)) {
   2219                 return entry.getValue();
   2220             }
   2221         }
   2222         return null;
   2223     }
   2224 
   2225     private void handleRegisterNetworkRequestWithIntent(Message msg) {
   2226         final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
   2227 
   2228         NetworkRequestInfo existingRequest = findExistingNetworkRequestInfo(nri.mPendingIntent);
   2229         if (existingRequest != null) { // remove the existing request.
   2230             if (DBG) log("Replacing " + existingRequest.request + " with "
   2231                     + nri.request + " because their intents matched.");
   2232             handleReleaseNetworkRequest(existingRequest.request, getCallingUid());
   2233         }
   2234         handleRegisterNetworkRequest(msg);
   2235     }
   2236 
   2237     private void handleRegisterNetworkRequest(Message msg) {
   2238         final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
   2239 
   2240         mNetworkRequests.put(nri.request, nri);
   2241 
   2242         // TODO: This logic may be better replaced with a call to rematchNetworkAndRequests
   2243 
   2244         // Check for the best currently alive network that satisfies this request
   2245         NetworkAgentInfo bestNetwork = null;
   2246         for (NetworkAgentInfo network : mNetworkAgentInfos.values()) {
   2247             if (DBG) log("handleRegisterNetworkRequest checking " + network.name());
   2248             if (network.satisfies(nri.request)) {
   2249                 if (DBG) log("apparently satisfied.  currentScore=" + network.getCurrentScore());
   2250                 if (!nri.isRequest) {
   2251                     // Not setting bestNetwork here as a listening NetworkRequest may be
   2252                     // satisfied by multiple Networks.  Instead the request is added to
   2253                     // each satisfying Network and notified about each.
   2254                     network.addRequest(nri.request);
   2255                     notifyNetworkCallback(network, nri);
   2256                 } else if (bestNetwork == null ||
   2257                         bestNetwork.getCurrentScore() < network.getCurrentScore()) {
   2258                     bestNetwork = network;
   2259                 }
   2260             }
   2261         }
   2262         if (bestNetwork != null) {
   2263             if (DBG) log("using " + bestNetwork.name());
   2264             unlinger(bestNetwork);
   2265             bestNetwork.addRequest(nri.request);
   2266             mNetworkForRequestId.put(nri.request.requestId, bestNetwork);
   2267             notifyNetworkCallback(bestNetwork, nri);
   2268             if (nri.request.legacyType != TYPE_NONE) {
   2269                 mLegacyTypeTracker.add(nri.request.legacyType, bestNetwork);
   2270             }
   2271         }
   2272 
   2273         if (nri.isRequest) {
   2274             if (DBG) log("sending new NetworkRequest to factories");
   2275             final int score = bestNetwork == null ? 0 : bestNetwork.getCurrentScore();
   2276             for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
   2277                 nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score,
   2278                         0, nri.request);
   2279             }
   2280         }
   2281     }
   2282 
   2283     private void handleReleaseNetworkRequestWithIntent(PendingIntent pendingIntent,
   2284             int callingUid) {
   2285         NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent);
   2286         if (nri != null) {
   2287             handleReleaseNetworkRequest(nri.request, callingUid);
   2288         }
   2289     }
   2290 
   2291     // Is nai unneeded by all NetworkRequests (and should be disconnected)?
   2292     // For validated Networks this is simply whether it is satsifying any NetworkRequests.
   2293     // For unvalidated Networks this is whether it is satsifying any NetworkRequests or
   2294     // were it to become validated, would it have a chance of satisfying any NetworkRequests.
   2295     private boolean unneeded(NetworkAgentInfo nai) {
   2296         if (!nai.created || nai.isVPN()) return false;
   2297         boolean unneeded = true;
   2298         if (nai.everValidated) {
   2299             for (int i = 0; i < nai.networkRequests.size() && unneeded; i++) {
   2300                 final NetworkRequest nr = nai.networkRequests.valueAt(i);
   2301                 try {
   2302                     if (isRequest(nr)) unneeded = false;
   2303                 } catch (Exception e) {
   2304                     loge("Request " + nr + " not found in mNetworkRequests.");
   2305                     loge("  it came from request list  of " + nai.name());
   2306                 }
   2307             }
   2308         } else {
   2309             for (NetworkRequestInfo nri : mNetworkRequests.values()) {
   2310                 // If this Network is already the highest scoring Network for a request, or if
   2311                 // there is hope for it to become one if it validated, then it is needed.
   2312                 if (nri.isRequest && nai.satisfies(nri.request) &&
   2313                         (nai.networkRequests.get(nri.request.requestId) != null ||
   2314                         // Note that this catches two important cases:
   2315                         // 1. Unvalidated cellular will not be reaped when unvalidated WiFi
   2316                         //    is currently satisfying the request.  This is desirable when
   2317                         //    cellular ends up validating but WiFi does not.
   2318                         // 2. Unvalidated WiFi will not be reaped when validated cellular
   2319                         //    is currently satsifying the request.  This is desirable when
   2320                         //    WiFi ends up validating and out scoring cellular.
   2321                         mNetworkForRequestId.get(nri.request.requestId).getCurrentScore() <
   2322                                 nai.getCurrentScoreAsValidated())) {
   2323                     unneeded = false;
   2324                     break;
   2325                 }
   2326             }
   2327         }
   2328         return unneeded;
   2329     }
   2330 
   2331     private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) {
   2332         NetworkRequestInfo nri = mNetworkRequests.get(request);
   2333         if (nri != null) {
   2334             if (Process.SYSTEM_UID != callingUid && nri.mUid != callingUid) {
   2335                 if (DBG) log("Attempt to release unowned NetworkRequest " + request);
   2336                 return;
   2337             }
   2338             if (DBG) log("releasing NetworkRequest " + request);
   2339             nri.unlinkDeathRecipient();
   2340             mNetworkRequests.remove(request);
   2341             if (nri.isRequest) {
   2342                 // Find all networks that are satisfying this request and remove the request
   2343                 // from their request lists.
   2344                 // TODO - it's my understanding that for a request there is only a single
   2345                 // network satisfying it, so this loop is wasteful
   2346                 boolean wasKept = false;
   2347                 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
   2348                     if (nai.networkRequests.get(nri.request.requestId) != null) {
   2349                         nai.networkRequests.remove(nri.request.requestId);
   2350                         if (DBG) {
   2351                             log(" Removing from current network " + nai.name() +
   2352                                     ", leaving " + nai.networkRequests.size() +
   2353                                     " requests.");
   2354                         }
   2355                         if (unneeded(nai)) {
   2356                             if (DBG) log("no live requests for " + nai.name() + "; disconnecting");
   2357                             teardownUnneededNetwork(nai);
   2358                         } else {
   2359                             // suspect there should only be one pass through here
   2360                             // but if any were kept do the check below
   2361                             wasKept |= true;
   2362                         }
   2363                     }
   2364                 }
   2365 
   2366                 NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
   2367                 if (nai != null) {
   2368                     mNetworkForRequestId.remove(nri.request.requestId);
   2369                 }
   2370                 // Maintain the illusion.  When this request arrived, we might have pretended
   2371                 // that a network connected to serve it, even though the network was already
   2372                 // connected.  Now that this request has gone away, we might have to pretend
   2373                 // that the network disconnected.  LegacyTypeTracker will generate that
   2374                 // phantom disconnect for this type.
   2375                 if (nri.request.legacyType != TYPE_NONE && nai != null) {
   2376                     boolean doRemove = true;
   2377                     if (wasKept) {
   2378                         // check if any of the remaining requests for this network are for the
   2379                         // same legacy type - if so, don't remove the nai
   2380                         for (int i = 0; i < nai.networkRequests.size(); i++) {
   2381                             NetworkRequest otherRequest = nai.networkRequests.valueAt(i);
   2382                             if (otherRequest.legacyType == nri.request.legacyType &&
   2383                                     isRequest(otherRequest)) {
   2384                                 if (DBG) log(" still have other legacy request - leaving");
   2385                                 doRemove = false;
   2386                             }
   2387                         }
   2388                     }
   2389 
   2390                     if (doRemove) {
   2391                         mLegacyTypeTracker.remove(nri.request.legacyType, nai);
   2392                     }
   2393                 }
   2394 
   2395                 for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
   2396                     nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST,
   2397                             nri.request);
   2398                 }
   2399             } else {
   2400                 // listens don't have a singular affectedNetwork.  Check all networks to see
   2401                 // if this listen request applies and remove it.
   2402                 for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
   2403                     nai.networkRequests.remove(nri.request.requestId);
   2404                 }
   2405             }
   2406             callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED);
   2407         }
   2408     }
   2409 
   2410     private class InternalHandler extends Handler {
   2411         public InternalHandler(Looper looper) {
   2412             super(looper);
   2413         }
   2414 
   2415         @Override
   2416         public void handleMessage(Message msg) {
   2417             switch (msg.what) {
   2418                 case EVENT_EXPIRE_NET_TRANSITION_WAKELOCK:
   2419                 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: {
   2420                     String causedBy = null;
   2421                     synchronized (ConnectivityService.this) {
   2422                         if (msg.arg1 == mNetTransitionWakeLockSerialNumber &&
   2423                                 mNetTransitionWakeLock.isHeld()) {
   2424                             mNetTransitionWakeLock.release();
   2425                             causedBy = mNetTransitionWakeLockCausedBy;
   2426                         } else {
   2427                             break;
   2428                         }
   2429                     }
   2430                     if (msg.what == EVENT_EXPIRE_NET_TRANSITION_WAKELOCK) {
   2431                         log("Failed to find a new network - expiring NetTransition Wakelock");
   2432                     } else {
   2433                         log("NetTransition Wakelock (" + (causedBy == null ? "unknown" : causedBy) +
   2434                                 " cleared because we found a replacement network");
   2435                     }
   2436                     break;
   2437                 }
   2438                 case EVENT_APPLY_GLOBAL_HTTP_PROXY: {
   2439                     handleDeprecatedGlobalHttpProxy();
   2440                     break;
   2441                 }
   2442                 case EVENT_SET_DEPENDENCY_MET: {
   2443                     boolean met = (msg.arg1 == ENABLED);
   2444                     handleSetDependencyMet(msg.arg2, met);
   2445                     break;
   2446                 }
   2447                 case EVENT_SEND_STICKY_BROADCAST_INTENT: {
   2448                     Intent intent = (Intent)msg.obj;
   2449                     sendStickyBroadcast(intent);
   2450                     break;
   2451                 }
   2452                 case EVENT_ENABLE_FAIL_FAST_MOBILE_DATA: {
   2453                     int tag = mEnableFailFastMobileDataTag.get();
   2454                     if (msg.arg1 == tag) {
   2455                         MobileDataStateTracker mobileDst =
   2456                             (MobileDataStateTracker) mNetTrackers[ConnectivityManager.TYPE_MOBILE];
   2457                         if (mobileDst != null) {
   2458                             mobileDst.setEnableFailFastMobileData(msg.arg2);
   2459                         }
   2460                     } else {
   2461                         log("EVENT_ENABLE_FAIL_FAST_MOBILE_DATA: stale arg1:" + msg.arg1
   2462                                 + " != tag:" + tag);
   2463                     }
   2464                     break;
   2465                 }
   2466                 case EVENT_SAMPLE_INTERVAL_ELAPSED: {
   2467                     handleNetworkSamplingTimeout();
   2468                     break;
   2469                 }
   2470                 case EVENT_PROXY_HAS_CHANGED: {
   2471                     handleApplyDefaultProxy((ProxyInfo)msg.obj);
   2472                     break;
   2473                 }
   2474                 case EVENT_REGISTER_NETWORK_FACTORY: {
   2475                     handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj);
   2476                     break;
   2477                 }
   2478                 case EVENT_UNREGISTER_NETWORK_FACTORY: {
   2479                     handleUnregisterNetworkFactory((Messenger)msg.obj);
   2480                     break;
   2481                 }
   2482                 case EVENT_REGISTER_NETWORK_AGENT: {
   2483                     handleRegisterNetworkAgent((NetworkAgentInfo)msg.obj);
   2484                     break;
   2485                 }
   2486                 case EVENT_REGISTER_NETWORK_REQUEST:
   2487                 case EVENT_REGISTER_NETWORK_LISTENER: {
   2488                     handleRegisterNetworkRequest(msg);
   2489                     break;
   2490                 }
   2491                 case EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT: {
   2492                     handleRegisterNetworkRequestWithIntent(msg);
   2493                     break;
   2494                 }
   2495                 case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: {
   2496                     handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1);
   2497                     break;
   2498                 }
   2499                 case EVENT_RELEASE_NETWORK_REQUEST: {
   2500                     handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.arg1);
   2501                     break;
   2502                 }
   2503                 case EVENT_SYSTEM_READY: {
   2504                     for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
   2505                         nai.networkMonitor.systemReady = true;
   2506                     }
   2507                     break;
   2508                 }
   2509             }
   2510         }
   2511     }
   2512 
   2513     // javadoc from interface
   2514     public int tether(String iface) {
   2515         ConnectivityManager.enforceTetherChangePermission(mContext);
   2516         if (isTetheringSupported()) {
   2517             return mTethering.tether(iface);
   2518         } else {
   2519             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
   2520         }
   2521     }
   2522 
   2523     // javadoc from interface
   2524     public int untether(String iface) {
   2525         ConnectivityManager.enforceTetherChangePermission(mContext);
   2526 
   2527         if (isTetheringSupported()) {
   2528             return mTethering.untether(iface);
   2529         } else {
   2530             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
   2531         }
   2532     }
   2533 
   2534     // javadoc from interface
   2535     public int getLastTetherError(String iface) {
   2536         enforceTetherAccessPermission();
   2537 
   2538         if (isTetheringSupported()) {
   2539             return mTethering.getLastTetherError(iface);
   2540         } else {
   2541             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
   2542         }
   2543     }
   2544 
   2545     // TODO - proper iface API for selection by property, inspection, etc
   2546     public String[] getTetherableUsbRegexs() {
   2547         enforceTetherAccessPermission();
   2548         if (isTetheringSupported()) {
   2549             return mTethering.getTetherableUsbRegexs();
   2550         } else {
   2551             return new String[0];
   2552         }
   2553     }
   2554 
   2555     public String[] getTetherableWifiRegexs() {
   2556         enforceTetherAccessPermission();
   2557         if (isTetheringSupported()) {
   2558             return mTethering.getTetherableWifiRegexs();
   2559         } else {
   2560             return new String[0];
   2561         }
   2562     }
   2563 
   2564     public String[] getTetherableBluetoothRegexs() {
   2565         enforceTetherAccessPermission();
   2566         if (isTetheringSupported()) {
   2567             return mTethering.getTetherableBluetoothRegexs();
   2568         } else {
   2569             return new String[0];
   2570         }
   2571     }
   2572 
   2573     public int setUsbTethering(boolean enable) {
   2574         ConnectivityManager.enforceTetherChangePermission(mContext);
   2575         if (isTetheringSupported()) {
   2576             return mTethering.setUsbTethering(enable);
   2577         } else {
   2578             return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
   2579         }
   2580     }
   2581 
   2582     // TODO - move iface listing, queries, etc to new module
   2583     // javadoc from interface
   2584     public String[] getTetherableIfaces() {
   2585         enforceTetherAccessPermission();
   2586         return mTethering.getTetherableIfaces();
   2587     }
   2588 
   2589     public String[] getTetheredIfaces() {
   2590         enforceTetherAccessPermission();
   2591         return mTethering.getTetheredIfaces();
   2592     }
   2593 
   2594     public String[] getTetheringErroredIfaces() {
   2595         enforceTetherAccessPermission();
   2596         return mTethering.getErroredIfaces();
   2597     }
   2598 
   2599     public String[] getTetheredDhcpRanges() {
   2600         enforceConnectivityInternalPermission();
   2601         return mTethering.getTetheredDhcpRanges();
   2602     }
   2603 
   2604     // if ro.tether.denied = true we default to no tethering
   2605     // gservices could set the secure setting to 1 though to enable it on a build where it
   2606     // had previously been turned off.
   2607     public boolean isTetheringSupported() {
   2608         enforceTetherAccessPermission();
   2609         int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
   2610         boolean tetherEnabledInSettings = (Settings.Global.getInt(mContext.getContentResolver(),
   2611                 Settings.Global.TETHER_SUPPORTED, defaultVal) != 0)
   2612                 && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
   2613         return tetherEnabledInSettings && ((mTethering.getTetherableUsbRegexs().length != 0 ||
   2614                 mTethering.getTetherableWifiRegexs().length != 0 ||
   2615                 mTethering.getTetherableBluetoothRegexs().length != 0) &&
   2616                 mTethering.getUpstreamIfaceTypes().length != 0);
   2617     }
   2618 
   2619     // Called when we lose the default network and have no replacement yet.
   2620     // This will automatically be cleared after X seconds or a new default network
   2621     // becomes CONNECTED, whichever happens first.  The timer is started by the
   2622     // first caller and not restarted by subsequent callers.
   2623     private void requestNetworkTransitionWakelock(String forWhom) {
   2624         int serialNum = 0;
   2625         synchronized (this) {
   2626             if (mNetTransitionWakeLock.isHeld()) return;
   2627             serialNum = ++mNetTransitionWakeLockSerialNumber;
   2628             mNetTransitionWakeLock.acquire();
   2629             mNetTransitionWakeLockCausedBy = forWhom;
   2630         }
   2631         mHandler.sendMessageDelayed(mHandler.obtainMessage(
   2632                 EVENT_EXPIRE_NET_TRANSITION_WAKELOCK, serialNum, 0),
   2633                 mNetTransitionWakeLockTimeout);
   2634         return;
   2635     }
   2636 
   2637     // 100 percent is full good, 0 is full bad.
   2638     public void reportInetCondition(int networkType, int percentage) {
   2639         NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
   2640         if (nai == null) return;
   2641         boolean isGood = percentage > 50;
   2642         // Revalidate if the app report does not match our current validated state.
   2643         if (isGood != nai.lastValidated) {
   2644             // Make the message logged by reportBadNetwork below less confusing.
   2645             if (DBG && isGood) log("reportInetCondition: type=" + networkType + " ok, revalidate");
   2646             reportBadNetwork(nai.network);
   2647         }
   2648     }
   2649 
   2650     public void reportBadNetwork(Network network) {
   2651         enforceAccessPermission();
   2652         enforceInternetPermission();
   2653 
   2654         if (network == null) return;
   2655 
   2656         final int uid = Binder.getCallingUid();
   2657         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
   2658         if (nai == null) return;
   2659         if (DBG) log("reportBadNetwork(" + nai.name() + ") by " + uid);
   2660         synchronized (nai) {
   2661             // Validating an uncreated network could result in a call to rematchNetworkAndRequests()
   2662             // which isn't meant to work on uncreated networks.
   2663             if (!nai.created) return;
   2664 
   2665             if (isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid)) return;
   2666 
   2667             nai.networkMonitor.sendMessage(NetworkMonitor.CMD_FORCE_REEVALUATION, uid);
   2668         }
   2669     }
   2670 
   2671     public ProxyInfo getDefaultProxy() {
   2672         // this information is already available as a world read/writable jvm property
   2673         // so this API change wouldn't have a benifit.  It also breaks the passing
   2674         // of proxy info to all the JVMs.
   2675         // enforceAccessPermission();
   2676         synchronized (mProxyLock) {
   2677             ProxyInfo ret = mGlobalProxy;
   2678             if ((ret == null) && !mDefaultProxyDisabled) ret = mDefaultProxy;
   2679             return ret;
   2680         }
   2681     }
   2682 
   2683     // Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present
   2684     // (e.g. if mGlobalProxy==null fall back to network-specific proxy, if network-specific
   2685     // proxy is null then there is no proxy in place).
   2686     private ProxyInfo canonicalizeProxyInfo(ProxyInfo proxy) {
   2687         if (proxy != null && TextUtils.isEmpty(proxy.getHost())
   2688                 && (proxy.getPacFileUrl() == null || Uri.EMPTY.equals(proxy.getPacFileUrl()))) {
   2689             proxy = null;
   2690         }
   2691         return proxy;
   2692     }
   2693 
   2694     // ProxyInfo equality function with a couple modifications over ProxyInfo.equals() to make it
   2695     // better for determining if a new proxy broadcast is necessary:
   2696     // 1. Canonicalize empty ProxyInfos to null so an empty proxy compares equal to null so as to
   2697     //    avoid unnecessary broadcasts.
   2698     // 2. Make sure all parts of the ProxyInfo's compare true, including the host when a PAC URL
   2699     //    is in place.  This is important so legacy PAC resolver (see com.android.proxyhandler)
   2700     //    changes aren't missed.  The legacy PAC resolver pretends to be a simple HTTP proxy but
   2701     //    actually uses the PAC to resolve; this results in ProxyInfo's with PAC URL, host and port
   2702     //    all set.
   2703     private boolean proxyInfoEqual(ProxyInfo a, ProxyInfo b) {
   2704         a = canonicalizeProxyInfo(a);
   2705         b = canonicalizeProxyInfo(b);
   2706         // ProxyInfo.equals() doesn't check hosts when PAC URLs are present, but we need to check
   2707         // hosts even when PAC URLs are present to account for the legacy PAC resolver.
   2708         return Objects.equals(a, b) && (a == null || Objects.equals(a.getHost(), b.getHost()));
   2709     }
   2710 
   2711     public void setGlobalProxy(ProxyInfo proxyProperties) {
   2712         enforceConnectivityInternalPermission();
   2713 
   2714         synchronized (mProxyLock) {
   2715             if (proxyProperties == mGlobalProxy) return;
   2716             if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return;
   2717             if (mGlobalProxy != null && mGlobalProxy.equals(proxyProperties)) return;
   2718 
   2719             String host = "";
   2720             int port = 0;
   2721             String exclList = "";
   2722             String pacFileUrl = "";
   2723             if (proxyProperties != null && (!TextUtils.isEmpty(proxyProperties.getHost()) ||
   2724                     !Uri.EMPTY.equals(proxyProperties.getPacFileUrl()))) {
   2725                 if (!proxyProperties.isValid()) {
   2726                     if (DBG)
   2727                         log("Invalid proxy properties, ignoring: " + proxyProperties.toString());
   2728                     return;
   2729                 }
   2730                 mGlobalProxy = new ProxyInfo(proxyProperties);
   2731                 host = mGlobalProxy.getHost();
   2732                 port = mGlobalProxy.getPort();
   2733                 exclList = mGlobalProxy.getExclusionListAsString();
   2734                 if (!Uri.EMPTY.equals(proxyProperties.getPacFileUrl())) {
   2735                     pacFileUrl = proxyProperties.getPacFileUrl().toString();
   2736                 }
   2737             } else {
   2738                 mGlobalProxy = null;
   2739             }
   2740             ContentResolver res = mContext.getContentResolver();
   2741             final long token = Binder.clearCallingIdentity();
   2742             try {
   2743                 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, host);
   2744                 Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, port);
   2745                 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
   2746                         exclList);
   2747                 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
   2748             } finally {
   2749                 Binder.restoreCallingIdentity(token);
   2750             }
   2751 
   2752             if (mGlobalProxy == null) {
   2753                 proxyProperties = mDefaultProxy;
   2754             }
   2755             sendProxyBroadcast(proxyProperties);
   2756         }
   2757     }
   2758 
   2759     private void loadGlobalProxy() {
   2760         ContentResolver res = mContext.getContentResolver();
   2761         String host = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST);
   2762         int port = Settings.Global.getInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, 0);
   2763         String exclList = Settings.Global.getString(res,
   2764                 Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
   2765         String pacFileUrl = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC);
   2766         if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) {
   2767             ProxyInfo proxyProperties;
   2768             if (!TextUtils.isEmpty(pacFileUrl)) {
   2769                 proxyProperties = new ProxyInfo(pacFileUrl);
   2770             } else {
   2771                 proxyProperties = new ProxyInfo(host, port, exclList);
   2772             }
   2773             if (!proxyProperties.isValid()) {
   2774                 if (DBG) log("Invalid proxy properties, ignoring: " + proxyProperties.toString());
   2775                 return;
   2776             }
   2777 
   2778             synchronized (mProxyLock) {
   2779                 mGlobalProxy = proxyProperties;
   2780             }
   2781         }
   2782     }
   2783 
   2784     public ProxyInfo getGlobalProxy() {
   2785         // this information is already available as a world read/writable jvm property
   2786         // so this API change wouldn't have a benifit.  It also breaks the passing
   2787         // of proxy info to all the JVMs.
   2788         // enforceAccessPermission();
   2789         synchronized (mProxyLock) {
   2790             return mGlobalProxy;
   2791         }
   2792     }
   2793 
   2794     private void handleApplyDefaultProxy(ProxyInfo proxy) {
   2795         if (proxy != null && TextUtils.isEmpty(proxy.getHost())
   2796                 && Uri.EMPTY.equals(proxy.getPacFileUrl())) {
   2797             proxy = null;
   2798         }
   2799         synchronized (mProxyLock) {
   2800             if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return;
   2801             if (mDefaultProxy == proxy) return; // catches repeated nulls
   2802             if (proxy != null &&  !proxy.isValid()) {
   2803                 if (DBG) log("Invalid proxy properties, ignoring: " + proxy.toString());
   2804                 return;
   2805             }
   2806 
   2807             // This call could be coming from the PacManager, containing the port of the local
   2808             // proxy.  If this new proxy matches the global proxy then copy this proxy to the
   2809             // global (to get the correct local port), and send a broadcast.
   2810             // TODO: Switch PacManager to have its own message to send back rather than
   2811             // reusing EVENT_HAS_CHANGED_PROXY and this call to handleApplyDefaultProxy.
   2812             if ((mGlobalProxy != null) && (proxy != null)
   2813                     && (!Uri.EMPTY.equals(proxy.getPacFileUrl()))
   2814                     && proxy.getPacFileUrl().equals(mGlobalProxy.getPacFileUrl())) {
   2815                 mGlobalProxy = proxy;
   2816                 sendProxyBroadcast(mGlobalProxy);
   2817                 return;
   2818             }
   2819             mDefaultProxy = proxy;
   2820 
   2821             if (mGlobalProxy != null) return;
   2822             if (!mDefaultProxyDisabled) {
   2823                 sendProxyBroadcast(proxy);
   2824             }
   2825         }
   2826     }
   2827 
   2828     // If the proxy has changed from oldLp to newLp, resend proxy broadcast with default proxy.
   2829     // This method gets called when any network changes proxy, but the broadcast only ever contains
   2830     // the default proxy (even if it hasn't changed).
   2831     // TODO: Deprecate the broadcast extras as they aren't necessarily applicable in a multi-network
   2832     // world where an app might be bound to a non-default network.
   2833     private void updateProxy(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai) {
   2834         ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy();
   2835         ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
   2836 
   2837         if (!proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
   2838             sendProxyBroadcast(getDefaultProxy());
   2839         }
   2840     }
   2841 
   2842     private void handleDeprecatedGlobalHttpProxy() {
   2843         String proxy = Settings.Global.getString(mContext.getContentResolver(),
   2844                 Settings.Global.HTTP_PROXY);
   2845         if (!TextUtils.isEmpty(proxy)) {
   2846             String data[] = proxy.split(":");
   2847             if (data.length == 0) {
   2848                 return;
   2849             }
   2850 
   2851             String proxyHost =  data[0];
   2852             int proxyPort = 8080;
   2853             if (data.length > 1) {
   2854                 try {
   2855                     proxyPort = Integer.parseInt(data[1]);
   2856                 } catch (NumberFormatException e) {
   2857                     return;
   2858                 }
   2859             }
   2860             ProxyInfo p = new ProxyInfo(data[0], proxyPort, "");
   2861             setGlobalProxy(p);
   2862         }
   2863     }
   2864 
   2865     private void sendProxyBroadcast(ProxyInfo proxy) {
   2866         if (proxy == null) proxy = new ProxyInfo("", 0, "");
   2867         if (mPacManager.setCurrentProxyScriptUrl(proxy)) return;
   2868         if (DBG) log("sending Proxy Broadcast for " + proxy);
   2869         Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
   2870         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
   2871             Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
   2872         intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy);
   2873         final long ident = Binder.clearCallingIdentity();
   2874         try {
   2875             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
   2876         } finally {
   2877             Binder.restoreCallingIdentity(ident);
   2878         }
   2879     }
   2880 
   2881     private static class SettingsObserver extends ContentObserver {
   2882         private int mWhat;
   2883         private Handler mHandler;
   2884         SettingsObserver(Handler handler, int what) {
   2885             super(handler);
   2886             mHandler = handler;
   2887             mWhat = what;
   2888         }
   2889 
   2890         void observe(Context context) {
   2891             ContentResolver resolver = context.getContentResolver();
   2892             resolver.registerContentObserver(Settings.Global.getUriFor(
   2893                     Settings.Global.HTTP_PROXY), false, this);
   2894         }
   2895 
   2896         @Override
   2897         public void onChange(boolean selfChange) {
   2898             mHandler.obtainMessage(mWhat).sendToTarget();
   2899         }
   2900     }
   2901 
   2902     private static void log(String s) {
   2903         Slog.d(TAG, s);
   2904     }
   2905 
   2906     private static void loge(String s) {
   2907         Slog.e(TAG, s);
   2908     }
   2909 
   2910     private static <T> T checkNotNull(T value, String message) {
   2911         if (value == null) {
   2912             throw new NullPointerException(message);
   2913         }
   2914         return value;
   2915     }
   2916 
   2917     /**
   2918      * Prepare for a VPN application.
   2919      * Permissions are checked in Vpn class.
   2920      * @hide
   2921      */
   2922     @Override
   2923     public boolean prepareVpn(String oldPackage, String newPackage) {
   2924         throwIfLockdownEnabled();
   2925         int user = UserHandle.getUserId(Binder.getCallingUid());
   2926         synchronized(mVpns) {
   2927             return mVpns.get(user).prepare(oldPackage, newPackage);
   2928         }
   2929     }
   2930 
   2931     /**
   2932      * Set whether the current VPN package has the ability to launch VPNs without
   2933      * user intervention. This method is used by system-privileged apps.
   2934      * Permissions are checked in Vpn class.
   2935      * @hide
   2936      */
   2937     @Override
   2938     public void setVpnPackageAuthorization(boolean authorized) {
   2939         int user = UserHandle.getUserId(Binder.getCallingUid());
   2940         synchronized(mVpns) {
   2941             mVpns.get(user).setPackageAuthorization(authorized);
   2942         }
   2943     }
   2944 
   2945     /**
   2946      * Configure a TUN interface and return its file descriptor. Parameters
   2947      * are encoded and opaque to this class. This method is used by VpnBuilder
   2948      * and not available in ConnectivityManager. Permissions are checked in
   2949      * Vpn class.
   2950      * @hide
   2951      */
   2952     @Override
   2953     public ParcelFileDescriptor establishVpn(VpnConfig config) {
   2954         throwIfLockdownEnabled();
   2955         int user = UserHandle.getUserId(Binder.getCallingUid());
   2956         synchronized(mVpns) {
   2957             return mVpns.get(user).establish(config);
   2958         }
   2959     }
   2960 
   2961     /**
   2962      * Start legacy VPN, controlling native daemons as needed. Creates a
   2963      * secondary thread to perform connection work, returning quickly.
   2964      */
   2965     @Override
   2966     public void startLegacyVpn(VpnProfile profile) {
   2967         throwIfLockdownEnabled();
   2968         final LinkProperties egress = getActiveLinkProperties();
   2969         if (egress == null) {
   2970             throw new IllegalStateException("Missing active network connection");
   2971         }
   2972         int user = UserHandle.getUserId(Binder.getCallingUid());
   2973         synchronized(mVpns) {
   2974             mVpns.get(user).startLegacyVpn(profile, mKeyStore, egress);
   2975         }
   2976     }
   2977 
   2978     /**
   2979      * Return the information of the ongoing legacy VPN. This method is used
   2980      * by VpnSettings and not available in ConnectivityManager. Permissions
   2981      * are checked in Vpn class.
   2982      * @hide
   2983      */
   2984     @Override
   2985     public LegacyVpnInfo getLegacyVpnInfo() {
   2986         throwIfLockdownEnabled();
   2987         int user = UserHandle.getUserId(Binder.getCallingUid());
   2988         synchronized(mVpns) {
   2989             return mVpns.get(user).getLegacyVpnInfo();
   2990         }
   2991     }
   2992 
   2993     /**
   2994      * Returns the information of the ongoing VPN. This method is used by VpnDialogs and
   2995      * not available in ConnectivityManager.
   2996      * Permissions are checked in Vpn class.
   2997      * @hide
   2998      */
   2999     @Override
   3000     public VpnConfig getVpnConfig() {
   3001         int user = UserHandle.getUserId(Binder.getCallingUid());
   3002         synchronized(mVpns) {
   3003             return mVpns.get(user).getVpnConfig();
   3004         }
   3005     }
   3006 
   3007     @Override
   3008     public boolean updateLockdownVpn() {
   3009         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
   3010             Slog.w(TAG, "Lockdown VPN only available to AID_SYSTEM");
   3011             return false;
   3012         }
   3013 
   3014         // Tear down existing lockdown if profile was removed
   3015         mLockdownEnabled = LockdownVpnTracker.isEnabled();
   3016         if (mLockdownEnabled) {
   3017             if (!mKeyStore.isUnlocked()) {
   3018                 Slog.w(TAG, "KeyStore locked; unable to create LockdownTracker");
   3019                 return false;
   3020             }
   3021 
   3022             final String profileName = new String(mKeyStore.get(Credentials.LOCKDOWN_VPN));
   3023             final VpnProfile profile = VpnProfile.decode(
   3024                     profileName, mKeyStore.get(Credentials.VPN + profileName));
   3025             int user = UserHandle.getUserId(Binder.getCallingUid());
   3026             synchronized(mVpns) {
   3027                 setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, mVpns.get(user),
   3028                             profile));
   3029             }
   3030         } else {
   3031             setLockdownTracker(null);
   3032         }
   3033 
   3034         return true;
   3035     }
   3036 
   3037     /**
   3038      * Internally set new {@link LockdownVpnTracker}, shutting down any existing
   3039      * {@link LockdownVpnTracker}. Can be {@code null} to disable lockdown.
   3040      */
   3041     private void setLockdownTracker(LockdownVpnTracker tracker) {
   3042         // Shutdown any existing tracker
   3043         final LockdownVpnTracker existing = mLockdownTracker;
   3044         mLockdownTracker = null;
   3045         if (existing != null) {
   3046             existing.shutdown();
   3047         }
   3048 
   3049         try {
   3050             if (tracker != null) {
   3051                 mNetd.setFirewallEnabled(true);
   3052                 mNetd.setFirewallInterfaceRule("lo", true);
   3053                 mLockdownTracker = tracker;
   3054                 mLockdownTracker.init();
   3055             } else {
   3056                 mNetd.setFirewallEnabled(false);
   3057             }
   3058         } catch (RemoteException e) {
   3059             // ignored; NMS lives inside system_server
   3060         }
   3061     }
   3062 
   3063     private void throwIfLockdownEnabled() {
   3064         if (mLockdownEnabled) {
   3065             throw new IllegalStateException("Unavailable in lockdown mode");
   3066         }
   3067     }
   3068 
   3069     public void supplyMessenger(int networkType, Messenger messenger) {
   3070         enforceConnectivityInternalPermission();
   3071 
   3072         if (isNetworkTypeValid(networkType) && mNetTrackers[networkType] != null) {
   3073             mNetTrackers[networkType].supplyMessenger(messenger);
   3074         }
   3075     }
   3076 
   3077     public int findConnectionTypeForIface(String iface) {
   3078         enforceConnectivityInternalPermission();
   3079 
   3080         if (TextUtils.isEmpty(iface)) return ConnectivityManager.TYPE_NONE;
   3081 
   3082         synchronized(mNetworkForNetId) {
   3083             for (int i = 0; i < mNetworkForNetId.size(); i++) {
   3084                 NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
   3085                 LinkProperties lp = nai.linkProperties;
   3086                 if (lp != null && iface.equals(lp.getInterfaceName()) && nai.networkInfo != null) {
   3087                     return nai.networkInfo.getType();
   3088                 }
   3089             }
   3090         }
   3091         return ConnectivityManager.TYPE_NONE;
   3092     }
   3093 
   3094     /**
   3095      * Have mobile data fail fast if enabled.
   3096      *
   3097      * @param enabled DctConstants.ENABLED/DISABLED
   3098      */
   3099     private void setEnableFailFastMobileData(int enabled) {
   3100         int tag;
   3101 
   3102         if (enabled == DctConstants.ENABLED) {
   3103             tag = mEnableFailFastMobileDataTag.incrementAndGet();
   3104         } else {
   3105             tag = mEnableFailFastMobileDataTag.get();
   3106         }
   3107         mHandler.sendMessage(mHandler.obtainMessage(EVENT_ENABLE_FAIL_FAST_MOBILE_DATA, tag,
   3108                          enabled));
   3109     }
   3110 
   3111     @Override
   3112     public int checkMobileProvisioning(int suggestedTimeOutMs) {
   3113         // TODO: Remove?  Any reason to trigger a provisioning check?
   3114         return -1;
   3115     }
   3116 
   3117     private static final String NOTIFICATION_ID = "CaptivePortal.Notification";
   3118     private volatile boolean mIsNotificationVisible = false;
   3119 
   3120     private void setProvNotificationVisible(boolean visible, int networkType, String action) {
   3121         if (DBG) {
   3122             log("setProvNotificationVisible: E visible=" + visible + " networkType=" + networkType
   3123                 + " action=" + action);
   3124         }
   3125         Intent intent = new Intent(action);
   3126         PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
   3127         // Concatenate the range of types onto the range of NetIDs.
   3128         int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE);
   3129         setProvNotificationVisibleIntent(visible, id, networkType, null, pendingIntent);
   3130     }
   3131 
   3132     /**
   3133      * Show or hide network provisioning notificaitons.
   3134      *
   3135      * @param id an identifier that uniquely identifies this notification.  This must match
   3136      *         between show and hide calls.  We use the NetID value but for legacy callers
   3137      *         we concatenate the range of types with the range of NetIDs.
   3138      */
   3139     private void setProvNotificationVisibleIntent(boolean visible, int id, int networkType,
   3140             String extraInfo, PendingIntent intent) {
   3141         if (DBG) {
   3142             log("setProvNotificationVisibleIntent: E visible=" + visible + " networkType=" +
   3143                 networkType + " extraInfo=" + extraInfo);
   3144         }
   3145 
   3146         Resources r = Resources.getSystem();
   3147         NotificationManager notificationManager = (NotificationManager) mContext
   3148             .getSystemService(Context.NOTIFICATION_SERVICE);
   3149 
   3150         if (visible) {
   3151             CharSequence title;
   3152             CharSequence details;
   3153             int icon;
   3154             Notification notification = new Notification();
   3155             switch (networkType) {
   3156                 case ConnectivityManager.TYPE_WIFI:
   3157                     title = r.getString(R.string.wifi_available_sign_in, 0);
   3158                     details = r.getString(R.string.network_available_sign_in_detailed,
   3159                             extraInfo);
   3160                     icon = R.drawable.stat_notify_wifi_in_range;
   3161                     break;
   3162                 case ConnectivityManager.TYPE_MOBILE:
   3163                 case ConnectivityManager.TYPE_MOBILE_HIPRI:
   3164                     title = r.getString(R.string.network_available_sign_in, 0);
   3165                     // TODO: Change this to pull from NetworkInfo once a printable
   3166                     // name has been added to it
   3167                     details = mTelephonyManager.getNetworkOperatorName();
   3168                     icon = R.drawable.stat_notify_rssi_in_range;
   3169                     break;
   3170                 default:
   3171                     title = r.getString(R.string.network_available_sign_in, 0);
   3172                     details = r.getString(R.string.network_available_sign_in_detailed,
   3173                             extraInfo);
   3174                     icon = R.drawable.stat_notify_rssi_in_range;
   3175                     break;
   3176             }
   3177 
   3178             notification.when = 0;
   3179             notification.icon = icon;
   3180             notification.flags = Notification.FLAG_AUTO_CANCEL;
   3181             notification.tickerText = title;
   3182             notification.color = mContext.getResources().getColor(
   3183                     com.android.internal.R.color.system_notification_accent_color);
   3184             notification.setLatestEventInfo(mContext, title, details, notification.contentIntent);
   3185             notification.contentIntent = intent;
   3186 
   3187             try {
   3188                 notificationManager.notify(NOTIFICATION_ID, id, notification);
   3189             } catch (NullPointerException npe) {
   3190                 loge("setNotificaitionVisible: visible notificationManager npe=" + npe);
   3191                 npe.printStackTrace();
   3192             }
   3193         } else {
   3194             try {
   3195                 notificationManager.cancel(NOTIFICATION_ID, id);
   3196             } catch (NullPointerException npe) {
   3197                 loge("setNotificaitionVisible: cancel notificationManager npe=" + npe);
   3198                 npe.printStackTrace();
   3199             }
   3200         }
   3201         mIsNotificationVisible = visible;
   3202     }
   3203 
   3204     /** Location to an updatable file listing carrier provisioning urls.
   3205      *  An example:
   3206      *
   3207      * <?xml version="1.0" encoding="utf-8"?>
   3208      *  <provisioningUrls>
   3209      *   <provisioningUrl mcc="310" mnc="4">http://myserver.com/foo?mdn=%3$s&iccid=%1$s&imei=%2$s</provisioningUrl>
   3210      *   <redirectedUrl mcc="310" mnc="4">http://www.google.com</redirectedUrl>
   3211      *  </provisioningUrls>
   3212      */
   3213     private static final String PROVISIONING_URL_PATH =
   3214             "/data/misc/radio/provisioning_urls.xml";
   3215     private final File mProvisioningUrlFile = new File(PROVISIONING_URL_PATH);
   3216 
   3217     /** XML tag for root element. */
   3218     private static final String TAG_PROVISIONING_URLS = "provisioningUrls";
   3219     /** XML tag for individual url */
   3220     private static final String TAG_PROVISIONING_URL = "provisioningUrl";
   3221     /** XML tag for redirected url */
   3222     private static final String TAG_REDIRECTED_URL = "redirectedUrl";
   3223     /** XML attribute for mcc */
   3224     private static final String ATTR_MCC = "mcc";
   3225     /** XML attribute for mnc */
   3226     private static final String ATTR_MNC = "mnc";
   3227 
   3228     private static final int REDIRECTED_PROVISIONING = 1;
   3229     private static final int PROVISIONING = 2;
   3230 
   3231     private String getProvisioningUrlBaseFromFile(int type) {
   3232         FileReader fileReader = null;
   3233         XmlPullParser parser = null;
   3234         Configuration config = mContext.getResources().getConfiguration();
   3235         String tagType;
   3236 
   3237         switch (type) {
   3238             case PROVISIONING:
   3239                 tagType = TAG_PROVISIONING_URL;
   3240                 break;
   3241             case REDIRECTED_PROVISIONING:
   3242                 tagType = TAG_REDIRECTED_URL;
   3243                 break;
   3244             default:
   3245                 throw new RuntimeException("getProvisioningUrlBaseFromFile: Unexpected parameter " +
   3246                         type);
   3247         }
   3248 
   3249         try {
   3250             fileReader = new FileReader(mProvisioningUrlFile);
   3251             parser = Xml.newPullParser();
   3252             parser.setInput(fileReader);
   3253             XmlUtils.beginDocument(parser, TAG_PROVISIONING_URLS);
   3254 
   3255             while (true) {
   3256                 XmlUtils.nextElement(parser);
   3257 
   3258                 String element = parser.getName();
   3259                 if (element == null) break;
   3260 
   3261                 if (element.equals(tagType)) {
   3262                     String mcc = parser.getAttributeValue(null, ATTR_MCC);
   3263                     try {
   3264                         if (mcc != null && Integer.parseInt(mcc) == config.mcc) {
   3265                             String mnc = parser.getAttributeValue(null, ATTR_MNC);
   3266                             if (mnc != null && Integer.parseInt(mnc) == config.mnc) {
   3267                                 parser.next();
   3268                                 if (parser.getEventType() == XmlPullParser.TEXT) {
   3269                                     return parser.getText();
   3270                                 }
   3271                             }
   3272                         }
   3273                     } catch (NumberFormatException e) {
   3274                         loge("NumberFormatException in getProvisioningUrlBaseFromFile: " + e);
   3275                     }
   3276                 }
   3277             }
   3278             return null;
   3279         } catch (FileNotFoundException e) {
   3280             loge("Carrier Provisioning Urls file not found");
   3281         } catch (XmlPullParserException e) {
   3282             loge("Xml parser exception reading Carrier Provisioning Urls file: " + e);
   3283         } catch (IOException e) {
   3284             loge("I/O exception reading Carrier Provisioning Urls file: " + e);
   3285         } finally {
   3286             if (fileReader != null) {
   3287                 try {
   3288                     fileReader.close();
   3289                 } catch (IOException e) {}
   3290             }
   3291         }
   3292         return null;
   3293     }
   3294 
   3295     @Override
   3296     public String getMobileRedirectedProvisioningUrl() {
   3297         enforceConnectivityInternalPermission();
   3298         String url = getProvisioningUrlBaseFromFile(REDIRECTED_PROVISIONING);
   3299         if (TextUtils.isEmpty(url)) {
   3300             url = mContext.getResources().getString(R.string.mobile_redirected_provisioning_url);
   3301         }
   3302         return url;
   3303     }
   3304 
   3305     @Override
   3306     public String getMobileProvisioningUrl() {
   3307         enforceConnectivityInternalPermission();
   3308         String url = getProvisioningUrlBaseFromFile(PROVISIONING);
   3309         if (TextUtils.isEmpty(url)) {
   3310             url = mContext.getResources().getString(R.string.mobile_provisioning_url);
   3311             log("getMobileProvisioningUrl: mobile_provisioining_url from resource =" + url);
   3312         } else {
   3313             log("getMobileProvisioningUrl: mobile_provisioning_url from File =" + url);
   3314         }
   3315         // populate the iccid, imei and phone number in the provisioning url.
   3316         if (!TextUtils.isEmpty(url)) {
   3317             String phoneNumber = mTelephonyManager.getLine1Number();
   3318             if (TextUtils.isEmpty(phoneNumber)) {
   3319                 phoneNumber = "0000000000";
   3320             }
   3321             url = String.format(url,
   3322                     mTelephonyManager.getSimSerialNumber() /* ICCID */,
   3323                     mTelephonyManager.getDeviceId() /* IMEI */,
   3324                     phoneNumber /* Phone numer */);
   3325         }
   3326 
   3327         return url;
   3328     }
   3329 
   3330     @Override
   3331     public void setProvisioningNotificationVisible(boolean visible, int networkType,
   3332             String action) {
   3333         enforceConnectivityInternalPermission();
   3334         final long ident = Binder.clearCallingIdentity();
   3335         try {
   3336             setProvNotificationVisible(visible, networkType, action);
   3337         } finally {
   3338             Binder.restoreCallingIdentity(ident);
   3339         }
   3340     }
   3341 
   3342     @Override
   3343     public void setAirplaneMode(boolean enable) {
   3344         enforceConnectivityInternalPermission();
   3345         final long ident = Binder.clearCallingIdentity();
   3346         try {
   3347             final ContentResolver cr = mContext.getContentResolver();
   3348             Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, enable ? 1 : 0);
   3349             Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
   3350             intent.putExtra("state", enable);
   3351             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
   3352         } finally {
   3353             Binder.restoreCallingIdentity(ident);
   3354         }
   3355     }
   3356 
   3357     private void onUserStart(int userId) {
   3358         synchronized(mVpns) {
   3359             Vpn userVpn = mVpns.get(userId);
   3360             if (userVpn != null) {
   3361                 loge("Starting user already has a VPN");
   3362                 return;
   3363             }
   3364             userVpn = new Vpn(mHandler.getLooper(), mContext, mNetd, this, userId);
   3365             mVpns.put(userId, userVpn);
   3366         }
   3367     }
   3368 
   3369     private void onUserStop(int userId) {
   3370         synchronized(mVpns) {
   3371             Vpn userVpn = mVpns.get(userId);
   3372             if (userVpn == null) {
   3373                 loge("Stopping user has no VPN");
   3374                 return;
   3375             }
   3376             mVpns.delete(userId);
   3377         }
   3378     }
   3379 
   3380     private BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
   3381         @Override
   3382         public void onReceive(Context context, Intent intent) {
   3383             final String action = intent.getAction();
   3384             final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
   3385             if (userId == UserHandle.USER_NULL) return;
   3386 
   3387             if (Intent.ACTION_USER_STARTING.equals(action)) {
   3388                 onUserStart(userId);
   3389             } else if (Intent.ACTION_USER_STOPPING.equals(action)) {
   3390                 onUserStop(userId);
   3391             }
   3392         }
   3393     };
   3394 
   3395     /* Infrastructure for network sampling */
   3396 
   3397     private void handleNetworkSamplingTimeout() {
   3398 
   3399         if (SAMPLE_DBG) log("Sampling interval elapsed, updating statistics ..");
   3400 
   3401         // initialize list of interfaces ..
   3402         Map<String, SamplingDataTracker.SamplingSnapshot> mapIfaceToSample =
   3403                 new HashMap<String, SamplingDataTracker.SamplingSnapshot>();
   3404         for (NetworkStateTracker tracker : mNetTrackers) {
   3405             if (tracker != null) {
   3406                 String ifaceName = tracker.getNetworkInterfaceName();
   3407                 if (ifaceName != null) {
   3408                     mapIfaceToSample.put(ifaceName, null);
   3409                 }
   3410             }
   3411         }
   3412 
   3413         // Read samples for all interfaces
   3414         SamplingDataTracker.getSamplingSnapshots(mapIfaceToSample);
   3415 
   3416         // process samples for all networks
   3417         for (NetworkStateTracker tracker : mNetTrackers) {
   3418             if (tracker != null) {
   3419                 String ifaceName = tracker.getNetworkInterfaceName();
   3420                 SamplingDataTracker.SamplingSnapshot ss = mapIfaceToSample.get(ifaceName);
   3421                 if (ss != null) {
   3422                     // end the previous sampling cycle
   3423                     tracker.stopSampling(ss);
   3424                     // start a new sampling cycle ..
   3425                     tracker.startSampling(ss);
   3426                 }
   3427             }
   3428         }
   3429 
   3430         if (SAMPLE_DBG) log("Done.");
   3431 
   3432         int samplingIntervalInSeconds = Settings.Global.getInt(mContext.getContentResolver(),
   3433                 Settings.Global.CONNECTIVITY_SAMPLING_INTERVAL_IN_SECONDS,
   3434                 DEFAULT_SAMPLING_INTERVAL_IN_SECONDS);
   3435 
   3436         if (SAMPLE_DBG) {
   3437             log("Setting timer for " + String.valueOf(samplingIntervalInSeconds) + "seconds");
   3438         }
   3439 
   3440         setAlarm(samplingIntervalInSeconds * 1000, mSampleIntervalElapsedIntent);
   3441     }
   3442 
   3443     /**
   3444      * Sets a network sampling alarm.
   3445      */
   3446     void setAlarm(int timeoutInMilliseconds, PendingIntent intent) {
   3447         long wakeupTime = SystemClock.elapsedRealtime() + timeoutInMilliseconds;
   3448         int alarmType;
   3449         if (Resources.getSystem().getBoolean(
   3450                 R.bool.config_networkSamplingWakesDevice)) {
   3451             alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
   3452         } else {
   3453             alarmType = AlarmManager.ELAPSED_REALTIME;
   3454         }
   3455         mAlarmManager.set(alarmType, wakeupTime, intent);
   3456     }
   3457 
   3458     private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos =
   3459             new HashMap<Messenger, NetworkFactoryInfo>();
   3460     private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
   3461             new HashMap<NetworkRequest, NetworkRequestInfo>();
   3462 
   3463     private static class NetworkFactoryInfo {
   3464         public final String name;
   3465         public final Messenger messenger;
   3466         public final AsyncChannel asyncChannel;
   3467 
   3468         public NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel) {
   3469             this.name = name;
   3470             this.messenger = messenger;
   3471             this.asyncChannel = asyncChannel;
   3472         }
   3473     }
   3474 
   3475     /**
   3476      * Tracks info about the requester.
   3477      * Also used to notice when the calling process dies so we can self-expire
   3478      */
   3479     private class NetworkRequestInfo implements IBinder.DeathRecipient {
   3480         static final boolean REQUEST = true;
   3481         static final boolean LISTEN = false;
   3482 
   3483         final NetworkRequest request;
   3484         final PendingIntent mPendingIntent;
   3485         boolean mPendingIntentSent;
   3486         private final IBinder mBinder;
   3487         final int mPid;
   3488         final int mUid;
   3489         final Messenger messenger;
   3490         final boolean isRequest;
   3491 
   3492         NetworkRequestInfo(NetworkRequest r, PendingIntent pi, boolean isRequest) {
   3493             request = r;
   3494             mPendingIntent = pi;
   3495             messenger = null;
   3496             mBinder = null;
   3497             mPid = getCallingPid();
   3498             mUid = getCallingUid();
   3499             this.isRequest = isRequest;
   3500         }
   3501 
   3502         NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, boolean isRequest) {
   3503             super();
   3504             messenger = m;
   3505             request = r;
   3506             mBinder = binder;
   3507             mPid = getCallingPid();
   3508             mUid = getCallingUid();
   3509             this.isRequest = isRequest;
   3510             mPendingIntent = null;
   3511 
   3512             try {
   3513                 mBinder.linkToDeath(this, 0);
   3514             } catch (RemoteException e) {
   3515                 binderDied();
   3516             }
   3517         }
   3518 
   3519         void unlinkDeathRecipient() {
   3520             if (mBinder != null) {
   3521                 mBinder.unlinkToDeath(this, 0);
   3522             }
   3523         }
   3524 
   3525         public void binderDied() {
   3526             log("ConnectivityService NetworkRequestInfo binderDied(" +
   3527                     request + ", " + mBinder + ")");
   3528             releaseNetworkRequest(request);
   3529         }
   3530 
   3531         public String toString() {
   3532             return (isRequest ? "Request" : "Listen") + " from uid/pid:" + mUid + "/" +
   3533                     mPid + " for " + request +
   3534                     (mPendingIntent == null ? "" : " to trigger " + mPendingIntent);
   3535         }
   3536     }
   3537 
   3538     @Override
   3539     public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
   3540             Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
   3541         networkCapabilities = new NetworkCapabilities(networkCapabilities);
   3542         enforceNetworkRequestPermissions(networkCapabilities);
   3543         enforceMeteredApnPolicy(networkCapabilities);
   3544 
   3545         if (timeoutMs < 0 || timeoutMs > ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_MS) {
   3546             throw new IllegalArgumentException("Bad timeout specified");
   3547         }
   3548 
   3549         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
   3550                 nextNetworkRequestId());
   3551         if (DBG) log("requestNetwork for " + networkRequest);
   3552         NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
   3553                 NetworkRequestInfo.REQUEST);
   3554 
   3555         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
   3556         if (timeoutMs > 0) {
   3557             mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NETWORK_REQUEST,
   3558                     nri), timeoutMs);
   3559         }
   3560         return networkRequest;
   3561     }
   3562 
   3563     private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) {
   3564         if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
   3565                 == false) {
   3566             enforceConnectivityInternalPermission();
   3567         } else {
   3568             enforceChangePermission();
   3569         }
   3570     }
   3571 
   3572     private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) {
   3573         // if UID is restricted, don't allow them to bring up metered APNs
   3574         if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
   3575                 == false) {
   3576             final int uidRules;
   3577             final int uid = Binder.getCallingUid();
   3578             synchronized(mRulesLock) {
   3579                 uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
   3580             }
   3581             if ((uidRules & RULE_REJECT_METERED) != 0) {
   3582                 // we could silently fail or we can filter the available nets to only give
   3583                 // them those they have access to.  Chose the more useful
   3584                 networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
   3585             }
   3586         }
   3587     }
   3588 
   3589     @Override
   3590     public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
   3591             PendingIntent operation) {
   3592         checkNotNull(operation, "PendingIntent cannot be null.");
   3593         networkCapabilities = new NetworkCapabilities(networkCapabilities);
   3594         enforceNetworkRequestPermissions(networkCapabilities);
   3595         enforceMeteredApnPolicy(networkCapabilities);
   3596 
   3597         NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
   3598                 nextNetworkRequestId());
   3599         if (DBG) log("pendingRequest for " + networkRequest + " to trigger " + operation);
   3600         NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation,
   3601                 NetworkRequestInfo.REQUEST);
   3602         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT,
   3603                 nri));
   3604         return networkRequest;
   3605     }
   3606 
   3607     private void releasePendingNetworkRequestWithDelay(PendingIntent operation) {
   3608         mHandler.sendMessageDelayed(
   3609                 mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
   3610                 getCallingUid(), 0, operation), mReleasePendingIntentDelayMs);
   3611     }
   3612 
   3613     @Override
   3614     public void releasePendingNetworkRequest(PendingIntent operation) {
   3615         mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
   3616                 getCallingUid(), 0, operation));
   3617     }
   3618 
   3619     @Override
   3620     public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
   3621             Messenger messenger, IBinder binder) {
   3622         enforceAccessPermission();
   3623 
   3624         NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
   3625                 networkCapabilities), TYPE_NONE, nextNetworkRequestId());
   3626         if (DBG) log("listenForNetwork for " + networkRequest);
   3627         NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
   3628                 NetworkRequestInfo.LISTEN);
   3629 
   3630         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
   3631         return networkRequest;
   3632     }
   3633 
   3634     @Override
   3635     public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
   3636             PendingIntent operation) {
   3637     }
   3638 
   3639     @Override
   3640     public void releaseNetworkRequest(NetworkRequest networkRequest) {
   3641         mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST, getCallingUid(),
   3642                 0, networkRequest));
   3643     }
   3644 
   3645     @Override
   3646     public void registerNetworkFactory(Messenger messenger, String name) {
   3647         enforceConnectivityInternalPermission();
   3648         NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel());
   3649         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi));
   3650     }
   3651 
   3652     private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) {
   3653         if (DBG) log("Got NetworkFactory Messenger for " + nfi.name);
   3654         mNetworkFactoryInfos.put(nfi.messenger, nfi);
   3655         nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger);
   3656     }
   3657 
   3658     @Override
   3659     public void unregisterNetworkFactory(Messenger messenger) {
   3660         enforceConnectivityInternalPermission();
   3661         mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger));
   3662     }
   3663 
   3664     private void handleUnregisterNetworkFactory(Messenger messenger) {
   3665         NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(messenger);
   3666         if (nfi == null) {
   3667             loge("Failed to find Messenger in unregisterNetworkFactory");
   3668             return;
   3669         }
   3670         if (DBG) log("unregisterNetworkFactory for " + nfi.name);
   3671     }
   3672 
   3673     /**
   3674      * NetworkAgentInfo supporting a request by requestId.
   3675      * These have already been vetted (their Capabilities satisfy the request)
   3676      * and the are the highest scored network available.
   3677      * the are keyed off the Requests requestId.
   3678      */
   3679     private final SparseArray<NetworkAgentInfo> mNetworkForRequestId =
   3680             new SparseArray<NetworkAgentInfo>();
   3681 
   3682     private final SparseArray<NetworkAgentInfo> mNetworkForNetId =
   3683             new SparseArray<NetworkAgentInfo>();
   3684 
   3685     // NetworkAgentInfo keyed off its connecting messenger
   3686     // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays
   3687     private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos =
   3688             new HashMap<Messenger, NetworkAgentInfo>();
   3689 
   3690     // Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
   3691     private final NetworkRequest mDefaultRequest;
   3692 
   3693     private NetworkAgentInfo getDefaultNetwork() {
   3694         return mNetworkForRequestId.get(mDefaultRequest.requestId);
   3695     }
   3696 
   3697     private boolean isDefaultNetwork(NetworkAgentInfo nai) {
   3698         return nai == getDefaultNetwork();
   3699     }
   3700 
   3701     public void registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
   3702             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
   3703             int currentScore, NetworkMisc networkMisc) {
   3704         enforceConnectivityInternalPermission();
   3705 
   3706         // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
   3707         // satisfies mDefaultRequest.
   3708         NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
   3709             new NetworkInfo(networkInfo), new LinkProperties(linkProperties),
   3710             new NetworkCapabilities(networkCapabilities), currentScore, mContext, mTrackerHandler,
   3711             new NetworkMisc(networkMisc), mDefaultRequest);
   3712         synchronized (this) {
   3713             nai.networkMonitor.systemReady = mSystemReady;
   3714         }
   3715         if (DBG) log("registerNetworkAgent " + nai);
   3716         mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
   3717     }
   3718 
   3719     private void handleRegisterNetworkAgent(NetworkAgentInfo na) {
   3720         if (VDBG) log("Got NetworkAgent Messenger");
   3721         mNetworkAgentInfos.put(na.messenger, na);
   3722         assignNextNetId(na);
   3723         na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
   3724         NetworkInfo networkInfo = na.networkInfo;
   3725         na.networkInfo = null;
   3726         updateNetworkInfo(na, networkInfo);
   3727     }
   3728 
   3729     private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties oldLp) {
   3730         LinkProperties newLp = networkAgent.linkProperties;
   3731         int netId = networkAgent.network.netId;
   3732 
   3733         // The NetworkAgentInfo does not know whether clatd is running on its network or not. Before
   3734         // we do anything else, make sure its LinkProperties are accurate.
   3735         if (networkAgent.clatd != null) {
   3736             networkAgent.clatd.fixupLinkProperties(oldLp);
   3737         }
   3738 
   3739         updateInterfaces(newLp, oldLp, netId);
   3740         updateMtu(newLp, oldLp);
   3741         // TODO - figure out what to do for clat
   3742 //        for (LinkProperties lp : newLp.getStackedLinks()) {
   3743 //            updateMtu(lp, null);
   3744 //        }
   3745         updateTcpBufferSizes(networkAgent);
   3746 
   3747         // TODO: deprecate and remove mDefaultDns when we can do so safely.
   3748         // For now, use it only when the network has Internet access. http://b/18327075
   3749         final boolean useDefaultDns = networkAgent.networkCapabilities.hasCapability(
   3750                 NetworkCapabilities.NET_CAPABILITY_INTERNET);
   3751         final boolean flushDns = updateRoutes(newLp, oldLp, netId);
   3752         updateDnses(newLp, oldLp, netId, flushDns, useDefaultDns);
   3753 
   3754         updateClat(newLp, oldLp, networkAgent);
   3755         if (isDefaultNetwork(networkAgent)) {
   3756             handleApplyDefaultProxy(newLp.getHttpProxy());
   3757         } else {
   3758             updateProxy(newLp, oldLp, networkAgent);
   3759         }
   3760         // TODO - move this check to cover the whole function
   3761         if (!Objects.equals(newLp, oldLp)) {
   3762             notifyIfacesChanged();
   3763             notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
   3764         }
   3765     }
   3766 
   3767     private void updateClat(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai) {
   3768         final boolean wasRunningClat = nai.clatd != null && nai.clatd.isStarted();
   3769         final boolean shouldRunClat = Nat464Xlat.requiresClat(nai);
   3770 
   3771         if (!wasRunningClat && shouldRunClat) {
   3772             nai.clatd = new Nat464Xlat(mContext, mNetd, mTrackerHandler, nai);
   3773             nai.clatd.start();
   3774         } else if (wasRunningClat && !shouldRunClat) {
   3775             nai.clatd.stop();
   3776         }
   3777     }
   3778 
   3779     private void updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId) {
   3780         CompareResult<String> interfaceDiff = new CompareResult<String>();
   3781         if (oldLp != null) {
   3782             interfaceDiff = oldLp.compareAllInterfaceNames(newLp);
   3783         } else if (newLp != null) {
   3784             interfaceDiff.added = newLp.getAllInterfaceNames();
   3785         }
   3786         for (String iface : interfaceDiff.added) {
   3787             try {
   3788                 if (DBG) log("Adding iface " + iface + " to network " + netId);
   3789                 mNetd.addInterfaceToNetwork(iface, netId);
   3790             } catch (Exception e) {
   3791                 loge("Exception adding interface: " + e);
   3792             }
   3793         }
   3794         for (String iface : interfaceDiff.removed) {
   3795             try {
   3796                 if (DBG) log("Removing iface " + iface + " from network " + netId);
   3797                 mNetd.removeInterfaceFromNetwork(iface, netId);
   3798             } catch (Exception e) {
   3799                 loge("Exception removing interface: " + e);
   3800             }
   3801         }
   3802     }
   3803 
   3804     /**
   3805      * Have netd update routes from oldLp to newLp.
   3806      * @return true if routes changed between oldLp and newLp
   3807      */
   3808     private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
   3809         CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
   3810         if (oldLp != null) {
   3811             routeDiff = oldLp.compareAllRoutes(newLp);
   3812         } else if (newLp != null) {
   3813             routeDiff.added = newLp.getAllRoutes();
   3814         }
   3815 
   3816         // add routes before removing old in case it helps with continuous connectivity
   3817 
   3818         // do this twice, adding non-nexthop routes first, then routes they are dependent on
   3819         for (RouteInfo route : routeDiff.added) {
   3820             if (route.hasGateway()) continue;
   3821             if (DBG) log("Adding Route [" + route + "] to network " + netId);
   3822             try {
   3823                 mNetd.addRoute(netId, route);
   3824             } catch (Exception e) {
   3825                 if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) {
   3826                     loge("Exception in addRoute for non-gateway: " + e);
   3827                 }
   3828             }
   3829         }
   3830         for (RouteInfo route : routeDiff.added) {
   3831             if (route.hasGateway() == false) continue;
   3832             if (DBG) log("Adding Route [" + route + "] to network " + netId);
   3833             try {
   3834                 mNetd.addRoute(netId, route);
   3835             } catch (Exception e) {
   3836                 if ((route.getGateway() instanceof Inet4Address) || VDBG) {
   3837                     loge("Exception in addRoute for gateway: " + e);
   3838                 }
   3839             }
   3840         }
   3841 
   3842         for (RouteInfo route : routeDiff.removed) {
   3843             if (DBG) log("Removing Route [" + route + "] from network " + netId);
   3844             try {
   3845                 mNetd.removeRoute(netId, route);
   3846             } catch (Exception e) {
   3847                 loge("Exception in removeRoute: " + e);
   3848             }
   3849         }
   3850         return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty();
   3851     }
   3852     private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId,
   3853                              boolean flush, boolean useDefaultDns) {
   3854         if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) {
   3855             Collection<InetAddress> dnses = newLp.getDnsServers();
   3856             if (dnses.size() == 0 && mDefaultDns != null && useDefaultDns) {
   3857                 dnses = new ArrayList();
   3858                 dnses.add(mDefaultDns);
   3859                 if (DBG) {
   3860                     loge("no dns provided for netId " + netId + ", so using defaults");
   3861                 }
   3862             }
   3863             if (DBG) log("Setting Dns servers for network " + netId + " to " + dnses);
   3864             try {
   3865                 mNetd.setDnsServersForNetwork(netId, NetworkUtils.makeStrings(dnses),
   3866                     newLp.getDomains());
   3867             } catch (Exception e) {
   3868                 loge("Exception in setDnsServersForNetwork: " + e);
   3869             }
   3870             NetworkAgentInfo defaultNai = mNetworkForRequestId.get(mDefaultRequest.requestId);
   3871             if (defaultNai != null && defaultNai.network.netId == netId) {
   3872                 setDefaultDnsSystemProperties(dnses);
   3873             }
   3874             flushVmDnsCache();
   3875         } else if (flush) {
   3876             try {
   3877                 mNetd.flushNetworkDnsCache(netId);
   3878             } catch (Exception e) {
   3879                 loge("Exception in flushNetworkDnsCache: " + e);
   3880             }
   3881             flushVmDnsCache();
   3882         }
   3883     }
   3884 
   3885     private void setDefaultDnsSystemProperties(Collection<InetAddress> dnses) {
   3886         int last = 0;
   3887         for (InetAddress dns : dnses) {
   3888             ++last;
   3889             String key = "net.dns" + last;
   3890             String value = dns.getHostAddress();
   3891             SystemProperties.set(key, value);
   3892         }
   3893         for (int i = last + 1; i <= mNumDnsEntries; ++i) {
   3894             String key = "net.dns" + i;
   3895             SystemProperties.set(key, "");
   3896         }
   3897         mNumDnsEntries = last;
   3898     }
   3899 
   3900     private void updateCapabilities(NetworkAgentInfo networkAgent,
   3901             NetworkCapabilities networkCapabilities) {
   3902         if (!Objects.equals(networkAgent.networkCapabilities, networkCapabilities)) {
   3903             synchronized (networkAgent) {
   3904                 networkAgent.networkCapabilities = networkCapabilities;
   3905             }
   3906             rematchAllNetworksAndRequests(networkAgent, networkAgent.getCurrentScore());
   3907             notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_CAP_CHANGED);
   3908         }
   3909     }
   3910 
   3911     private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) {
   3912         for (int i = 0; i < nai.networkRequests.size(); i++) {
   3913             NetworkRequest nr = nai.networkRequests.valueAt(i);
   3914             // Don't send listening requests to factories. b/17393458
   3915             if (!isRequest(nr)) continue;
   3916             sendUpdatedScoreToFactories(nr, nai.getCurrentScore());
   3917         }
   3918     }
   3919 
   3920     private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) {
   3921         if (VDBG) log("sending new Min Network Score(" + score + "): " + networkRequest.toString());
   3922         for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
   3923             nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, 0,
   3924                     networkRequest);
   3925         }
   3926     }
   3927 
   3928     private void sendPendingIntentForRequest(NetworkRequestInfo nri, NetworkAgentInfo networkAgent,
   3929             int notificationType) {
   3930         if (notificationType == ConnectivityManager.CALLBACK_AVAILABLE && !nri.mPendingIntentSent) {
   3931             Intent intent = new Intent();
   3932             intent.putExtra(ConnectivityManager.EXTRA_NETWORK, networkAgent.network);
   3933             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_REQUEST, nri.request);
   3934             nri.mPendingIntentSent = true;
   3935             sendIntent(nri.mPendingIntent, intent);
   3936         }
   3937         // else not handled
   3938     }
   3939 
   3940     private void sendIntent(PendingIntent pendingIntent, Intent intent) {
   3941         mPendingIntentWakeLock.acquire();
   3942         try {
   3943             if (DBG) log("Sending " + pendingIntent);
   3944             pendingIntent.send(mContext, 0, intent, this /* onFinished */, null /* Handler */);
   3945         } catch (PendingIntent.CanceledException e) {
   3946             if (DBG) log(pendingIntent + " was not sent, it had been canceled.");
   3947             mPendingIntentWakeLock.release();
   3948             releasePendingNetworkRequest(pendingIntent);
   3949         }
   3950         // ...otherwise, mPendingIntentWakeLock.release() gets called by onSendFinished()
   3951     }
   3952 
   3953     @Override
   3954     public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode,
   3955             String resultData, Bundle resultExtras) {
   3956         if (DBG) log("Finished sending " + pendingIntent);
   3957         mPendingIntentWakeLock.release();
   3958         // Release with a delay so the receiving client has an opportunity to put in its
   3959         // own request.
   3960         releasePendingNetworkRequestWithDelay(pendingIntent);
   3961     }
   3962 
   3963     private void callCallbackForRequest(NetworkRequestInfo nri,
   3964             NetworkAgentInfo networkAgent, int notificationType) {
   3965         if (nri.messenger == null) return;  // Default request has no msgr
   3966         Bundle bundle = new Bundle();
   3967         bundle.putParcelable(NetworkRequest.class.getSimpleName(),
   3968                 new NetworkRequest(nri.request));
   3969         Message msg = Message.obtain();
   3970         if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL &&
   3971                 notificationType != ConnectivityManager.CALLBACK_RELEASED) {
   3972             bundle.putParcelable(Network.class.getSimpleName(), networkAgent.network);
   3973         }
   3974         switch (notificationType) {
   3975             case ConnectivityManager.CALLBACK_LOSING: {
   3976                 msg.arg1 = 30 * 1000; // TODO - read this from NetworkMonitor
   3977                 break;
   3978             }
   3979             case ConnectivityManager.CALLBACK_CAP_CHANGED: {
   3980                 bundle.putParcelable(NetworkCapabilities.class.getSimpleName(),
   3981                         new NetworkCapabilities(networkAgent.networkCapabilities));
   3982                 break;
   3983             }
   3984             case ConnectivityManager.CALLBACK_IP_CHANGED: {
   3985                 bundle.putParcelable(LinkProperties.class.getSimpleName(),
   3986                         new LinkProperties(networkAgent.linkProperties));
   3987                 break;
   3988             }
   3989         }
   3990         msg.what = notificationType;
   3991         msg.setData(bundle);
   3992         try {
   3993             if (VDBG) {
   3994                 log("sending notification " + notifyTypeToName(notificationType) +
   3995                         " for " + nri.request);
   3996             }
   3997             nri.messenger.send(msg);
   3998         } catch (RemoteException e) {
   3999             // may occur naturally in the race of binder death.
   4000             loge("RemoteException caught trying to send a callback msg for " + nri.request);
   4001         }
   4002     }
   4003 
   4004     private void teardownUnneededNetwork(NetworkAgentInfo nai) {
   4005         for (int i = 0; i < nai.networkRequests.size(); i++) {
   4006             NetworkRequest nr = nai.networkRequests.valueAt(i);
   4007             // Ignore listening requests.
   4008             if (!isRequest(nr)) continue;
   4009             loge("Dead network still had at least " + nr);
   4010             break;
   4011         }
   4012         nai.asyncChannel.disconnect();
   4013     }
   4014 
   4015     private void handleLingerComplete(NetworkAgentInfo oldNetwork) {
   4016         if (oldNetwork == null) {
   4017             loge("Unknown NetworkAgentInfo in handleLingerComplete");
   4018             return;
   4019         }
   4020         if (DBG) log("handleLingerComplete for " + oldNetwork.name());
   4021         teardownUnneededNetwork(oldNetwork);
   4022     }
   4023 
   4024     private void makeDefault(NetworkAgentInfo newNetwork) {
   4025         if (DBG) log("Switching to new default network: " + newNetwork);
   4026         setupDataActivityTracking(newNetwork);
   4027         try {
   4028             mNetd.setDefaultNetId(newNetwork.network.netId);
   4029         } catch (Exception e) {
   4030             loge("Exception setting default network :" + e);
   4031         }
   4032         notifyLockdownVpn(newNetwork);
   4033         handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy());
   4034         updateTcpBufferSizes(newNetwork);
   4035         setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers());
   4036     }
   4037 
   4038     // Handles a network appearing or improving its score.
   4039     //
   4040     // - Evaluates all current NetworkRequests that can be
   4041     //   satisfied by newNetwork, and reassigns to newNetwork
   4042     //   any such requests for which newNetwork is the best.
   4043     //
   4044     // - Lingers any validated Networks that as a result are no longer
   4045     //   needed. A network is needed if it is the best network for
   4046     //   one or more NetworkRequests, or if it is a VPN.
   4047     //
   4048     // - Tears down newNetwork if it just became validated
   4049     //   (i.e. nascent==JUST_VALIDATED) but turns out to be unneeded.
   4050     //
   4051     // - If reapUnvalidatedNetworks==REAP, tears down unvalidated
   4052     //   networks that have no chance (i.e. even if validated)
   4053     //   of becoming the highest scoring network.
   4054     //
   4055     // NOTE: This function only adds NetworkRequests that "newNetwork" could satisfy,
   4056     // it does not remove NetworkRequests that other Networks could better satisfy.
   4057     // If you need to handle decreases in score, use {@link rematchAllNetworksAndRequests}.
   4058     // This function should be used when possible instead of {@code rematchAllNetworksAndRequests}
   4059     // as it performs better by a factor of the number of Networks.
   4060     //
   4061     // @param newNetwork is the network to be matched against NetworkRequests.
   4062     // @param nascent indicates if newNetwork just became validated, in which case it should be
   4063     //               torn down if unneeded.
   4064     // @param reapUnvalidatedNetworks indicates if an additional pass over all networks should be
   4065     //               performed to tear down unvalidated networks that have no chance (i.e. even if
   4066     //               validated) of becoming the highest scoring network.
   4067     private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork, NascentState nascent,
   4068             ReapUnvalidatedNetworks reapUnvalidatedNetworks) {
   4069         if (!newNetwork.created) return;
   4070         if (nascent == NascentState.JUST_VALIDATED && !newNetwork.everValidated) {
   4071             loge("ERROR: nascent network not validated.");
   4072         }
   4073         boolean keep = newNetwork.isVPN();
   4074         boolean isNewDefault = false;
   4075         NetworkAgentInfo oldDefaultNetwork = null;
   4076         if (DBG) log("rematching " + newNetwork.name());
   4077         // Find and migrate to this Network any NetworkRequests for
   4078         // which this network is now the best.
   4079         ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<NetworkAgentInfo>();
   4080         if (VDBG) log(" network has: " + newNetwork.networkCapabilities);
   4081         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
   4082             NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId);
   4083             if (newNetwork == currentNetwork) {
   4084                 if (DBG) {
   4085                     log("Network " + newNetwork.name() + " was already satisfying" +
   4086                             " request " + nri.request.requestId + ". No change.");
   4087                 }
   4088                 keep = true;
   4089                 continue;
   4090             }
   4091 
   4092             // check if it satisfies the NetworkCapabilities
   4093             if (VDBG) log("  checking if request is satisfied: " + nri.request);
   4094             if (newNetwork.satisfies(nri.request)) {
   4095                 if (!nri.isRequest) {
   4096                     // This is not a request, it's a callback listener.
   4097                     // Add it to newNetwork regardless of score.
   4098                     newNetwork.addRequest(nri.request);
   4099                     continue;
   4100                 }
   4101 
   4102                 // next check if it's better than any current network we're using for
   4103                 // this request
   4104                 if (VDBG) {
   4105                     log("currentScore = " +
   4106                             (currentNetwork != null ? currentNetwork.getCurrentScore() : 0) +
   4107                             ", newScore = " + newNetwork.getCurrentScore());
   4108                 }
   4109                 if (currentNetwork == null ||
   4110                         currentNetwork.getCurrentScore() < newNetwork.getCurrentScore()) {
   4111                     if (currentNetwork != null) {
   4112                         if (DBG) log("   accepting network in place of " + currentNetwork.name());
   4113                         currentNetwork.networkRequests.remove(nri.request.requestId);
   4114                         currentNetwork.networkLingered.add(nri.request);
   4115                         affectedNetworks.add(currentNetwork);
   4116                     } else {
   4117                         if (DBG) log("   accepting network in place of null");
   4118                     }
   4119                     unlinger(newNetwork);
   4120                     mNetworkForRequestId.put(nri.request.requestId, newNetwork);
   4121                     newNetwork.addRequest(nri.request);
   4122                     keep = true;
   4123                     // Tell NetworkFactories about the new score, so they can stop
   4124                     // trying to connect if they know they cannot match it.
   4125                     // TODO - this could get expensive if we have alot of requests for this
   4126                     // network.  Think about if there is a way to reduce this.  Push
   4127                     // netid->request mapping to each factory?
   4128                     sendUpdatedScoreToFactories(nri.request, newNetwork.getCurrentScore());
   4129                     if (mDefaultRequest.requestId == nri.request.requestId) {
   4130                         isNewDefault = true;
   4131                         oldDefaultNetwork = currentNetwork;
   4132                     }
   4133                 }
   4134             }
   4135         }
   4136         // Linger any networks that are no longer needed.
   4137         for (NetworkAgentInfo nai : affectedNetworks) {
   4138             if (nai.everValidated && unneeded(nai)) {
   4139                 nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_LINGER);
   4140                 notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING);
   4141             } else {
   4142                 unlinger(nai);
   4143             }
   4144         }
   4145         if (keep) {
   4146             if (isNewDefault) {
   4147                 // Notify system services that this network is up.
   4148                 makeDefault(newNetwork);
   4149                 synchronized (ConnectivityService.this) {
   4150                     // have a new default network, release the transition wakelock in
   4151                     // a second if it's held.  The second pause is to allow apps
   4152                     // to reconnect over the new network
   4153                     if (mNetTransitionWakeLock.isHeld()) {
   4154                         mHandler.sendMessageDelayed(mHandler.obtainMessage(
   4155                                 EVENT_CLEAR_NET_TRANSITION_WAKELOCK,
   4156                                 mNetTransitionWakeLockSerialNumber, 0),
   4157                                 1000);
   4158                     }
   4159                 }
   4160             }
   4161 
   4162             // do this after the default net is switched, but
   4163             // before LegacyTypeTracker sends legacy broadcasts
   4164             notifyNetworkCallbacks(newNetwork, ConnectivityManager.CALLBACK_AVAILABLE);
   4165 
   4166             if (isNewDefault) {
   4167                 // Maintain the illusion: since the legacy API only
   4168                 // understands one network at a time, we must pretend
   4169                 // that the current default network disconnected before
   4170                 // the new one connected.
   4171                 if (oldDefaultNetwork != null) {
   4172                     mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
   4173                                               oldDefaultNetwork);
   4174                 }
   4175                 mDefaultInetConditionPublished = newNetwork.everValidated ? 100 : 0;
   4176                 mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork);
   4177                 notifyLockdownVpn(newNetwork);
   4178             }
   4179 
   4180             // Notify battery stats service about this network, both the normal
   4181             // interface and any stacked links.
   4182             // TODO: Avoid redoing this; this must only be done once when a network comes online.
   4183             try {
   4184                 final IBatteryStats bs = BatteryStatsService.getService();
   4185                 final int type = newNetwork.networkInfo.getType();
   4186 
   4187                 final String baseIface = newNetwork.linkProperties.getInterfaceName();
   4188                 bs.noteNetworkInterfaceType(baseIface, type);
   4189                 for (LinkProperties stacked : newNetwork.linkProperties.getStackedLinks()) {
   4190                     final String stackedIface = stacked.getInterfaceName();
   4191                     bs.noteNetworkInterfaceType(stackedIface, type);
   4192                     NetworkStatsFactory.noteStackedIface(stackedIface, baseIface);
   4193                 }
   4194             } catch (RemoteException ignored) {
   4195             }
   4196 
   4197             // This has to happen after the notifyNetworkCallbacks as that tickles each
   4198             // ConnectivityManager instance so that legacy requests correctly bind dns
   4199             // requests to this network.  The legacy users are listening for this bcast
   4200             // and will generally do a dns request so they can ensureRouteToHost and if
   4201             // they do that before the callbacks happen they'll use the default network.
   4202             //
   4203             // TODO: Is there still a race here? We send the broadcast
   4204             // after sending the callback, but if the app can receive the
   4205             // broadcast before the callback, it might still break.
   4206             //
   4207             // This *does* introduce a race where if the user uses the new api
   4208             // (notification callbacks) and then uses the old api (getNetworkInfo(type))
   4209             // they may get old info.  Reverse this after the old startUsing api is removed.
   4210             // This is on top of the multiple intent sequencing referenced in the todo above.
   4211             for (int i = 0; i < newNetwork.networkRequests.size(); i++) {
   4212                 NetworkRequest nr = newNetwork.networkRequests.valueAt(i);
   4213                 if (nr.legacyType != TYPE_NONE && isRequest(nr)) {
   4214                     // legacy type tracker filters out repeat adds
   4215                     mLegacyTypeTracker.add(nr.legacyType, newNetwork);
   4216                 }
   4217             }
   4218 
   4219             // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above,
   4220             // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest
   4221             // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the
   4222             // newNetwork to the tracker explicitly (it's a no-op if it has already been added).
   4223             if (newNetwork.isVPN()) {
   4224                 mLegacyTypeTracker.add(TYPE_VPN, newNetwork);
   4225             }
   4226         } else if (nascent == NascentState.JUST_VALIDATED) {
   4227             // Only tear down newly validated networks here.  Leave unvalidated to either become
   4228             // validated (and get evaluated against peers, one losing here), or get reaped (see
   4229             // reapUnvalidatedNetworks) if they have no chance of becoming the highest scoring
   4230             // network.  Networks that have been up for a while and are validated should be torn
   4231             // down via the lingering process so communication on that network is given time to
   4232             // wrap up.
   4233             if (DBG) log("Validated network turns out to be unwanted.  Tear it down.");
   4234             teardownUnneededNetwork(newNetwork);
   4235         }
   4236         if (reapUnvalidatedNetworks == ReapUnvalidatedNetworks.REAP) {
   4237             for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
   4238                 if (!nai.everValidated && unneeded(nai)) {
   4239                     if (DBG) log("Reaping " + nai.name());
   4240                     teardownUnneededNetwork(nai);
   4241                 }
   4242             }
   4243         }
   4244     }
   4245 
   4246     // Attempt to rematch all Networks with NetworkRequests.  This may result in Networks
   4247     // being disconnected.
   4248     // If only one Network's score or capabilities have been modified since the last time
   4249     // this function was called, pass this Network in via the "changed" arugment, otherwise
   4250     // pass null.
   4251     // If only one Network has been changed but its NetworkCapabilities have not changed,
   4252     // pass in the Network's score (from getCurrentScore()) prior to the change via
   4253     // "oldScore", otherwise pass changed.getCurrentScore() or 0 if "changed" is null.
   4254     private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore) {
   4255         // TODO: This may get slow.  The "changed" parameter is provided for future optimization
   4256         // to avoid the slowness.  It is not simply enough to process just "changed", for
   4257         // example in the case where "changed"'s score decreases and another network should begin
   4258         // satifying a NetworkRequest that "changed" currently satisfies.
   4259 
   4260         // Optimization: Only reprocess "changed" if its score improved.  This is safe because it
   4261         // can only add more NetworkRequests satisfied by "changed", and this is exactly what
   4262         // rematchNetworkAndRequests() handles.
   4263         if (changed != null && oldScore < changed.getCurrentScore()) {
   4264             rematchNetworkAndRequests(changed, NascentState.NOT_JUST_VALIDATED,
   4265                     ReapUnvalidatedNetworks.REAP);
   4266         } else {
   4267             for (Iterator i = mNetworkAgentInfos.values().iterator(); i.hasNext(); ) {
   4268                 rematchNetworkAndRequests((NetworkAgentInfo)i.next(),
   4269                         NascentState.NOT_JUST_VALIDATED,
   4270                         // Only reap the last time through the loop.  Reaping before all rematching
   4271                         // is complete could incorrectly teardown a network that hasn't yet been
   4272                         // rematched.
   4273                         i.hasNext() ? ReapUnvalidatedNetworks.DONT_REAP
   4274                                 : ReapUnvalidatedNetworks.REAP);
   4275             }
   4276         }
   4277     }
   4278 
   4279     private void updateInetCondition(NetworkAgentInfo nai) {
   4280         // Don't bother updating until we've graduated to validated at least once.
   4281         if (!nai.everValidated) return;
   4282         // For now only update icons for default connection.
   4283         // TODO: Update WiFi and cellular icons separately. b/17237507
   4284         if (!isDefaultNetwork(nai)) return;
   4285 
   4286         int newInetCondition = nai.lastValidated ? 100 : 0;
   4287         // Don't repeat publish.
   4288         if (newInetCondition == mDefaultInetConditionPublished) return;
   4289 
   4290         mDefaultInetConditionPublished = newInetCondition;
   4291         sendInetConditionBroadcast(nai.networkInfo);
   4292     }
   4293 
   4294     private void notifyLockdownVpn(NetworkAgentInfo nai) {
   4295         if (mLockdownTracker != null) {
   4296             if (nai != null && nai.isVPN()) {
   4297                 mLockdownTracker.onVpnStateChanged(nai.networkInfo);
   4298             } else {
   4299                 mLockdownTracker.onNetworkInfoChanged();
   4300             }
   4301         }
   4302     }
   4303 
   4304     private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo) {
   4305         NetworkInfo.State state = newInfo.getState();
   4306         NetworkInfo oldInfo = null;
   4307         synchronized (networkAgent) {
   4308             oldInfo = networkAgent.networkInfo;
   4309             networkAgent.networkInfo = newInfo;
   4310         }
   4311         notifyLockdownVpn(networkAgent);
   4312 
   4313         if (oldInfo != null && oldInfo.getState() == state) {
   4314             if (VDBG) log("ignoring duplicate network state non-change");
   4315             return;
   4316         }
   4317         if (DBG) {
   4318             log(networkAgent.name() + " EVENT_NETWORK_INFO_CHANGED, going from " +
   4319                     (oldInfo == null ? "null" : oldInfo.getState()) +
   4320                     " to " + state);
   4321         }
   4322 
   4323         if (state == NetworkInfo.State.CONNECTED && !networkAgent.created) {
   4324             try {
   4325                 // This should never fail.  Specifying an already in use NetID will cause failure.
   4326                 if (networkAgent.isVPN()) {
   4327                     mNetd.createVirtualNetwork(networkAgent.network.netId,
   4328                             !networkAgent.linkProperties.getDnsServers().isEmpty(),
   4329                             (networkAgent.networkMisc == null ||
   4330                                 !networkAgent.networkMisc.allowBypass));
   4331                 } else {
   4332                     mNetd.createPhysicalNetwork(networkAgent.network.netId);
   4333                 }
   4334             } catch (Exception e) {
   4335                 loge("Error creating network " + networkAgent.network.netId + ": "
   4336                         + e.getMessage());
   4337                 return;
   4338             }
   4339             networkAgent.created = true;
   4340             updateLinkProperties(networkAgent, null);
   4341             notifyIfacesChanged();
   4342             notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
   4343             networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
   4344             if (networkAgent.isVPN()) {
   4345                 // Temporarily disable the default proxy (not global).
   4346                 synchronized (mProxyLock) {
   4347                     if (!mDefaultProxyDisabled) {
   4348                         mDefaultProxyDisabled = true;
   4349                         if (mGlobalProxy == null && mDefaultProxy != null) {
   4350                             sendProxyBroadcast(null);
   4351                         }
   4352                     }
   4353                 }
   4354                 // TODO: support proxy per network.
   4355             }
   4356             // Consider network even though it is not yet validated.
   4357             rematchNetworkAndRequests(networkAgent, NascentState.NOT_JUST_VALIDATED,
   4358                     ReapUnvalidatedNetworks.REAP);
   4359         } else if (state == NetworkInfo.State.DISCONNECTED ||
   4360                 state == NetworkInfo.State.SUSPENDED) {
   4361             networkAgent.asyncChannel.disconnect();
   4362             if (networkAgent.isVPN()) {
   4363                 synchronized (mProxyLock) {
   4364                     if (mDefaultProxyDisabled) {
   4365                         mDefaultProxyDisabled = false;
   4366                         if (mGlobalProxy == null && mDefaultProxy != null) {
   4367                             sendProxyBroadcast(mDefaultProxy);
   4368                         }
   4369                     }
   4370                 }
   4371             }
   4372         }
   4373     }
   4374 
   4375     private void updateNetworkScore(NetworkAgentInfo nai, int score) {
   4376         if (DBG) log("updateNetworkScore for " + nai.name() + " to " + score);
   4377         if (score < 0) {
   4378             loge("updateNetworkScore for " + nai.name() + " got a negative score (" + score +
   4379                     ").  Bumping score to min of 0");
   4380             score = 0;
   4381         }
   4382 
   4383         final int oldScore = nai.getCurrentScore();
   4384         nai.setCurrentScore(score);
   4385 
   4386         rematchAllNetworksAndRequests(nai, oldScore);
   4387 
   4388         sendUpdatedScoreToFactories(nai);
   4389     }
   4390 
   4391     // notify only this one new request of the current state
   4392     protected void notifyNetworkCallback(NetworkAgentInfo nai, NetworkRequestInfo nri) {
   4393         int notifyType = ConnectivityManager.CALLBACK_AVAILABLE;
   4394         // TODO - read state from monitor to decide what to send.
   4395 //        if (nai.networkMonitor.isLingering()) {
   4396 //            notifyType = NetworkCallbacks.LOSING;
   4397 //        } else if (nai.networkMonitor.isEvaluating()) {
   4398 //            notifyType = NetworkCallbacks.callCallbackForRequest(request, nai, notifyType);
   4399 //        }
   4400         if (nri.mPendingIntent == null) {
   4401             callCallbackForRequest(nri, nai, notifyType);
   4402         } else {
   4403             sendPendingIntentForRequest(nri, nai, notifyType);
   4404         }
   4405     }
   4406 
   4407     private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, boolean connected, int type) {
   4408         // The NetworkInfo we actually send out has no bearing on the real
   4409         // state of affairs. For example, if the default connection is mobile,
   4410         // and a request for HIPRI has just gone away, we need to pretend that
   4411         // HIPRI has just disconnected. So we need to set the type to HIPRI and
   4412         // the state to DISCONNECTED, even though the network is of type MOBILE
   4413         // and is still connected.
   4414         NetworkInfo info = new NetworkInfo(nai.networkInfo);
   4415         info.setType(type);
   4416         if (connected) {
   4417             info.setDetailedState(DetailedState.CONNECTED, null, info.getExtraInfo());
   4418             sendConnectedBroadcast(info);
   4419         } else {
   4420             info.setDetailedState(DetailedState.DISCONNECTED, null, info.getExtraInfo());
   4421             Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
   4422             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
   4423             intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
   4424             if (info.isFailover()) {
   4425                 intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
   4426                 nai.networkInfo.setFailover(false);
   4427             }
   4428             if (info.getReason() != null) {
   4429                 intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
   4430             }
   4431             if (info.getExtraInfo() != null) {
   4432                 intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
   4433             }
   4434             NetworkAgentInfo newDefaultAgent = null;
   4435             if (nai.networkRequests.get(mDefaultRequest.requestId) != null) {
   4436                 newDefaultAgent = mNetworkForRequestId.get(mDefaultRequest.requestId);
   4437                 if (newDefaultAgent != null) {
   4438                     intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
   4439                             newDefaultAgent.networkInfo);
   4440                 } else {
   4441                     intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
   4442                 }
   4443             }
   4444             intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
   4445                     mDefaultInetConditionPublished);
   4446             final Intent immediateIntent = new Intent(intent);
   4447             immediateIntent.setAction(CONNECTIVITY_ACTION_IMMEDIATE);
   4448             sendStickyBroadcast(immediateIntent);
   4449             sendStickyBroadcast(intent);
   4450             if (newDefaultAgent != null) {
   4451                 sendConnectedBroadcast(newDefaultAgent.networkInfo);
   4452             }
   4453         }
   4454     }
   4455 
   4456     protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
   4457         if (DBG) log("notifyType " + notifyTypeToName(notifyType) + " for " + networkAgent.name());
   4458         for (int i = 0; i < networkAgent.networkRequests.size(); i++) {
   4459             NetworkRequest nr = networkAgent.networkRequests.valueAt(i);
   4460             NetworkRequestInfo nri = mNetworkRequests.get(nr);
   4461             if (VDBG) log(" sending notification for " + nr);
   4462             if (nri.mPendingIntent == null) {
   4463                 callCallbackForRequest(nri, networkAgent, notifyType);
   4464             } else {
   4465                 sendPendingIntentForRequest(nri, networkAgent, notifyType);
   4466             }
   4467         }
   4468     }
   4469 
   4470     private String notifyTypeToName(int notifyType) {
   4471         switch (notifyType) {
   4472             case ConnectivityManager.CALLBACK_PRECHECK:    return "PRECHECK";
   4473             case ConnectivityManager.CALLBACK_AVAILABLE:   return "AVAILABLE";
   4474             case ConnectivityManager.CALLBACK_LOSING:      return "LOSING";
   4475             case ConnectivityManager.CALLBACK_LOST:        return "LOST";
   4476             case ConnectivityManager.CALLBACK_UNAVAIL:     return "UNAVAILABLE";
   4477             case ConnectivityManager.CALLBACK_CAP_CHANGED: return "CAP_CHANGED";
   4478             case ConnectivityManager.CALLBACK_IP_CHANGED:  return "IP_CHANGED";
   4479             case ConnectivityManager.CALLBACK_RELEASED:    return "RELEASED";
   4480         }
   4481         return "UNKNOWN";
   4482     }
   4483 
   4484     /**
   4485      * Notify other system services that set of active ifaces has changed.
   4486      */
   4487     private void notifyIfacesChanged() {
   4488         try {
   4489             mStatsService.forceUpdateIfaces();
   4490         } catch (Exception ignored) {
   4491         }
   4492     }
   4493 
   4494     @Override
   4495     public boolean addVpnAddress(String address, int prefixLength) {
   4496         throwIfLockdownEnabled();
   4497         int user = UserHandle.getUserId(Binder.getCallingUid());
   4498         synchronized (mVpns) {
   4499             return mVpns.get(user).addAddress(address, prefixLength);
   4500         }
   4501     }
   4502 
   4503     @Override
   4504     public boolean removeVpnAddress(String address, int prefixLength) {
   4505         throwIfLockdownEnabled();
   4506         int user = UserHandle.getUserId(Binder.getCallingUid());
   4507         synchronized (mVpns) {
   4508             return mVpns.get(user).removeAddress(address, prefixLength);
   4509         }
   4510     }
   4511 
   4512     @Override
   4513     public boolean setUnderlyingNetworksForVpn(Network[] networks) {
   4514         throwIfLockdownEnabled();
   4515         int user = UserHandle.getUserId(Binder.getCallingUid());
   4516         synchronized (mVpns) {
   4517             return mVpns.get(user).setUnderlyingNetworks(networks);
   4518         }
   4519     }
   4520 }
   4521