Home | History | Annotate | Download | only in net
      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 package android.net;
     17 
     18 import static com.android.internal.util.Preconditions.checkNotNull;
     19 
     20 import android.annotation.SdkConstant;
     21 import android.annotation.SdkConstant.SdkConstantType;
     22 import android.app.PendingIntent;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.net.NetworkUtils;
     26 import android.os.Binder;
     27 import android.os.Build.VERSION_CODES;
     28 import android.os.Bundle;
     29 import android.os.Handler;
     30 import android.os.HandlerThread;
     31 import android.os.IBinder;
     32 import android.os.INetworkActivityListener;
     33 import android.os.INetworkManagementService;
     34 import android.os.Looper;
     35 import android.os.Message;
     36 import android.os.Messenger;
     37 import android.os.RemoteException;
     38 import android.os.ServiceManager;
     39 import android.provider.Settings;
     40 import android.telephony.TelephonyManager;
     41 import android.util.ArrayMap;
     42 import android.util.Log;
     43 
     44 import com.android.internal.telephony.ITelephony;
     45 import com.android.internal.telephony.PhoneConstants;
     46 import com.android.internal.util.Protocol;
     47 
     48 import java.net.InetAddress;
     49 import java.util.concurrent.atomic.AtomicInteger;
     50 import java.util.HashMap;
     51 
     52 import libcore.net.event.NetworkEventDispatcher;
     53 
     54 /**
     55  * Class that answers queries about the state of network connectivity. It also
     56  * notifies applications when network connectivity changes. Get an instance
     57  * of this class by calling
     58  * {@link android.content.Context#getSystemService(String) Context.getSystemService(Context.CONNECTIVITY_SERVICE)}.
     59  * <p>
     60  * The primary responsibilities of this class are to:
     61  * <ol>
     62  * <li>Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)</li>
     63  * <li>Send broadcast intents when network connectivity changes</li>
     64  * <li>Attempt to "fail over" to another network when connectivity to a network
     65  * is lost</li>
     66  * <li>Provide an API that allows applications to query the coarse-grained or fine-grained
     67  * state of the available networks</li>
     68  * <li>Provide an API that allows applications to request and select networks for their data
     69  * traffic</li>
     70  * </ol>
     71  */
     72 public class ConnectivityManager {
     73     private static final String TAG = "ConnectivityManager";
     74     private static final boolean LEGACY_DBG = true; // STOPSHIP
     75 
     76     /**
     77      * A change in network connectivity has occurred. A default connection has either
     78      * been established or lost. The NetworkInfo for the affected network is
     79      * sent as an extra; it should be consulted to see what kind of
     80      * connectivity event occurred.
     81      * <p/>
     82      * If this is a connection that was the result of failing over from a
     83      * disconnected network, then the FAILOVER_CONNECTION boolean extra is
     84      * set to true.
     85      * <p/>
     86      * For a loss of connectivity, if the connectivity manager is attempting
     87      * to connect (or has already connected) to another network, the
     88      * NetworkInfo for the new network is also passed as an extra. This lets
     89      * any receivers of the broadcast know that they should not necessarily
     90      * tell the user that no data traffic will be possible. Instead, the
     91      * receiver should expect another broadcast soon, indicating either that
     92      * the failover attempt succeeded (and so there is still overall data
     93      * connectivity), or that the failover attempt failed, meaning that all
     94      * connectivity has been lost.
     95      * <p/>
     96      * For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY
     97      * is set to {@code true} if there are no connected networks at all.
     98      */
     99     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    100     public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
    101 
    102     /**
    103      * Identical to {@link #CONNECTIVITY_ACTION} broadcast, but sent without any
    104      * applicable {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY}.
    105      *
    106      * @hide
    107      */
    108     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    109     public static final String CONNECTIVITY_ACTION_IMMEDIATE =
    110             "android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE";
    111 
    112     /**
    113      * The lookup key for a {@link NetworkInfo} object. Retrieve with
    114      * {@link android.content.Intent#getParcelableExtra(String)}.
    115      *
    116      * @deprecated Since {@link NetworkInfo} can vary based on UID, applications
    117      *             should always obtain network information through
    118      *             {@link #getActiveNetworkInfo()} or
    119      *             {@link #getAllNetworkInfo()}.
    120      * @see #EXTRA_NETWORK_TYPE
    121      */
    122     @Deprecated
    123     public static final String EXTRA_NETWORK_INFO = "networkInfo";
    124 
    125     /**
    126      * Network type which triggered a {@link #CONNECTIVITY_ACTION} broadcast.
    127      * Can be used with {@link #getNetworkInfo(int)} to get {@link NetworkInfo}
    128      * state based on the calling application.
    129      *
    130      * @see android.content.Intent#getIntExtra(String, int)
    131      */
    132     public static final String EXTRA_NETWORK_TYPE = "networkType";
    133 
    134     /**
    135      * The lookup key for a boolean that indicates whether a connect event
    136      * is for a network to which the connectivity manager was failing over
    137      * following a disconnect on another network.
    138      * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
    139      */
    140     public static final String EXTRA_IS_FAILOVER = "isFailover";
    141     /**
    142      * The lookup key for a {@link NetworkInfo} object. This is supplied when
    143      * there is another network that it may be possible to connect to. Retrieve with
    144      * {@link android.content.Intent#getParcelableExtra(String)}.
    145      */
    146     public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
    147     /**
    148      * The lookup key for a boolean that indicates whether there is a
    149      * complete lack of connectivity, i.e., no network is available.
    150      * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
    151      */
    152     public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
    153     /**
    154      * The lookup key for a string that indicates why an attempt to connect
    155      * to a network failed. The string has no particular structure. It is
    156      * intended to be used in notifications presented to users. Retrieve
    157      * it with {@link android.content.Intent#getStringExtra(String)}.
    158      */
    159     public static final String EXTRA_REASON = "reason";
    160     /**
    161      * The lookup key for a string that provides optionally supplied
    162      * extra information about the network state. The information
    163      * may be passed up from the lower networking layers, and its
    164      * meaning may be specific to a particular network type. Retrieve
    165      * it with {@link android.content.Intent#getStringExtra(String)}.
    166      */
    167     public static final String EXTRA_EXTRA_INFO = "extraInfo";
    168     /**
    169      * The lookup key for an int that provides information about
    170      * our connection to the internet at large.  0 indicates no connection,
    171      * 100 indicates a great connection.  Retrieve it with
    172      * {@link android.content.Intent#getIntExtra(String, int)}.
    173      * {@hide}
    174      */
    175     public static final String EXTRA_INET_CONDITION = "inetCondition";
    176 
    177     /**
    178      * Broadcast action to indicate the change of data activity status
    179      * (idle or active) on a network in a recent period.
    180      * The network becomes active when data transmission is started, or
    181      * idle if there is no data transmission for a period of time.
    182      * {@hide}
    183      */
    184     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    185     public static final String ACTION_DATA_ACTIVITY_CHANGE = "android.net.conn.DATA_ACTIVITY_CHANGE";
    186     /**
    187      * The lookup key for an enum that indicates the network device type on which this data activity
    188      * change happens.
    189      * {@hide}
    190      */
    191     public static final String EXTRA_DEVICE_TYPE = "deviceType";
    192     /**
    193      * The lookup key for a boolean that indicates the device is active or not. {@code true} means
    194      * it is actively sending or receiving data and {@code false} means it is idle.
    195      * {@hide}
    196      */
    197     public static final String EXTRA_IS_ACTIVE = "isActive";
    198     /**
    199      * The lookup key for a long that contains the timestamp (nanos) of the radio state change.
    200      * {@hide}
    201      */
    202     public static final String EXTRA_REALTIME_NS = "tsNanos";
    203 
    204     /**
    205      * Broadcast Action: The setting for background data usage has changed
    206      * values. Use {@link #getBackgroundDataSetting()} to get the current value.
    207      * <p>
    208      * If an application uses the network in the background, it should listen
    209      * for this broadcast and stop using the background data if the value is
    210      * {@code false}.
    211      * <p>
    212      *
    213      * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability
    214      *             of background data depends on several combined factors, and
    215      *             this broadcast is no longer sent. Instead, when background
    216      *             data is unavailable, {@link #getActiveNetworkInfo()} will now
    217      *             appear disconnected. During first boot after a platform
    218      *             upgrade, this broadcast will be sent once if
    219      *             {@link #getBackgroundDataSetting()} was {@code false} before
    220      *             the upgrade.
    221      */
    222     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    223     @Deprecated
    224     public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED =
    225             "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
    226 
    227     /**
    228      * Broadcast Action: The network connection may not be good
    229      * uses {@code ConnectivityManager.EXTRA_INET_CONDITION} and
    230      * {@code ConnectivityManager.EXTRA_NETWORK_INFO} to specify
    231      * the network and it's condition.
    232      * @hide
    233      */
    234     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    235     public static final String INET_CONDITION_ACTION =
    236             "android.net.conn.INET_CONDITION_ACTION";
    237 
    238     /**
    239      * Broadcast Action: A tetherable connection has come or gone.
    240      * Uses {@code ConnectivityManager.EXTRA_AVAILABLE_TETHER},
    241      * {@code ConnectivityManager.EXTRA_ACTIVE_TETHER} and
    242      * {@code ConnectivityManager.EXTRA_ERRORED_TETHER} to indicate
    243      * the current state of tethering.  Each include a list of
    244      * interface names in that state (may be empty).
    245      * @hide
    246      */
    247     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    248     public static final String ACTION_TETHER_STATE_CHANGED =
    249             "android.net.conn.TETHER_STATE_CHANGED";
    250 
    251     /**
    252      * @hide
    253      * gives a String[] listing all the interfaces configured for
    254      * tethering and currently available for tethering.
    255      */
    256     public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
    257 
    258     /**
    259      * @hide
    260      * gives a String[] listing all the interfaces currently tethered
    261      * (ie, has dhcp support and packets potentially forwarded/NATed)
    262      */
    263     public static final String EXTRA_ACTIVE_TETHER = "activeArray";
    264 
    265     /**
    266      * @hide
    267      * gives a String[] listing all the interfaces we tried to tether and
    268      * failed.  Use {@link #getLastTetherError} to find the error code
    269      * for any interfaces listed here.
    270      */
    271     public static final String EXTRA_ERRORED_TETHER = "erroredArray";
    272 
    273     /**
    274      * Broadcast Action: The captive portal tracker has finished its test.
    275      * Sent only while running Setup Wizard, in lieu of showing a user
    276      * notification.
    277      * @hide
    278      */
    279     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    280     public static final String ACTION_CAPTIVE_PORTAL_TEST_COMPLETED =
    281             "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED";
    282     /**
    283      * The lookup key for a boolean that indicates whether a captive portal was detected.
    284      * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
    285      * @hide
    286      */
    287     public static final String EXTRA_IS_CAPTIVE_PORTAL = "captivePortal";
    288 
    289     /**
    290      * The absence of a connection type.
    291      * @hide
    292      */
    293     public static final int TYPE_NONE        = -1;
    294 
    295     /**
    296      * The Mobile data connection.  When active, all data traffic
    297      * will use this network type's interface by default
    298      * (it has a default route)
    299      */
    300     public static final int TYPE_MOBILE      = 0;
    301     /**
    302      * The WIFI data connection.  When active, all data traffic
    303      * will use this network type's interface by default
    304      * (it has a default route).
    305      */
    306     public static final int TYPE_WIFI        = 1;
    307     /**
    308      * An MMS-specific Mobile data connection.  This network type may use the
    309      * same network interface as {@link #TYPE_MOBILE} or it may use a different
    310      * one.  This is used by applications needing to talk to the carrier's
    311      * Multimedia Messaging Service servers.
    312      */
    313     public static final int TYPE_MOBILE_MMS  = 2;
    314     /**
    315      * A SUPL-specific Mobile data connection.  This network type may use the
    316      * same network interface as {@link #TYPE_MOBILE} or it may use a different
    317      * one.  This is used by applications needing to talk to the carrier's
    318      * Secure User Plane Location servers for help locating the device.
    319      */
    320     public static final int TYPE_MOBILE_SUPL = 3;
    321     /**
    322      * A DUN-specific Mobile data connection.  This network type may use the
    323      * same network interface as {@link #TYPE_MOBILE} or it may use a different
    324      * one.  This is sometimes by the system when setting up an upstream connection
    325      * for tethering so that the carrier is aware of DUN traffic.
    326      */
    327     public static final int TYPE_MOBILE_DUN  = 4;
    328     /**
    329      * A High Priority Mobile data connection.  This network type uses the
    330      * same network interface as {@link #TYPE_MOBILE} but the routing setup
    331      * is different.  Only requesting processes will have access to the
    332      * Mobile DNS servers and only IP's explicitly requested via {@link #requestRouteToHost}
    333      * will route over this interface if no default route exists.
    334      */
    335     public static final int TYPE_MOBILE_HIPRI = 5;
    336     /**
    337      * The WiMAX data connection.  When active, all data traffic
    338      * will use this network type's interface by default
    339      * (it has a default route).
    340      */
    341     public static final int TYPE_WIMAX       = 6;
    342 
    343     /**
    344      * The Bluetooth data connection.  When active, all data traffic
    345      * will use this network type's interface by default
    346      * (it has a default route).
    347      */
    348     public static final int TYPE_BLUETOOTH   = 7;
    349 
    350     /**
    351      * Dummy data connection.  This should not be used on shipping devices.
    352      */
    353     public static final int TYPE_DUMMY       = 8;
    354 
    355     /**
    356      * The Ethernet data connection.  When active, all data traffic
    357      * will use this network type's interface by default
    358      * (it has a default route).
    359      */
    360     public static final int TYPE_ETHERNET    = 9;
    361 
    362     /**
    363      * Over the air Administration.
    364      * {@hide}
    365      */
    366     public static final int TYPE_MOBILE_FOTA = 10;
    367 
    368     /**
    369      * IP Multimedia Subsystem.
    370      * {@hide}
    371      */
    372     public static final int TYPE_MOBILE_IMS  = 11;
    373 
    374     /**
    375      * Carrier Branded Services.
    376      * {@hide}
    377      */
    378     public static final int TYPE_MOBILE_CBS  = 12;
    379 
    380     /**
    381      * A Wi-Fi p2p connection. Only requesting processes will have access to
    382      * the peers connected.
    383      * {@hide}
    384      */
    385     public static final int TYPE_WIFI_P2P    = 13;
    386 
    387     /**
    388      * The network to use for initially attaching to the network
    389      * {@hide}
    390      */
    391     public static final int TYPE_MOBILE_IA = 14;
    392 
    393 /**
    394      * Emergency PDN connection for emergency calls
    395      * {@hide}
    396      */
    397     public static final int TYPE_MOBILE_EMERGENCY = 15;
    398 
    399     /**
    400      * The network that uses proxy to achieve connectivity.
    401      * {@hide}
    402      */
    403     public static final int TYPE_PROXY = 16;
    404 
    405     /**
    406      * A virtual network using one or more native bearers.
    407      * It may or may not be providing security services.
    408      */
    409     public static final int TYPE_VPN = 17;
    410 
    411     /** {@hide} */
    412     public static final int MAX_RADIO_TYPE   = TYPE_VPN;
    413 
    414     /** {@hide} */
    415     public static final int MAX_NETWORK_TYPE = TYPE_VPN;
    416 
    417     /**
    418      * If you want to set the default network preference,you can directly
    419      * change the networkAttributes array in framework's config.xml.
    420      *
    421      * @deprecated Since we support so many more networks now, the single
    422      *             network default network preference can't really express
    423      *             the hierarchy.  Instead, the default is defined by the
    424      *             networkAttributes in config.xml.  You can determine
    425      *             the current value by calling {@link #getNetworkPreference()}
    426      *             from an App.
    427      */
    428     @Deprecated
    429     public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
    430 
    431     /**
    432      * Default value for {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY} in
    433      * milliseconds.  This was introduced because IPv6 routes seem to take a
    434      * moment to settle - trying network activity before the routes are adjusted
    435      * can lead to packets using the wrong interface or having the wrong IP address.
    436      * This delay is a bit crude, but in the future hopefully we will have kernel
    437      * notifications letting us know when it's safe to use the new network.
    438      *
    439      * @hide
    440      */
    441     public static final int CONNECTIVITY_CHANGE_DELAY_DEFAULT = 3000;
    442 
    443     /**
    444      * @hide
    445      */
    446     public final static int REQUEST_ID_UNSET = 0;
    447 
    448     /**
    449      * A NetID indicating no Network is selected.
    450      * Keep in sync with bionic/libc/dns/include/resolv_netid.h
    451      * @hide
    452      */
    453     public static final int NETID_UNSET = 0;
    454 
    455     private final IConnectivityManager mService;
    456 
    457     private INetworkManagementService mNMService;
    458 
    459     /**
    460      * Tests if a given integer represents a valid network type.
    461      * @param networkType the type to be tested
    462      * @return a boolean.  {@code true} if the type is valid, else {@code false}
    463      */
    464     public static boolean isNetworkTypeValid(int networkType) {
    465         return networkType >= 0 && networkType <= MAX_NETWORK_TYPE;
    466     }
    467 
    468     /**
    469      * Returns a non-localized string representing a given network type.
    470      * ONLY used for debugging output.
    471      * @param type the type needing naming
    472      * @return a String for the given type, or a string version of the type ("87")
    473      * if no name is known.
    474      * {@hide}
    475      */
    476     public static String getNetworkTypeName(int type) {
    477         switch (type) {
    478             case TYPE_MOBILE:
    479                 return "MOBILE";
    480             case TYPE_WIFI:
    481                 return "WIFI";
    482             case TYPE_MOBILE_MMS:
    483                 return "MOBILE_MMS";
    484             case TYPE_MOBILE_SUPL:
    485                 return "MOBILE_SUPL";
    486             case TYPE_MOBILE_DUN:
    487                 return "MOBILE_DUN";
    488             case TYPE_MOBILE_HIPRI:
    489                 return "MOBILE_HIPRI";
    490             case TYPE_WIMAX:
    491                 return "WIMAX";
    492             case TYPE_BLUETOOTH:
    493                 return "BLUETOOTH";
    494             case TYPE_DUMMY:
    495                 return "DUMMY";
    496             case TYPE_ETHERNET:
    497                 return "ETHERNET";
    498             case TYPE_MOBILE_FOTA:
    499                 return "MOBILE_FOTA";
    500             case TYPE_MOBILE_IMS:
    501                 return "MOBILE_IMS";
    502             case TYPE_MOBILE_CBS:
    503                 return "MOBILE_CBS";
    504             case TYPE_WIFI_P2P:
    505                 return "WIFI_P2P";
    506             case TYPE_MOBILE_IA:
    507                 return "MOBILE_IA";
    508             case TYPE_MOBILE_EMERGENCY:
    509                 return "MOBILE_EMERGENCY";
    510             case TYPE_PROXY:
    511                 return "PROXY";
    512             default:
    513                 return Integer.toString(type);
    514         }
    515     }
    516 
    517     /**
    518      * Checks if a given type uses the cellular data connection.
    519      * This should be replaced in the future by a network property.
    520      * @param networkType the type to check
    521      * @return a boolean - {@code true} if uses cellular network, else {@code false}
    522      * {@hide}
    523      */
    524     public static boolean isNetworkTypeMobile(int networkType) {
    525         switch (networkType) {
    526             case TYPE_MOBILE:
    527             case TYPE_MOBILE_MMS:
    528             case TYPE_MOBILE_SUPL:
    529             case TYPE_MOBILE_DUN:
    530             case TYPE_MOBILE_HIPRI:
    531             case TYPE_MOBILE_FOTA:
    532             case TYPE_MOBILE_IMS:
    533             case TYPE_MOBILE_CBS:
    534             case TYPE_MOBILE_IA:
    535             case TYPE_MOBILE_EMERGENCY:
    536                 return true;
    537             default:
    538                 return false;
    539         }
    540     }
    541 
    542     /**
    543      * Checks if the given network type is backed by a Wi-Fi radio.
    544      *
    545      * @hide
    546      */
    547     public static boolean isNetworkTypeWifi(int networkType) {
    548         switch (networkType) {
    549             case TYPE_WIFI:
    550             case TYPE_WIFI_P2P:
    551                 return true;
    552             default:
    553                 return false;
    554         }
    555     }
    556 
    557     /**
    558      * Specifies the preferred network type.  When the device has more
    559      * than one type available the preferred network type will be used.
    560      *
    561      * @param preference the network type to prefer over all others.  It is
    562      *         unspecified what happens to the old preferred network in the
    563      *         overall ordering.
    564      * @deprecated Functionality has been removed as it no longer makes sense,
    565      *             with many more than two networks - we'd need an array to express
    566      *             preference.  Instead we use dynamic network properties of
    567      *             the networks to describe their precedence.
    568      */
    569     public void setNetworkPreference(int preference) {
    570     }
    571 
    572     /**
    573      * Retrieves the current preferred network type.
    574      *
    575      * @return an integer representing the preferred network type
    576      *
    577      * <p>This method requires the caller to hold the permission
    578      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    579      * @deprecated Functionality has been removed as it no longer makes sense,
    580      *             with many more than two networks - we'd need an array to express
    581      *             preference.  Instead we use dynamic network properties of
    582      *             the networks to describe their precedence.
    583      */
    584     public int getNetworkPreference() {
    585         return TYPE_NONE;
    586     }
    587 
    588     /**
    589      * Returns details about the currently active default data network. When
    590      * connected, this network is the default route for outgoing connections.
    591      * You should always check {@link NetworkInfo#isConnected()} before initiating
    592      * network traffic. This may return {@code null} when there is no default
    593      * network.
    594      *
    595      * @return a {@link NetworkInfo} object for the current default network
    596      *        or {@code null} if no network default network is currently active
    597      *
    598      * <p>This method requires the call to hold the permission
    599      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    600      */
    601     public NetworkInfo getActiveNetworkInfo() {
    602         try {
    603             return mService.getActiveNetworkInfo();
    604         } catch (RemoteException e) {
    605             return null;
    606         }
    607     }
    608 
    609     /**
    610      * Returns details about the currently active default data network
    611      * for a given uid.  This is for internal use only to avoid spying
    612      * other apps.
    613      *
    614      * @return a {@link NetworkInfo} object for the current default network
    615      *        for the given uid or {@code null} if no default network is
    616      *        available for the specified uid.
    617      *
    618      * <p>This method requires the caller to hold the permission
    619      * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}
    620      * {@hide}
    621      */
    622     public NetworkInfo getActiveNetworkInfoForUid(int uid) {
    623         try {
    624             return mService.getActiveNetworkInfoForUid(uid);
    625         } catch (RemoteException e) {
    626             return null;
    627         }
    628     }
    629 
    630     /**
    631      * Returns connection status information about a particular
    632      * network type.
    633      *
    634      * @param networkType integer specifying which networkType in
    635      *        which you're interested.
    636      * @return a {@link NetworkInfo} object for the requested
    637      *        network type or {@code null} if the type is not
    638      *        supported by the device.
    639      *
    640      * <p>This method requires the caller to hold the permission
    641      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    642      */
    643     public NetworkInfo getNetworkInfo(int networkType) {
    644         try {
    645             return mService.getNetworkInfo(networkType);
    646         } catch (RemoteException e) {
    647             return null;
    648         }
    649     }
    650 
    651     /**
    652      * Returns connection status information about a particular
    653      * Network.
    654      *
    655      * @param network {@link Network} specifying which network
    656      *        in which you're interested.
    657      * @return a {@link NetworkInfo} object for the requested
    658      *        network or {@code null} if the {@code Network}
    659      *        is not valid.
    660      *
    661      * <p>This method requires the caller to hold the permission
    662      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    663      */
    664     public NetworkInfo getNetworkInfo(Network network) {
    665         try {
    666             return mService.getNetworkInfoForNetwork(network);
    667         } catch (RemoteException e) {
    668             return null;
    669         }
    670     }
    671 
    672     /**
    673      * Returns connection status information about all network
    674      * types supported by the device.
    675      *
    676      * @return an array of {@link NetworkInfo} objects.  Check each
    677      * {@link NetworkInfo#getType} for which type each applies.
    678      *
    679      * <p>This method requires the caller to hold the permission
    680      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    681      */
    682     public NetworkInfo[] getAllNetworkInfo() {
    683         try {
    684             return mService.getAllNetworkInfo();
    685         } catch (RemoteException e) {
    686             return null;
    687         }
    688     }
    689 
    690     /**
    691      * Returns the {@link Network} object currently serving a given type, or
    692      * null if the given type is not connected.
    693      *
    694      * <p>This method requires the caller to hold the permission
    695      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    696      *
    697      * @hide
    698      */
    699     public Network getNetworkForType(int networkType) {
    700         try {
    701             return mService.getNetworkForType(networkType);
    702         } catch (RemoteException e) {
    703             return null;
    704         }
    705     }
    706 
    707     /**
    708      * Returns an array of all {@link Network} currently tracked by the
    709      * framework.
    710      *
    711      * @return an array of {@link Network} objects.
    712      *
    713      * <p>This method requires the caller to hold the permission
    714      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    715      */
    716     public Network[] getAllNetworks() {
    717         try {
    718             return mService.getAllNetworks();
    719         } catch (RemoteException e) {
    720             return null;
    721         }
    722     }
    723 
    724     /**
    725      * Returns details about the Provisioning or currently active default data network. When
    726      * connected, this network is the default route for outgoing connections.
    727      * You should always check {@link NetworkInfo#isConnected()} before initiating
    728      * network traffic. This may return {@code null} when there is no default
    729      * network.
    730      *
    731      * @return a {@link NetworkInfo} object for the current default network
    732      *        or {@code null} if no network default network is currently active
    733      *
    734      * <p>This method requires the call to hold the permission
    735      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    736      *
    737      * {@hide}
    738      */
    739     public NetworkInfo getProvisioningOrActiveNetworkInfo() {
    740         try {
    741             return mService.getProvisioningOrActiveNetworkInfo();
    742         } catch (RemoteException e) {
    743             return null;
    744         }
    745     }
    746 
    747     /**
    748      * Returns the IP information for the current default network.
    749      *
    750      * @return a {@link LinkProperties} object describing the IP info
    751      *        for the current default network, or {@code null} if there
    752      *        is no current default network.
    753      *
    754      * <p>This method requires the call to hold the permission
    755      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    756      * {@hide}
    757      */
    758     public LinkProperties getActiveLinkProperties() {
    759         try {
    760             return mService.getActiveLinkProperties();
    761         } catch (RemoteException e) {
    762             return null;
    763         }
    764     }
    765 
    766     /**
    767      * Returns the IP information for a given network type.
    768      *
    769      * @param networkType the network type of interest.
    770      * @return a {@link LinkProperties} object describing the IP info
    771      *        for the given networkType, or {@code null} if there is
    772      *        no current default network.
    773      *
    774      * <p>This method requires the call to hold the permission
    775      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    776      * {@hide}
    777      */
    778     public LinkProperties getLinkProperties(int networkType) {
    779         try {
    780             return mService.getLinkPropertiesForType(networkType);
    781         } catch (RemoteException e) {
    782             return null;
    783         }
    784     }
    785 
    786     /**
    787      * Get the {@link LinkProperties} for the given {@link Network}.  This
    788      * will return {@code null} if the network is unknown.
    789      *
    790      * @param network The {@link Network} object identifying the network in question.
    791      * @return The {@link LinkProperties} for the network, or {@code null}.
    792      **/
    793     public LinkProperties getLinkProperties(Network network) {
    794         try {
    795             return mService.getLinkProperties(network);
    796         } catch (RemoteException e) {
    797             return null;
    798         }
    799     }
    800 
    801     /**
    802      * Get the {@link NetworkCapabilities} for the given {@link Network}.  This
    803      * will return {@code null} if the network is unknown.
    804      *
    805      * @param network The {@link Network} object identifying the network in question.
    806      * @return The {@link NetworkCapabilities} for the network, or {@code null}.
    807      */
    808     public NetworkCapabilities getNetworkCapabilities(Network network) {
    809         try {
    810             return mService.getNetworkCapabilities(network);
    811         } catch (RemoteException e) {
    812             return null;
    813         }
    814     }
    815 
    816     /**
    817      * Tells each network type to set its radio power state as directed.
    818      *
    819      * @param turnOn a boolean, {@code true} to turn the radios on,
    820      *        {@code false} to turn them off.
    821      * @return a boolean, {@code true} indicating success.  All network types
    822      *        will be tried, even if some fail.
    823      *
    824      * <p>This method requires the call to hold the permission
    825      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
    826      * {@hide}
    827      */
    828 // TODO - check for any callers and remove
    829 //    public boolean setRadios(boolean turnOn) {
    830 //        try {
    831 //            return mService.setRadios(turnOn);
    832 //        } catch (RemoteException e) {
    833 //            return false;
    834 //        }
    835 //    }
    836 
    837     /**
    838      * Tells a given networkType to set its radio power state as directed.
    839      *
    840      * @param networkType the int networkType of interest.
    841      * @param turnOn a boolean, {@code true} to turn the radio on,
    842      *        {@code} false to turn it off.
    843      * @return a boolean, {@code true} indicating success.
    844      *
    845      * <p>This method requires the call to hold the permission
    846      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
    847      * {@hide}
    848      */
    849 // TODO - check for any callers and remove
    850 //    public boolean setRadio(int networkType, boolean turnOn) {
    851 //        try {
    852 //            return mService.setRadio(networkType, turnOn);
    853 //        } catch (RemoteException e) {
    854 //            return false;
    855 //        }
    856 //    }
    857 
    858     /**
    859      * Tells the underlying networking system that the caller wants to
    860      * begin using the named feature. The interpretation of {@code feature}
    861      * is completely up to each networking implementation.
    862      * <p>This method requires the caller to hold the permission
    863      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
    864      * @param networkType specifies which network the request pertains to
    865      * @param feature the name of the feature to be used
    866      * @return an integer value representing the outcome of the request.
    867      * The interpretation of this value is specific to each networking
    868      * implementation+feature combination, except that the value {@code -1}
    869      * always indicates failure.
    870      *
    871      * @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
    872      */
    873     public int startUsingNetworkFeature(int networkType, String feature) {
    874         NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
    875         if (netCap == null) {
    876             Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " +
    877                     feature);
    878             return PhoneConstants.APN_REQUEST_FAILED;
    879         }
    880 
    881         NetworkRequest request = null;
    882         synchronized (sLegacyRequests) {
    883             if (LEGACY_DBG) {
    884                 Log.d(TAG, "Looking for legacyRequest for netCap with hash: " + netCap + " (" +
    885                         netCap.hashCode() + ")");
    886                 Log.d(TAG, "sLegacyRequests has:");
    887                 for (NetworkCapabilities nc : sLegacyRequests.keySet()) {
    888                     Log.d(TAG, "  " + nc + " (" + nc.hashCode() + ")");
    889                 }
    890             }
    891             LegacyRequest l = sLegacyRequests.get(netCap);
    892             if (l != null) {
    893                 Log.d(TAG, "renewing startUsingNetworkFeature request " + l.networkRequest);
    894                 renewRequestLocked(l);
    895                 if (l.currentNetwork != null) {
    896                     return PhoneConstants.APN_ALREADY_ACTIVE;
    897                 } else {
    898                     return PhoneConstants.APN_REQUEST_STARTED;
    899                 }
    900             }
    901 
    902             request = requestNetworkForFeatureLocked(netCap);
    903         }
    904         if (request != null) {
    905             Log.d(TAG, "starting startUsingNetworkFeature for request " + request);
    906             return PhoneConstants.APN_REQUEST_STARTED;
    907         } else {
    908             Log.d(TAG, " request Failed");
    909             return PhoneConstants.APN_REQUEST_FAILED;
    910         }
    911     }
    912 
    913     /**
    914      * Tells the underlying networking system that the caller is finished
    915      * using the named feature. The interpretation of {@code feature}
    916      * is completely up to each networking implementation.
    917      * <p>This method requires the caller to hold the permission
    918      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
    919      * @param networkType specifies which network the request pertains to
    920      * @param feature the name of the feature that is no longer needed
    921      * @return an integer value representing the outcome of the request.
    922      * The interpretation of this value is specific to each networking
    923      * implementation+feature combination, except that the value {@code -1}
    924      * always indicates failure.
    925      *
    926      * @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
    927      */
    928     public int stopUsingNetworkFeature(int networkType, String feature) {
    929         NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
    930         if (netCap == null) {
    931             Log.d(TAG, "Can't satisfy stopUsingNetworkFeature for " + networkType + ", " +
    932                     feature);
    933             return -1;
    934         }
    935 
    936         NetworkCallback networkCallback = removeRequestForFeature(netCap);
    937         if (networkCallback != null) {
    938             Log.d(TAG, "stopUsingNetworkFeature for " + networkType + ", " + feature);
    939             unregisterNetworkCallback(networkCallback);
    940         }
    941         return 1;
    942     }
    943 
    944     /**
    945      * Removes the NET_CAPABILITY_NOT_RESTRICTED capability from the given
    946      * NetworkCapabilities object if all the capabilities it provides are
    947      * typically provided by restricted networks.
    948      *
    949      * TODO: consider:
    950      * - Moving to NetworkCapabilities
    951      * - Renaming it to guessRestrictedCapability and make it set the
    952      *   restricted capability bit in addition to clearing it.
    953      * @hide
    954      */
    955     public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
    956         for (int capability : nc.getCapabilities()) {
    957             switch (capability) {
    958                 case NetworkCapabilities.NET_CAPABILITY_CBS:
    959                 case NetworkCapabilities.NET_CAPABILITY_DUN:
    960                 case NetworkCapabilities.NET_CAPABILITY_EIMS:
    961                 case NetworkCapabilities.NET_CAPABILITY_FOTA:
    962                 case NetworkCapabilities.NET_CAPABILITY_IA:
    963                 case NetworkCapabilities.NET_CAPABILITY_IMS:
    964                 case NetworkCapabilities.NET_CAPABILITY_RCS:
    965                 case NetworkCapabilities.NET_CAPABILITY_XCAP:
    966                 case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED: //there by default
    967                     continue;
    968                 default:
    969                     // At least one capability usually provided by unrestricted
    970                     // networks. Conclude that this network is unrestricted.
    971                     return;
    972             }
    973         }
    974         // All the capabilities are typically provided by restricted networks.
    975         // Conclude that this network is restricted.
    976         nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
    977     }
    978 
    979     private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
    980         if (networkType == TYPE_MOBILE) {
    981             int cap = -1;
    982             if ("enableMMS".equals(feature)) {
    983                 cap = NetworkCapabilities.NET_CAPABILITY_MMS;
    984             } else if ("enableSUPL".equals(feature)) {
    985                 cap = NetworkCapabilities.NET_CAPABILITY_SUPL;
    986             } else if ("enableDUN".equals(feature) || "enableDUNAlways".equals(feature)) {
    987                 cap = NetworkCapabilities.NET_CAPABILITY_DUN;
    988             } else if ("enableHIPRI".equals(feature)) {
    989                 cap = NetworkCapabilities.NET_CAPABILITY_INTERNET;
    990             } else if ("enableFOTA".equals(feature)) {
    991                 cap = NetworkCapabilities.NET_CAPABILITY_FOTA;
    992             } else if ("enableIMS".equals(feature)) {
    993                 cap = NetworkCapabilities.NET_CAPABILITY_IMS;
    994             } else if ("enableCBS".equals(feature)) {
    995                 cap = NetworkCapabilities.NET_CAPABILITY_CBS;
    996             } else {
    997                 return null;
    998             }
    999             NetworkCapabilities netCap = new NetworkCapabilities();
   1000             netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
   1001             maybeMarkCapabilitiesRestricted(netCap);
   1002             return netCap;
   1003         } else if (networkType == TYPE_WIFI) {
   1004             if ("p2p".equals(feature)) {
   1005                 NetworkCapabilities netCap = new NetworkCapabilities();
   1006                 netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
   1007                 netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
   1008                 maybeMarkCapabilitiesRestricted(netCap);
   1009                 return netCap;
   1010             }
   1011         }
   1012         return null;
   1013     }
   1014 
   1015     private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
   1016         if (netCap == null) {
   1017             return TYPE_NONE;
   1018         }
   1019         if (!netCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
   1020             return TYPE_NONE;
   1021         }
   1022         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
   1023             if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableCBS"))) {
   1024                 return TYPE_MOBILE_CBS;
   1025             } else {
   1026                 return TYPE_NONE;
   1027             }
   1028         }
   1029         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
   1030             if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableIMS"))) {
   1031                 return TYPE_MOBILE_IMS;
   1032             } else {
   1033                 return TYPE_NONE;
   1034             }
   1035         }
   1036         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
   1037             if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableFOTA"))) {
   1038                 return TYPE_MOBILE_FOTA;
   1039             } else {
   1040                 return TYPE_NONE;
   1041             }
   1042         }
   1043         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
   1044             if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableDUN"))) {
   1045                 return TYPE_MOBILE_DUN;
   1046             } else {
   1047                 return TYPE_NONE;
   1048             }
   1049         }
   1050         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
   1051             if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableSUPL"))) {
   1052                 return TYPE_MOBILE_SUPL;
   1053             } else {
   1054                 return TYPE_NONE;
   1055             }
   1056         }
   1057         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
   1058             if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableMMS"))) {
   1059                 return TYPE_MOBILE_MMS;
   1060             } else {
   1061                 return TYPE_NONE;
   1062             }
   1063         }
   1064         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
   1065             if (netCap.equals(networkCapabilitiesForFeature(TYPE_MOBILE, "enableHIPRI"))) {
   1066                 return TYPE_MOBILE_HIPRI;
   1067             } else {
   1068                 return TYPE_NONE;
   1069             }
   1070         }
   1071         return TYPE_NONE;
   1072     }
   1073 
   1074     private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
   1075         if (netCap == null) return TYPE_NONE;
   1076         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
   1077             return TYPE_MOBILE_CBS;
   1078         }
   1079         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
   1080             return TYPE_MOBILE_IMS;
   1081         }
   1082         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
   1083             return TYPE_MOBILE_FOTA;
   1084         }
   1085         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
   1086             return TYPE_MOBILE_DUN;
   1087         }
   1088         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
   1089             return TYPE_MOBILE_SUPL;
   1090         }
   1091         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
   1092             return TYPE_MOBILE_MMS;
   1093         }
   1094         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
   1095             return TYPE_MOBILE_HIPRI;
   1096         }
   1097         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) {
   1098             return TYPE_WIFI_P2P;
   1099         }
   1100         return TYPE_NONE;
   1101     }
   1102 
   1103     private static class LegacyRequest {
   1104         NetworkCapabilities networkCapabilities;
   1105         NetworkRequest networkRequest;
   1106         int expireSequenceNumber;
   1107         Network currentNetwork;
   1108         int delay = -1;
   1109         NetworkCallback networkCallback = new NetworkCallback() {
   1110             @Override
   1111             public void onAvailable(Network network) {
   1112                 currentNetwork = network;
   1113                 Log.d(TAG, "startUsingNetworkFeature got Network:" + network);
   1114                 setProcessDefaultNetworkForHostResolution(network);
   1115             }
   1116             @Override
   1117             public void onLost(Network network) {
   1118                 if (network.equals(currentNetwork)) {
   1119                     currentNetwork = null;
   1120                     setProcessDefaultNetworkForHostResolution(null);
   1121                 }
   1122                 Log.d(TAG, "startUsingNetworkFeature lost Network:" + network);
   1123             }
   1124         };
   1125     }
   1126 
   1127     private static HashMap<NetworkCapabilities, LegacyRequest> sLegacyRequests =
   1128             new HashMap<NetworkCapabilities, LegacyRequest>();
   1129 
   1130     private NetworkRequest findRequestForFeature(NetworkCapabilities netCap) {
   1131         synchronized (sLegacyRequests) {
   1132             LegacyRequest l = sLegacyRequests.get(netCap);
   1133             if (l != null) return l.networkRequest;
   1134         }
   1135         return null;
   1136     }
   1137 
   1138     private void renewRequestLocked(LegacyRequest l) {
   1139         l.expireSequenceNumber++;
   1140         Log.d(TAG, "renewing request to seqNum " + l.expireSequenceNumber);
   1141         sendExpireMsgForFeature(l.networkCapabilities, l.expireSequenceNumber, l.delay);
   1142     }
   1143 
   1144     private void expireRequest(NetworkCapabilities netCap, int sequenceNum) {
   1145         int ourSeqNum = -1;
   1146         synchronized (sLegacyRequests) {
   1147             LegacyRequest l = sLegacyRequests.get(netCap);
   1148             if (l == null) return;
   1149             ourSeqNum = l.expireSequenceNumber;
   1150             if (l.expireSequenceNumber == sequenceNum) {
   1151                 unregisterNetworkCallback(l.networkCallback);
   1152                 sLegacyRequests.remove(netCap);
   1153             }
   1154         }
   1155         Log.d(TAG, "expireRequest with " + ourSeqNum + ", " + sequenceNum);
   1156     }
   1157 
   1158     private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) {
   1159         int delay = -1;
   1160         int type = legacyTypeForNetworkCapabilities(netCap);
   1161         try {
   1162             delay = mService.getRestoreDefaultNetworkDelay(type);
   1163         } catch (RemoteException e) {}
   1164         LegacyRequest l = new LegacyRequest();
   1165         l.networkCapabilities = netCap;
   1166         l.delay = delay;
   1167         l.expireSequenceNumber = 0;
   1168         l.networkRequest = sendRequestForNetwork(netCap, l.networkCallback, 0,
   1169                 REQUEST, type);
   1170         if (l.networkRequest == null) return null;
   1171         sLegacyRequests.put(netCap, l);
   1172         sendExpireMsgForFeature(netCap, l.expireSequenceNumber, delay);
   1173         return l.networkRequest;
   1174     }
   1175 
   1176     private void sendExpireMsgForFeature(NetworkCapabilities netCap, int seqNum, int delay) {
   1177         if (delay >= 0) {
   1178             Log.d(TAG, "sending expire msg with seqNum " + seqNum + " and delay " + delay);
   1179             Message msg = sCallbackHandler.obtainMessage(EXPIRE_LEGACY_REQUEST, seqNum, 0, netCap);
   1180             sCallbackHandler.sendMessageDelayed(msg, delay);
   1181         }
   1182     }
   1183 
   1184     private NetworkCallback removeRequestForFeature(NetworkCapabilities netCap) {
   1185         synchronized (sLegacyRequests) {
   1186             LegacyRequest l = sLegacyRequests.remove(netCap);
   1187             if (l == null) return null;
   1188             return l.networkCallback;
   1189         }
   1190     }
   1191 
   1192     /**
   1193      * Ensure that a network route exists to deliver traffic to the specified
   1194      * host via the specified network interface. An attempt to add a route that
   1195      * already exists is ignored, but treated as successful.
   1196      * <p>This method requires the caller to hold the permission
   1197      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
   1198      * @param networkType the type of the network over which traffic to the specified
   1199      * host is to be routed
   1200      * @param hostAddress the IP address of the host to which the route is desired
   1201      * @return {@code true} on success, {@code false} on failure
   1202      *
   1203      * @deprecated Deprecated in favor of the {@link #requestNetwork},
   1204      *             {@link #setProcessDefaultNetwork} and {@link Network#getSocketFactory} api.
   1205      */
   1206     public boolean requestRouteToHost(int networkType, int hostAddress) {
   1207         return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress));
   1208     }
   1209 
   1210     /**
   1211      * Ensure that a network route exists to deliver traffic to the specified
   1212      * host via the specified network interface. An attempt to add a route that
   1213      * already exists is ignored, but treated as successful.
   1214      * <p>This method requires the caller to hold the permission
   1215      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
   1216      * @param networkType the type of the network over which traffic to the specified
   1217      * host is to be routed
   1218      * @param hostAddress the IP address of the host to which the route is desired
   1219      * @return {@code true} on success, {@code false} on failure
   1220      * @hide
   1221      * @deprecated Deprecated in favor of the {@link #requestNetwork} and
   1222      *             {@link #setProcessDefaultNetwork} api.
   1223      */
   1224     public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
   1225         try {
   1226             return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress());
   1227         } catch (RemoteException e) {
   1228             return false;
   1229         }
   1230     }
   1231 
   1232     /**
   1233      * Returns the value of the setting for background data usage. If false,
   1234      * applications should not use the network if the application is not in the
   1235      * foreground. Developers should respect this setting, and check the value
   1236      * of this before performing any background data operations.
   1237      * <p>
   1238      * All applications that have background services that use the network
   1239      * should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}.
   1240      * <p>
   1241      * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability of
   1242      * background data depends on several combined factors, and this method will
   1243      * always return {@code true}. Instead, when background data is unavailable,
   1244      * {@link #getActiveNetworkInfo()} will now appear disconnected.
   1245      *
   1246      * @return Whether background data usage is allowed.
   1247      */
   1248     @Deprecated
   1249     public boolean getBackgroundDataSetting() {
   1250         // assume that background data is allowed; final authority is
   1251         // NetworkInfo which may be blocked.
   1252         return true;
   1253     }
   1254 
   1255     /**
   1256      * Sets the value of the setting for background data usage.
   1257      *
   1258      * @param allowBackgroundData Whether an application should use data while
   1259      *            it is in the background.
   1260      *
   1261      * @attr ref android.Manifest.permission#CHANGE_BACKGROUND_DATA_SETTING
   1262      * @see #getBackgroundDataSetting()
   1263      * @hide
   1264      */
   1265     @Deprecated
   1266     public void setBackgroundDataSetting(boolean allowBackgroundData) {
   1267         // ignored
   1268     }
   1269 
   1270     /**
   1271      * Return quota status for the current active network, or {@code null} if no
   1272      * network is active. Quota status can change rapidly, so these values
   1273      * shouldn't be cached.
   1274      *
   1275      * <p>This method requires the call to hold the permission
   1276      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1277      *
   1278      * @hide
   1279      */
   1280     public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
   1281         try {
   1282             return mService.getActiveNetworkQuotaInfo();
   1283         } catch (RemoteException e) {
   1284             return null;
   1285         }
   1286     }
   1287 
   1288     /**
   1289      * @hide
   1290      * @deprecated Talk to TelephonyManager directly
   1291      */
   1292     public boolean getMobileDataEnabled() {
   1293         IBinder b = ServiceManager.getService(Context.TELEPHONY_SERVICE);
   1294         if (b != null) {
   1295             try {
   1296                 ITelephony it = ITelephony.Stub.asInterface(b);
   1297                 return it.getDataEnabled();
   1298             } catch (RemoteException e) { }
   1299         }
   1300         return false;
   1301     }
   1302 
   1303     /**
   1304      * Callback for use with {@link ConnectivityManager#addDefaultNetworkActiveListener}
   1305      * to find out when the system default network has gone in to a high power state.
   1306      */
   1307     public interface OnNetworkActiveListener {
   1308         /**
   1309          * Called on the main thread of the process to report that the current data network
   1310          * has become active, and it is now a good time to perform any pending network
   1311          * operations.  Note that this listener only tells you when the network becomes
   1312          * active; if at any other time you want to know whether it is active (and thus okay
   1313          * to initiate network traffic), you can retrieve its instantaneous state with
   1314          * {@link ConnectivityManager#isDefaultNetworkActive}.
   1315          */
   1316         public void onNetworkActive();
   1317     }
   1318 
   1319     private INetworkManagementService getNetworkManagementService() {
   1320         synchronized (this) {
   1321             if (mNMService != null) {
   1322                 return mNMService;
   1323             }
   1324             IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
   1325             mNMService = INetworkManagementService.Stub.asInterface(b);
   1326             return mNMService;
   1327         }
   1328     }
   1329 
   1330     private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
   1331             mNetworkActivityListeners
   1332                     = new ArrayMap<OnNetworkActiveListener, INetworkActivityListener>();
   1333 
   1334     /**
   1335      * Start listening to reports when the system's default data network is active, meaning it is
   1336      * a good time to perform network traffic.  Use {@link #isDefaultNetworkActive()}
   1337      * to determine the current state of the system's default network after registering the
   1338      * listener.
   1339      * <p>
   1340      * If the process default network has been set with
   1341      * {@link ConnectivityManager#setProcessDefaultNetwork} this function will not
   1342      * reflect the process's default, but the system default.
   1343      *
   1344      * @param l The listener to be told when the network is active.
   1345      */
   1346     public void addDefaultNetworkActiveListener(final OnNetworkActiveListener l) {
   1347         INetworkActivityListener rl = new INetworkActivityListener.Stub() {
   1348             @Override
   1349             public void onNetworkActive() throws RemoteException {
   1350                 l.onNetworkActive();
   1351             }
   1352         };
   1353 
   1354         try {
   1355             getNetworkManagementService().registerNetworkActivityListener(rl);
   1356             mNetworkActivityListeners.put(l, rl);
   1357         } catch (RemoteException e) {
   1358         }
   1359     }
   1360 
   1361     /**
   1362      * Remove network active listener previously registered with
   1363      * {@link #addDefaultNetworkActiveListener}.
   1364      *
   1365      * @param l Previously registered listener.
   1366      */
   1367     public void removeDefaultNetworkActiveListener(OnNetworkActiveListener l) {
   1368         INetworkActivityListener rl = mNetworkActivityListeners.get(l);
   1369         if (rl == null) {
   1370             throw new IllegalArgumentException("Listener not registered: " + l);
   1371         }
   1372         try {
   1373             getNetworkManagementService().unregisterNetworkActivityListener(rl);
   1374         } catch (RemoteException e) {
   1375         }
   1376     }
   1377 
   1378     /**
   1379      * Return whether the data network is currently active.  An active network means that
   1380      * it is currently in a high power state for performing data transmission.  On some
   1381      * types of networks, it may be expensive to move and stay in such a state, so it is
   1382      * more power efficient to batch network traffic together when the radio is already in
   1383      * this state.  This method tells you whether right now is currently a good time to
   1384      * initiate network traffic, as the network is already active.
   1385      */
   1386     public boolean isDefaultNetworkActive() {
   1387         try {
   1388             return getNetworkManagementService().isNetworkActive();
   1389         } catch (RemoteException e) {
   1390         }
   1391         return false;
   1392     }
   1393 
   1394     /**
   1395      * {@hide}
   1396      */
   1397     public ConnectivityManager(IConnectivityManager service) {
   1398         mService = checkNotNull(service, "missing IConnectivityManager");
   1399     }
   1400 
   1401     /** {@hide} */
   1402     public static ConnectivityManager from(Context context) {
   1403         return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
   1404     }
   1405 
   1406     /** {@hide */
   1407     public static final void enforceTetherChangePermission(Context context) {
   1408         if (context.getResources().getStringArray(
   1409                 com.android.internal.R.array.config_mobile_hotspot_provision_app).length == 2) {
   1410             // Have a provisioning app - must only let system apps (which check this app)
   1411             // turn on tethering
   1412             context.enforceCallingOrSelfPermission(
   1413                     android.Manifest.permission.CONNECTIVITY_INTERNAL, "ConnectivityService");
   1414         } else {
   1415             context.enforceCallingOrSelfPermission(
   1416                     android.Manifest.permission.CHANGE_NETWORK_STATE, "ConnectivityService");
   1417         }
   1418     }
   1419 
   1420     /**
   1421      * Get the set of tetherable, available interfaces.  This list is limited by
   1422      * device configuration and current interface existence.
   1423      *
   1424      * @return an array of 0 or more Strings of tetherable interface names.
   1425      *
   1426      * <p>This method requires the call to hold the permission
   1427      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1428      * {@hide}
   1429      */
   1430     public String[] getTetherableIfaces() {
   1431         try {
   1432             return mService.getTetherableIfaces();
   1433         } catch (RemoteException e) {
   1434             return new String[0];
   1435         }
   1436     }
   1437 
   1438     /**
   1439      * Get the set of tethered interfaces.
   1440      *
   1441      * @return an array of 0 or more String of currently tethered interface names.
   1442      *
   1443      * <p>This method requires the call to hold the permission
   1444      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1445      * {@hide}
   1446      */
   1447     public String[] getTetheredIfaces() {
   1448         try {
   1449             return mService.getTetheredIfaces();
   1450         } catch (RemoteException e) {
   1451             return new String[0];
   1452         }
   1453     }
   1454 
   1455     /**
   1456      * Get the set of interface names which attempted to tether but
   1457      * failed.  Re-attempting to tether may cause them to reset to the Tethered
   1458      * state.  Alternatively, causing the interface to be destroyed and recreated
   1459      * may cause them to reset to the available state.
   1460      * {@link ConnectivityManager#getLastTetherError} can be used to get more
   1461      * information on the cause of the errors.
   1462      *
   1463      * @return an array of 0 or more String indicating the interface names
   1464      *        which failed to tether.
   1465      *
   1466      * <p>This method requires the call to hold the permission
   1467      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1468      * {@hide}
   1469      */
   1470     public String[] getTetheringErroredIfaces() {
   1471         try {
   1472             return mService.getTetheringErroredIfaces();
   1473         } catch (RemoteException e) {
   1474             return new String[0];
   1475         }
   1476     }
   1477 
   1478     /**
   1479      * Get the set of tethered dhcp ranges.
   1480      *
   1481      * @return an array of 0 or more {@code String} of tethered dhcp ranges.
   1482      * {@hide}
   1483      */
   1484     public String[] getTetheredDhcpRanges() {
   1485         try {
   1486             return mService.getTetheredDhcpRanges();
   1487         } catch (RemoteException e) {
   1488             return new String[0];
   1489         }
   1490     }
   1491 
   1492     /**
   1493      * Attempt to tether the named interface.  This will setup a dhcp server
   1494      * on the interface, forward and NAT IP packets and forward DNS requests
   1495      * to the best active upstream network interface.  Note that if no upstream
   1496      * IP network interface is available, dhcp will still run and traffic will be
   1497      * allowed between the tethered devices and this device, though upstream net
   1498      * access will of course fail until an upstream network interface becomes
   1499      * active.
   1500      *
   1501      * @param iface the interface name to tether.
   1502      * @return error a {@code TETHER_ERROR} value indicating success or failure type
   1503      *
   1504      * <p>This method requires the call to hold the permission
   1505      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
   1506      * {@hide}
   1507      */
   1508     public int tether(String iface) {
   1509         try {
   1510             return mService.tether(iface);
   1511         } catch (RemoteException e) {
   1512             return TETHER_ERROR_SERVICE_UNAVAIL;
   1513         }
   1514     }
   1515 
   1516     /**
   1517      * Stop tethering the named interface.
   1518      *
   1519      * @param iface the interface name to untether.
   1520      * @return error a {@code TETHER_ERROR} value indicating success or failure type
   1521      *
   1522      * <p>This method requires the call to hold the permission
   1523      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
   1524      * {@hide}
   1525      */
   1526     public int untether(String iface) {
   1527         try {
   1528             return mService.untether(iface);
   1529         } catch (RemoteException e) {
   1530             return TETHER_ERROR_SERVICE_UNAVAIL;
   1531         }
   1532     }
   1533 
   1534     /**
   1535      * Check if the device allows for tethering.  It may be disabled via
   1536      * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
   1537      * due to device configuration.
   1538      *
   1539      * @return a boolean - {@code true} indicating Tethering is supported.
   1540      *
   1541      * <p>This method requires the call to hold the permission
   1542      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1543      * {@hide}
   1544      */
   1545     public boolean isTetheringSupported() {
   1546         try {
   1547             return mService.isTetheringSupported();
   1548         } catch (RemoteException e) {
   1549             return false;
   1550         }
   1551     }
   1552 
   1553     /**
   1554      * Get the list of regular expressions that define any tetherable
   1555      * USB network interfaces.  If USB tethering is not supported by the
   1556      * device, this list should be empty.
   1557      *
   1558      * @return an array of 0 or more regular expression Strings defining
   1559      *        what interfaces are considered tetherable usb interfaces.
   1560      *
   1561      * <p>This method requires the call to hold the permission
   1562      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1563      * {@hide}
   1564      */
   1565     public String[] getTetherableUsbRegexs() {
   1566         try {
   1567             return mService.getTetherableUsbRegexs();
   1568         } catch (RemoteException e) {
   1569             return new String[0];
   1570         }
   1571     }
   1572 
   1573     /**
   1574      * Get the list of regular expressions that define any tetherable
   1575      * Wifi network interfaces.  If Wifi tethering is not supported by the
   1576      * device, this list should be empty.
   1577      *
   1578      * @return an array of 0 or more regular expression Strings defining
   1579      *        what interfaces are considered tetherable wifi interfaces.
   1580      *
   1581      * <p>This method requires the call to hold the permission
   1582      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1583      * {@hide}
   1584      */
   1585     public String[] getTetherableWifiRegexs() {
   1586         try {
   1587             return mService.getTetherableWifiRegexs();
   1588         } catch (RemoteException e) {
   1589             return new String[0];
   1590         }
   1591     }
   1592 
   1593     /**
   1594      * Get the list of regular expressions that define any tetherable
   1595      * Bluetooth network interfaces.  If Bluetooth tethering is not supported by the
   1596      * device, this list should be empty.
   1597      *
   1598      * @return an array of 0 or more regular expression Strings defining
   1599      *        what interfaces are considered tetherable bluetooth interfaces.
   1600      *
   1601      * <p>This method requires the call to hold the permission
   1602      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1603      * {@hide}
   1604      */
   1605     public String[] getTetherableBluetoothRegexs() {
   1606         try {
   1607             return mService.getTetherableBluetoothRegexs();
   1608         } catch (RemoteException e) {
   1609             return new String[0];
   1610         }
   1611     }
   1612 
   1613     /**
   1614      * Attempt to both alter the mode of USB and Tethering of USB.  A
   1615      * utility method to deal with some of the complexity of USB - will
   1616      * attempt to switch to Rndis and subsequently tether the resulting
   1617      * interface on {@code true} or turn off tethering and switch off
   1618      * Rndis on {@code false}.
   1619      *
   1620      * @param enable a boolean - {@code true} to enable tethering
   1621      * @return error a {@code TETHER_ERROR} value indicating success or failure type
   1622      *
   1623      * <p>This method requires the call to hold the permission
   1624      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
   1625      * {@hide}
   1626      */
   1627     public int setUsbTethering(boolean enable) {
   1628         try {
   1629             return mService.setUsbTethering(enable);
   1630         } catch (RemoteException e) {
   1631             return TETHER_ERROR_SERVICE_UNAVAIL;
   1632         }
   1633     }
   1634 
   1635     /** {@hide} */
   1636     public static final int TETHER_ERROR_NO_ERROR           = 0;
   1637     /** {@hide} */
   1638     public static final int TETHER_ERROR_UNKNOWN_IFACE      = 1;
   1639     /** {@hide} */
   1640     public static final int TETHER_ERROR_SERVICE_UNAVAIL    = 2;
   1641     /** {@hide} */
   1642     public static final int TETHER_ERROR_UNSUPPORTED        = 3;
   1643     /** {@hide} */
   1644     public static final int TETHER_ERROR_UNAVAIL_IFACE      = 4;
   1645     /** {@hide} */
   1646     public static final int TETHER_ERROR_MASTER_ERROR       = 5;
   1647     /** {@hide} */
   1648     public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
   1649     /** {@hide} */
   1650     public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
   1651     /** {@hide} */
   1652     public static final int TETHER_ERROR_ENABLE_NAT_ERROR     = 8;
   1653     /** {@hide} */
   1654     public static final int TETHER_ERROR_DISABLE_NAT_ERROR    = 9;
   1655     /** {@hide} */
   1656     public static final int TETHER_ERROR_IFACE_CFG_ERROR      = 10;
   1657 
   1658     /**
   1659      * Get a more detailed error code after a Tethering or Untethering
   1660      * request asynchronously failed.
   1661      *
   1662      * @param iface The name of the interface of interest
   1663      * @return error The error code of the last error tethering or untethering the named
   1664      *               interface
   1665      *
   1666      * <p>This method requires the call to hold the permission
   1667      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1668      * {@hide}
   1669      */
   1670     public int getLastTetherError(String iface) {
   1671         try {
   1672             return mService.getLastTetherError(iface);
   1673         } catch (RemoteException e) {
   1674             return TETHER_ERROR_SERVICE_UNAVAIL;
   1675         }
   1676     }
   1677 
   1678     /**
   1679      * Report network connectivity status.  This is currently used only
   1680      * to alter status bar UI.
   1681      *
   1682      * @param networkType The type of network you want to report on
   1683      * @param percentage The quality of the connection 0 is bad, 100 is good
   1684      *
   1685      * <p>This method requires the call to hold the permission
   1686      * {@link android.Manifest.permission#STATUS_BAR}.
   1687      * {@hide}
   1688      */
   1689     public void reportInetCondition(int networkType, int percentage) {
   1690         try {
   1691             mService.reportInetCondition(networkType, percentage);
   1692         } catch (RemoteException e) {
   1693         }
   1694     }
   1695 
   1696     /**
   1697      * Report a problem network to the framework.  This provides a hint to the system
   1698      * that there might be connectivity problems on this network and may cause
   1699      * the framework to re-evaluate network connectivity and/or switch to another
   1700      * network.
   1701      *
   1702      * @param network The {@link Network} the application was attempting to use
   1703      *                or {@code null} to indicate the current default network.
   1704      */
   1705     public void reportBadNetwork(Network network) {
   1706         try {
   1707             mService.reportBadNetwork(network);
   1708         } catch (RemoteException e) {
   1709         }
   1710     }
   1711 
   1712     /**
   1713      * Set a network-independent global http proxy.  This is not normally what you want
   1714      * for typical HTTP proxies - they are general network dependent.  However if you're
   1715      * doing something unusual like general internal filtering this may be useful.  On
   1716      * a private network where the proxy is not accessible, you may break HTTP using this.
   1717      *
   1718      * @param p The a {@link ProxyInfo} object defining the new global
   1719      *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
   1720      *
   1721      * <p>This method requires the call to hold the permission
   1722      * android.Manifest.permission#CONNECTIVITY_INTERNAL.
   1723      * @hide
   1724      */
   1725     public void setGlobalProxy(ProxyInfo p) {
   1726         try {
   1727             mService.setGlobalProxy(p);
   1728         } catch (RemoteException e) {
   1729         }
   1730     }
   1731 
   1732     /**
   1733      * Retrieve any network-independent global HTTP proxy.
   1734      *
   1735      * @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
   1736      *        if no global HTTP proxy is set.
   1737      *
   1738      * <p>This method requires the call to hold the permission
   1739      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1740      * @hide
   1741      */
   1742     public ProxyInfo getGlobalProxy() {
   1743         try {
   1744             return mService.getGlobalProxy();
   1745         } catch (RemoteException e) {
   1746             return null;
   1747         }
   1748     }
   1749 
   1750     /**
   1751      * Get the HTTP proxy settings for the current default network.  Note that
   1752      * if a global proxy is set, it will override any per-network setting.
   1753      *
   1754      * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no
   1755      *        HTTP proxy is active.
   1756      *
   1757      * <p>This method requires the call to hold the permission
   1758      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1759      * {@hide}
   1760      * @deprecated Deprecated in favor of {@link #getLinkProperties}
   1761      */
   1762     public ProxyInfo getProxy() {
   1763         try {
   1764             return mService.getProxy();
   1765         } catch (RemoteException e) {
   1766             return null;
   1767         }
   1768     }
   1769 
   1770     /**
   1771      * Sets a secondary requirement bit for the given networkType.
   1772      * This requirement bit is generally under the control of the carrier
   1773      * or its agents and is not directly controlled by the user.
   1774      *
   1775      * @param networkType The network who's dependence has changed
   1776      * @param met Boolean - true if network use is OK, false if not
   1777      *
   1778      * <p>This method requires the call to hold the permission
   1779      * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
   1780      * {@hide}
   1781      */
   1782     public void setDataDependency(int networkType, boolean met) {
   1783         try {
   1784             mService.setDataDependency(networkType, met);
   1785         } catch (RemoteException e) {
   1786         }
   1787     }
   1788 
   1789     /**
   1790      * Returns true if the hardware supports the given network type
   1791      * else it returns false.  This doesn't indicate we have coverage
   1792      * or are authorized onto a network, just whether or not the
   1793      * hardware supports it.  For example a GSM phone without a SIM
   1794      * should still return {@code true} for mobile data, but a wifi only
   1795      * tablet would return {@code false}.
   1796      *
   1797      * @param networkType The network type we'd like to check
   1798      * @return {@code true} if supported, else {@code false}
   1799      *
   1800      * <p>This method requires the call to hold the permission
   1801      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1802      * @hide
   1803      */
   1804     public boolean isNetworkSupported(int networkType) {
   1805         try {
   1806             return mService.isNetworkSupported(networkType);
   1807         } catch (RemoteException e) {}
   1808         return false;
   1809     }
   1810 
   1811     /**
   1812      * Returns if the currently active data network is metered. A network is
   1813      * classified as metered when the user is sensitive to heavy data usage on
   1814      * that connection due to monetary costs, data limitations or
   1815      * battery/performance issues. You should check this before doing large
   1816      * data transfers, and warn the user or delay the operation until another
   1817      * network is available.
   1818      *
   1819      * @return {@code true} if large transfers should be avoided, otherwise
   1820      *        {@code false}.
   1821      *
   1822      * <p>This method requires the call to hold the permission
   1823      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1824      */
   1825     public boolean isActiveNetworkMetered() {
   1826         try {
   1827             return mService.isActiveNetworkMetered();
   1828         } catch (RemoteException e) {
   1829             return false;
   1830         }
   1831     }
   1832 
   1833     /**
   1834      * If the LockdownVpn mechanism is enabled, updates the vpn
   1835      * with a reload of its profile.
   1836      *
   1837      * @return a boolean with {@code} indicating success
   1838      *
   1839      * <p>This method can only be called by the system UID
   1840      * {@hide}
   1841      */
   1842     public boolean updateLockdownVpn() {
   1843         try {
   1844             return mService.updateLockdownVpn();
   1845         } catch (RemoteException e) {
   1846             return false;
   1847         }
   1848     }
   1849 
   1850     /**
   1851      * Signal that the captive portal check on the indicated network
   1852      * is complete and whether its a captive portal or not.
   1853      *
   1854      * @param info the {@link NetworkInfo} object for the networkType
   1855      *        in question.
   1856      * @param isCaptivePortal true/false.
   1857      *
   1858      * <p>This method requires the call to hold the permission
   1859      * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
   1860      * {@hide}
   1861      */
   1862     public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
   1863         try {
   1864             mService.captivePortalCheckCompleted(info, isCaptivePortal);
   1865         } catch (RemoteException e) {
   1866         }
   1867     }
   1868 
   1869     /**
   1870      * Supply the backend messenger for a network tracker
   1871      *
   1872      * @param networkType NetworkType to set
   1873      * @param messenger {@link Messenger}
   1874      * {@hide}
   1875      */
   1876     public void supplyMessenger(int networkType, Messenger messenger) {
   1877         try {
   1878             mService.supplyMessenger(networkType, messenger);
   1879         } catch (RemoteException e) {
   1880         }
   1881     }
   1882 
   1883     /**
   1884      * Check mobile provisioning.
   1885      *
   1886      * @param suggestedTimeOutMs, timeout in milliseconds
   1887      *
   1888      * @return time out that will be used, maybe less that suggestedTimeOutMs
   1889      * -1 if an error.
   1890      *
   1891      * {@hide}
   1892      */
   1893     public int checkMobileProvisioning(int suggestedTimeOutMs) {
   1894         int timeOutMs = -1;
   1895         try {
   1896             timeOutMs = mService.checkMobileProvisioning(suggestedTimeOutMs);
   1897         } catch (RemoteException e) {
   1898         }
   1899         return timeOutMs;
   1900     }
   1901 
   1902     /**
   1903      * Get the mobile provisioning url.
   1904      * {@hide}
   1905      */
   1906     public String getMobileProvisioningUrl() {
   1907         try {
   1908             return mService.getMobileProvisioningUrl();
   1909         } catch (RemoteException e) {
   1910         }
   1911         return null;
   1912     }
   1913 
   1914     /**
   1915      * Get the mobile redirected provisioning url.
   1916      * {@hide}
   1917      */
   1918     public String getMobileRedirectedProvisioningUrl() {
   1919         try {
   1920             return mService.getMobileRedirectedProvisioningUrl();
   1921         } catch (RemoteException e) {
   1922         }
   1923         return null;
   1924     }
   1925 
   1926     /**
   1927      * get the information about a specific network link
   1928      * @hide
   1929      */
   1930     public LinkQualityInfo getLinkQualityInfo(int networkType) {
   1931         try {
   1932             LinkQualityInfo li = mService.getLinkQualityInfo(networkType);
   1933             return li;
   1934         } catch (RemoteException e) {
   1935             return null;
   1936         }
   1937     }
   1938 
   1939     /**
   1940      * get the information of currently active network link
   1941      * @hide
   1942      */
   1943     public LinkQualityInfo getActiveLinkQualityInfo() {
   1944         try {
   1945             LinkQualityInfo li = mService.getActiveLinkQualityInfo();
   1946             return li;
   1947         } catch (RemoteException e) {
   1948             return null;
   1949         }
   1950     }
   1951 
   1952     /**
   1953      * get the information of all network links
   1954      * @hide
   1955      */
   1956     public LinkQualityInfo[] getAllLinkQualityInfo() {
   1957         try {
   1958             LinkQualityInfo[] li = mService.getAllLinkQualityInfo();
   1959             return li;
   1960         } catch (RemoteException e) {
   1961             return null;
   1962         }
   1963     }
   1964 
   1965     /**
   1966      * Set sign in error notification to visible or in visible
   1967      *
   1968      * @param visible
   1969      * @param networkType
   1970      *
   1971      * {@hide}
   1972      */
   1973     public void setProvisioningNotificationVisible(boolean visible, int networkType,
   1974             String action) {
   1975         try {
   1976             mService.setProvisioningNotificationVisible(visible, networkType, action);
   1977         } catch (RemoteException e) {
   1978         }
   1979     }
   1980 
   1981     /**
   1982      * Set the value for enabling/disabling airplane mode
   1983      *
   1984      * @param enable whether to enable airplane mode or not
   1985      *
   1986      * <p>This method requires the call to hold the permission
   1987      * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
   1988      * @hide
   1989      */
   1990     public void setAirplaneMode(boolean enable) {
   1991         try {
   1992             mService.setAirplaneMode(enable);
   1993         } catch (RemoteException e) {
   1994         }
   1995     }
   1996 
   1997     /** {@hide} */
   1998     public void registerNetworkFactory(Messenger messenger, String name) {
   1999         try {
   2000             mService.registerNetworkFactory(messenger, name);
   2001         } catch (RemoteException e) { }
   2002     }
   2003 
   2004     /** {@hide} */
   2005     public void unregisterNetworkFactory(Messenger messenger) {
   2006         try {
   2007             mService.unregisterNetworkFactory(messenger);
   2008         } catch (RemoteException e) { }
   2009     }
   2010 
   2011     /** {@hide} */
   2012     public void registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
   2013             NetworkCapabilities nc, int score, NetworkMisc misc) {
   2014         try {
   2015             mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc);
   2016         } catch (RemoteException e) { }
   2017     }
   2018 
   2019     /**
   2020      * Base class for NetworkRequest callbacks.  Used for notifications about network
   2021      * changes.  Should be extended by applications wanting notifications.
   2022      */
   2023     public static class NetworkCallback {
   2024         /** @hide */
   2025         public static final int PRECHECK     = 1;
   2026         /** @hide */
   2027         public static final int AVAILABLE    = 2;
   2028         /** @hide */
   2029         public static final int LOSING       = 3;
   2030         /** @hide */
   2031         public static final int LOST         = 4;
   2032         /** @hide */
   2033         public static final int UNAVAIL      = 5;
   2034         /** @hide */
   2035         public static final int CAP_CHANGED  = 6;
   2036         /** @hide */
   2037         public static final int PROP_CHANGED = 7;
   2038         /** @hide */
   2039         public static final int CANCELED     = 8;
   2040 
   2041         /**
   2042          * @hide
   2043          * Called whenever the framework connects to a network that it may use to
   2044          * satisfy this request
   2045          */
   2046         public void onPreCheck(Network network) {}
   2047 
   2048         /**
   2049          * Called when the framework connects and has declared new network ready for use.
   2050          * This callback may be called more than once if the {@link Network} that is
   2051          * satisfying the request changes.
   2052          *
   2053          * @param network The {@link Network} of the satisfying network.
   2054          */
   2055         public void onAvailable(Network network) {}
   2056 
   2057         /**
   2058          * Called when the network is about to be disconnected.  Often paired with an
   2059          * {@link NetworkCallback#onAvailable} call with the new replacement network
   2060          * for graceful handover.  This may not be called if we have a hard loss
   2061          * (loss without warning).  This may be followed by either a
   2062          * {@link NetworkCallback#onLost} call or a
   2063          * {@link NetworkCallback#onAvailable} call for this network depending
   2064          * on whether we lose or regain it.
   2065          *
   2066          * @param network The {@link Network} that is about to be disconnected.
   2067          * @param maxMsToLive The time in ms the framework will attempt to keep the
   2068          *                     network connected.  Note that the network may suffer a
   2069          *                     hard loss at any time.
   2070          */
   2071         public void onLosing(Network network, int maxMsToLive) {}
   2072 
   2073         /**
   2074          * Called when the framework has a hard loss of the network or when the
   2075          * graceful failure ends.
   2076          *
   2077          * @param network The {@link Network} lost.
   2078          */
   2079         public void onLost(Network network) {}
   2080 
   2081         /**
   2082          * Called if no network is found in the given timeout time.  If no timeout is given,
   2083          * this will not be called.
   2084          * @hide
   2085          */
   2086         public void onUnavailable() {}
   2087 
   2088         /**
   2089          * Called when the network the framework connected to for this request
   2090          * changes capabilities but still satisfies the stated need.
   2091          *
   2092          * @param network The {@link Network} whose capabilities have changed.
   2093          * @param networkCapabilities The new {@link NetworkCapabilities} for this network.
   2094          */
   2095         public void onCapabilitiesChanged(Network network,
   2096                 NetworkCapabilities networkCapabilities) {}
   2097 
   2098         /**
   2099          * Called when the network the framework connected to for this request
   2100          * changes {@link LinkProperties}.
   2101          *
   2102          * @param network The {@link Network} whose link properties have changed.
   2103          * @param linkProperties The new {@link LinkProperties} for this network.
   2104          */
   2105         public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {}
   2106 
   2107         private NetworkRequest networkRequest;
   2108     }
   2109 
   2110     private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER;
   2111     /** @hide obj = pair(NetworkRequest, Network) */
   2112     public static final int CALLBACK_PRECHECK           = BASE + 1;
   2113     /** @hide obj = pair(NetworkRequest, Network) */
   2114     public static final int CALLBACK_AVAILABLE          = BASE + 2;
   2115     /** @hide obj = pair(NetworkRequest, Network), arg1 = ttl */
   2116     public static final int CALLBACK_LOSING             = BASE + 3;
   2117     /** @hide obj = pair(NetworkRequest, Network) */
   2118     public static final int CALLBACK_LOST               = BASE + 4;
   2119     /** @hide obj = NetworkRequest */
   2120     public static final int CALLBACK_UNAVAIL            = BASE + 5;
   2121     /** @hide obj = pair(NetworkRequest, Network) */
   2122     public static final int CALLBACK_CAP_CHANGED        = BASE + 6;
   2123     /** @hide obj = pair(NetworkRequest, Network) */
   2124     public static final int CALLBACK_IP_CHANGED         = BASE + 7;
   2125     /** @hide obj = NetworkRequest */
   2126     public static final int CALLBACK_RELEASED           = BASE + 8;
   2127     /** @hide */
   2128     public static final int CALLBACK_EXIT               = BASE + 9;
   2129     /** @hide obj = NetworkCapabilities, arg1 = seq number */
   2130     private static final int EXPIRE_LEGACY_REQUEST      = BASE + 10;
   2131 
   2132     private class CallbackHandler extends Handler {
   2133         private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap;
   2134         private final AtomicInteger mRefCount;
   2135         private static final String TAG = "ConnectivityManager.CallbackHandler";
   2136         private final ConnectivityManager mCm;
   2137 
   2138         CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallback>callbackMap,
   2139                 AtomicInteger refCount, ConnectivityManager cm) {
   2140             super(looper);
   2141             mCallbackMap = callbackMap;
   2142             mRefCount = refCount;
   2143             mCm = cm;
   2144         }
   2145 
   2146         @Override
   2147         public void handleMessage(Message message) {
   2148             Log.d(TAG, "CM callback handler got msg " + message.what);
   2149             switch (message.what) {
   2150                 case CALLBACK_PRECHECK: {
   2151                     NetworkRequest request = (NetworkRequest)getObject(message,
   2152                             NetworkRequest.class);
   2153                     NetworkCallback callbacks = getCallbacks(request);
   2154                     if (callbacks != null) {
   2155                         callbacks.onPreCheck((Network)getObject(message, Network.class));
   2156                     } else {
   2157                         Log.e(TAG, "callback not found for PRECHECK message");
   2158                     }
   2159                     break;
   2160                 }
   2161                 case CALLBACK_AVAILABLE: {
   2162                     NetworkRequest request = (NetworkRequest)getObject(message,
   2163                             NetworkRequest.class);
   2164                     NetworkCallback callbacks = getCallbacks(request);
   2165                     if (callbacks != null) {
   2166                         callbacks.onAvailable((Network)getObject(message, Network.class));
   2167                     } else {
   2168                         Log.e(TAG, "callback not found for AVAILABLE message");
   2169                     }
   2170                     break;
   2171                 }
   2172                 case CALLBACK_LOSING: {
   2173                     NetworkRequest request = (NetworkRequest)getObject(message,
   2174                             NetworkRequest.class);
   2175                     NetworkCallback callbacks = getCallbacks(request);
   2176                     if (callbacks != null) {
   2177                         callbacks.onLosing((Network)getObject(message, Network.class),
   2178                                 message.arg1);
   2179                     } else {
   2180                         Log.e(TAG, "callback not found for LOSING message");
   2181                     }
   2182                     break;
   2183                 }
   2184                 case CALLBACK_LOST: {
   2185                     NetworkRequest request = (NetworkRequest)getObject(message,
   2186                             NetworkRequest.class);
   2187 
   2188                     NetworkCallback callbacks = getCallbacks(request);
   2189                     if (callbacks != null) {
   2190                         callbacks.onLost((Network)getObject(message, Network.class));
   2191                     } else {
   2192                         Log.e(TAG, "callback not found for LOST message");
   2193                     }
   2194                     break;
   2195                 }
   2196                 case CALLBACK_UNAVAIL: {
   2197                     NetworkRequest request = (NetworkRequest)getObject(message,
   2198                             NetworkRequest.class);
   2199                     NetworkCallback callbacks = null;
   2200                     synchronized(mCallbackMap) {
   2201                         callbacks = mCallbackMap.get(request);
   2202                     }
   2203                     if (callbacks != null) {
   2204                         callbacks.onUnavailable();
   2205                     } else {
   2206                         Log.e(TAG, "callback not found for UNAVAIL message");
   2207                     }
   2208                     break;
   2209                 }
   2210                 case CALLBACK_CAP_CHANGED: {
   2211                     NetworkRequest request = (NetworkRequest)getObject(message,
   2212                             NetworkRequest.class);
   2213                     NetworkCallback callbacks = getCallbacks(request);
   2214                     if (callbacks != null) {
   2215                         Network network = (Network)getObject(message, Network.class);
   2216                         NetworkCapabilities cap = (NetworkCapabilities)getObject(message,
   2217                                 NetworkCapabilities.class);
   2218 
   2219                         callbacks.onCapabilitiesChanged(network, cap);
   2220                     } else {
   2221                         Log.e(TAG, "callback not found for CAP_CHANGED message");
   2222                     }
   2223                     break;
   2224                 }
   2225                 case CALLBACK_IP_CHANGED: {
   2226                     NetworkRequest request = (NetworkRequest)getObject(message,
   2227                             NetworkRequest.class);
   2228                     NetworkCallback callbacks = getCallbacks(request);
   2229                     if (callbacks != null) {
   2230                         Network network = (Network)getObject(message, Network.class);
   2231                         LinkProperties lp = (LinkProperties)getObject(message,
   2232                                 LinkProperties.class);
   2233 
   2234                         callbacks.onLinkPropertiesChanged(network, lp);
   2235                     } else {
   2236                         Log.e(TAG, "callback not found for IP_CHANGED message");
   2237                     }
   2238                     break;
   2239                 }
   2240                 case CALLBACK_RELEASED: {
   2241                     NetworkRequest req = (NetworkRequest)getObject(message, NetworkRequest.class);
   2242                     NetworkCallback callbacks = null;
   2243                     synchronized(mCallbackMap) {
   2244                         callbacks = mCallbackMap.remove(req);
   2245                     }
   2246                     if (callbacks != null) {
   2247                         synchronized(mRefCount) {
   2248                             if (mRefCount.decrementAndGet() == 0) {
   2249                                 getLooper().quit();
   2250                             }
   2251                         }
   2252                     } else {
   2253                         Log.e(TAG, "callback not found for CANCELED message");
   2254                     }
   2255                     break;
   2256                 }
   2257                 case CALLBACK_EXIT: {
   2258                     Log.d(TAG, "Listener quiting");
   2259                     getLooper().quit();
   2260                     break;
   2261                 }
   2262                 case EXPIRE_LEGACY_REQUEST: {
   2263                     expireRequest((NetworkCapabilities)message.obj, message.arg1);
   2264                     break;
   2265                 }
   2266             }
   2267         }
   2268 
   2269         private Object getObject(Message msg, Class c) {
   2270             return msg.getData().getParcelable(c.getSimpleName());
   2271         }
   2272         private NetworkCallback getCallbacks(NetworkRequest req) {
   2273             synchronized(mCallbackMap) {
   2274                 return mCallbackMap.get(req);
   2275             }
   2276         }
   2277     }
   2278 
   2279     private void incCallbackHandlerRefCount() {
   2280         synchronized(sCallbackRefCount) {
   2281             if (sCallbackRefCount.incrementAndGet() == 1) {
   2282                 // TODO - switch this over to a ManagerThread or expire it when done
   2283                 HandlerThread callbackThread = new HandlerThread("ConnectivityManager");
   2284                 callbackThread.start();
   2285                 sCallbackHandler = new CallbackHandler(callbackThread.getLooper(),
   2286                         sNetworkCallback, sCallbackRefCount, this);
   2287             }
   2288         }
   2289     }
   2290 
   2291     private void decCallbackHandlerRefCount() {
   2292         synchronized(sCallbackRefCount) {
   2293             if (sCallbackRefCount.decrementAndGet() == 0) {
   2294                 sCallbackHandler.obtainMessage(CALLBACK_EXIT).sendToTarget();
   2295                 sCallbackHandler = null;
   2296             }
   2297         }
   2298     }
   2299 
   2300     static final HashMap<NetworkRequest, NetworkCallback> sNetworkCallback =
   2301             new HashMap<NetworkRequest, NetworkCallback>();
   2302     static final AtomicInteger sCallbackRefCount = new AtomicInteger(0);
   2303     static CallbackHandler sCallbackHandler = null;
   2304 
   2305     private final static int LISTEN  = 1;
   2306     private final static int REQUEST = 2;
   2307 
   2308     private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
   2309             NetworkCallback networkCallback, int timeoutSec, int action,
   2310             int legacyType) {
   2311         if (networkCallback == null) {
   2312             throw new IllegalArgumentException("null NetworkCallback");
   2313         }
   2314         if (need == null) throw new IllegalArgumentException("null NetworkCapabilities");
   2315         try {
   2316             incCallbackHandlerRefCount();
   2317             synchronized(sNetworkCallback) {
   2318                 if (action == LISTEN) {
   2319                     networkCallback.networkRequest = mService.listenForNetwork(need,
   2320                             new Messenger(sCallbackHandler), new Binder());
   2321                 } else {
   2322                     networkCallback.networkRequest = mService.requestNetwork(need,
   2323                             new Messenger(sCallbackHandler), timeoutSec, new Binder(), legacyType);
   2324                 }
   2325                 if (networkCallback.networkRequest != null) {
   2326                     sNetworkCallback.put(networkCallback.networkRequest, networkCallback);
   2327                 }
   2328             }
   2329         } catch (RemoteException e) {}
   2330         if (networkCallback.networkRequest == null) decCallbackHandlerRefCount();
   2331         return networkCallback.networkRequest;
   2332     }
   2333 
   2334     /**
   2335      * Request a network to satisfy a set of {@link NetworkCapabilities}.
   2336      *
   2337      * This {@link NetworkRequest} will live until released via
   2338      * {@link #unregisterNetworkCallback} or the calling application exits.
   2339      * Status of the request can be followed by listening to the various
   2340      * callbacks described in {@link NetworkCallback}.  The {@link Network}
   2341      * can be used to direct traffic to the network.
   2342      *
   2343      * @param request {@link NetworkRequest} describing this request.
   2344      * @param networkCallback The {@link NetworkCallback} to be utilized for this
   2345      *                        request.  Note the callback must not be shared - they
   2346      *                        uniquely specify this request.
   2347      */
   2348     public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) {
   2349         sendRequestForNetwork(request.networkCapabilities, networkCallback, 0,
   2350                 REQUEST, inferLegacyTypeForNetworkCapabilities(request.networkCapabilities));
   2351     }
   2352 
   2353     /**
   2354      * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
   2355      * by a timeout.
   2356      *
   2357      * This function behaves identically to the non-timedout version, but if a suitable
   2358      * network is not found within the given time (in milliseconds) the
   2359      * {@link NetworkCallback#unavailable} callback is called.  The request must
   2360      * still be released normally by calling {@link releaseNetworkRequest}.
   2361      * @param request {@link NetworkRequest} describing this request.
   2362      * @param networkCallback The callbacks to be utilized for this request.  Note
   2363      *                        the callbacks must not be shared - they uniquely specify
   2364      *                        this request.
   2365      * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
   2366      *                  before {@link NetworkCallback#unavailable} is called.
   2367      * @hide
   2368      */
   2369     public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
   2370             int timeoutMs) {
   2371         sendRequestForNetwork(request.networkCapabilities, networkCallback, timeoutMs,
   2372                 REQUEST, inferLegacyTypeForNetworkCapabilities(request.networkCapabilities));
   2373     }
   2374 
   2375     /**
   2376      * The maximum number of milliseconds the framework will look for a suitable network
   2377      * during a timeout-equiped call to {@link requestNetwork}.
   2378      * {@hide}
   2379      */
   2380     public final static int MAX_NETWORK_REQUEST_TIMEOUT_MS = 100 * 60 * 1000;
   2381 
   2382     /**
   2383      * The lookup key for a {@link Network} object included with the intent after
   2384      * succesfully finding a network for the applications request.  Retrieve it with
   2385      * {@link android.content.Intent#getParcelableExtra(String)}.
   2386      * @hide
   2387      */
   2388     public static final String EXTRA_NETWORK_REQUEST_NETWORK = "networkRequestNetwork";
   2389 
   2390     /**
   2391      * The lookup key for a {@link NetworkRequest} object included with the intent after
   2392      * succesfully finding a network for the applications request.  Retrieve it with
   2393      * {@link android.content.Intent#getParcelableExtra(String)}.
   2394      * @hide
   2395      */
   2396     public static final String EXTRA_NETWORK_REQUEST_NETWORK_REQUEST =
   2397             "networkRequestNetworkRequest";
   2398 
   2399 
   2400     /**
   2401      * Request a network to satisfy a set of {@link NetworkCapabilities}.
   2402      *
   2403      * This function behavies identically to the version that takes a NetworkCallback, but instead
   2404      * of {@link NetworkCallback} a {@link PendingIntent} is used.  This means
   2405      * the request may outlive the calling application and get called back when a suitable
   2406      * network is found.
   2407      * <p>
   2408      * The operation is an Intent broadcast that goes to a broadcast receiver that
   2409      * you registered with {@link Context#registerReceiver} or through the
   2410      * &lt;receiver&gt; tag in an AndroidManifest.xml file
   2411      * <p>
   2412      * The operation Intent is delivered with two extras, a {@link Network} typed
   2413      * extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK} and a {@link NetworkRequest}
   2414      * typed extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK_REQUEST} containing
   2415      * the original requests parameters.  It is important to create a new,
   2416      * {@link NetworkCallback} based request before completing the processing of the
   2417      * Intent to reserve the network or it will be released shortly after the Intent
   2418      * is processed.
   2419      * <p>
   2420      * If there is already an request for this Intent registered (with the equality of
   2421      * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
   2422      * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
   2423      * <p>
   2424      * The request may be released normally by calling {@link #unregisterNetworkCallback}.
   2425      *
   2426      * @param request {@link NetworkRequest} describing this request.
   2427      * @param operation Action to perform when the network is available (corresponds
   2428      *                  to the {@link NetworkCallback#onAvailable} call.  Typically
   2429      *                  comes from {@link PendingIntent#getBroadcast}.
   2430      * @hide
   2431      */
   2432     public void requestNetwork(NetworkRequest request, PendingIntent operation) {
   2433         try {
   2434             mService.pendingRequestForNetwork(request.networkCapabilities, operation);
   2435         } catch (RemoteException e) {}
   2436     }
   2437 
   2438     /**
   2439      * Registers to receive notifications about all networks which satisfy the given
   2440      * {@link NetworkRequest}.  The callbacks will continue to be called until
   2441      * either the application exits or {@link #unregisterNetworkCallback} is called
   2442      *
   2443      * @param request {@link NetworkRequest} describing this request.
   2444      * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
   2445      *                        networks change state.
   2446      */
   2447     public void registerNetworkCallback(NetworkRequest request, NetworkCallback networkCallback) {
   2448         sendRequestForNetwork(request.networkCapabilities, networkCallback, 0, LISTEN, TYPE_NONE);
   2449     }
   2450 
   2451     /**
   2452      * Unregisters callbacks about and possibly releases networks originating from
   2453      * {@link #requestNetwork} and {@link #registerNetworkCallback} calls.  If the
   2454      * given {@code NetworkCallback} had previosuly been used with {@code #requestNetwork},
   2455      * any networks that had been connected to only to satisfy that request will be
   2456      * disconnected.
   2457      *
   2458      * @param networkCallback The {@link NetworkCallback} used when making the request.
   2459      */
   2460     public void unregisterNetworkCallback(NetworkCallback networkCallback) {
   2461         if (networkCallback == null || networkCallback.networkRequest == null ||
   2462                 networkCallback.networkRequest.requestId == REQUEST_ID_UNSET) {
   2463             throw new IllegalArgumentException("Invalid NetworkCallback");
   2464         }
   2465         try {
   2466             mService.releaseNetworkRequest(networkCallback.networkRequest);
   2467         } catch (RemoteException e) {}
   2468     }
   2469 
   2470     /**
   2471      * Binds the current process to {@code network}.  All Sockets created in the future
   2472      * (and not explicitly bound via a bound SocketFactory from
   2473      * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
   2474      * {@code network}.  All host name resolutions will be limited to {@code network} as well.
   2475      * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
   2476      * work and all host name resolutions will fail.  This is by design so an application doesn't
   2477      * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
   2478      * To clear binding pass {@code null} for {@code network}.  Using individually bound
   2479      * Sockets created by Network.getSocketFactory().createSocket() and
   2480      * performing network-specific host name resolutions via
   2481      * {@link Network#getAllByName Network.getAllByName} is preferred to calling
   2482      * {@code setProcessDefaultNetwork}.
   2483      *
   2484      * @param network The {@link Network} to bind the current process to, or {@code null} to clear
   2485      *                the current binding.
   2486      * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
   2487      */
   2488     public static boolean setProcessDefaultNetwork(Network network) {
   2489         int netId = (network == null) ? NETID_UNSET : network.netId;
   2490         if (netId == NetworkUtils.getNetworkBoundToProcess()) {
   2491             return true;
   2492         }
   2493         if (NetworkUtils.bindProcessToNetwork(netId)) {
   2494             // Must flush DNS cache as new network may have different DNS resolutions.
   2495             InetAddress.clearDnsCache();
   2496             // Must flush socket pool as idle sockets will be bound to previous network and may
   2497             // cause subsequent fetches to be performed on old network.
   2498             NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
   2499             return true;
   2500         } else {
   2501             return false;
   2502         }
   2503     }
   2504 
   2505     /**
   2506      * Returns the {@link Network} currently bound to this process via
   2507      * {@link #setProcessDefaultNetwork}, or {@code null} if no {@link Network} is explicitly bound.
   2508      *
   2509      * @return {@code Network} to which this process is bound, or {@code null}.
   2510      */
   2511     public static Network getProcessDefaultNetwork() {
   2512         int netId = NetworkUtils.getNetworkBoundToProcess();
   2513         if (netId == NETID_UNSET) return null;
   2514         return new Network(netId);
   2515     }
   2516 
   2517     /**
   2518      * Binds host resolutions performed by this process to {@code network}.
   2519      * {@link #setProcessDefaultNetwork} takes precedence over this setting.
   2520      *
   2521      * @param network The {@link Network} to bind host resolutions from the current process to, or
   2522      *                {@code null} to clear the current binding.
   2523      * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
   2524      * @hide
   2525      * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}.
   2526      */
   2527     public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
   2528         return NetworkUtils.bindProcessToNetworkForHostResolution(
   2529                 network == null ? NETID_UNSET : network.netId);
   2530     }
   2531 }
   2532