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.SubscriptionManager;
     41 import android.telephony.TelephonyManager;
     42 import android.util.ArrayMap;
     43 import android.util.Log;
     44 
     45 import com.android.internal.telephony.ITelephony;
     46 import com.android.internal.telephony.PhoneConstants;
     47 import com.android.internal.util.Protocol;
     48 
     49 import java.net.InetAddress;
     50 import java.util.concurrent.atomic.AtomicInteger;
     51 import java.util.HashMap;
     52 
     53 import libcore.net.event.NetworkEventDispatcher;
     54 
     55 /**
     56  * Class that answers queries about the state of network connectivity. It also
     57  * notifies applications when network connectivity changes. Get an instance
     58  * of this class by calling
     59  * {@link android.content.Context#getSystemService(String) Context.getSystemService(Context.CONNECTIVITY_SERVICE)}.
     60  * <p>
     61  * The primary responsibilities of this class are to:
     62  * <ol>
     63  * <li>Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)</li>
     64  * <li>Send broadcast intents when network connectivity changes</li>
     65  * <li>Attempt to "fail over" to another network when connectivity to a network
     66  * is lost</li>
     67  * <li>Provide an API that allows applications to query the coarse-grained or fine-grained
     68  * state of the available networks</li>
     69  * <li>Provide an API that allows applications to request and select networks for their data
     70  * traffic</li>
     71  * </ol>
     72  */
     73 public class ConnectivityManager {
     74     private static final String TAG = "ConnectivityManager";
     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      * historic {@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      * @hide
    433      */
    434     public final static int REQUEST_ID_UNSET = 0;
    435 
    436     /**
    437      * A NetID indicating no Network is selected.
    438      * Keep in sync with bionic/libc/dns/include/resolv_netid.h
    439      * @hide
    440      */
    441     public static final int NETID_UNSET = 0;
    442 
    443     private final IConnectivityManager mService;
    444     /**
    445      * A kludge to facilitate static access where a Context pointer isn't available, like in the
    446      * case of the static set/getProcessDefaultNetwork methods and from the Network class.
    447      * TODO: Remove this after deprecating the static methods in favor of non-static methods or
    448      * methods that take a Context argument.
    449      */
    450     private static ConnectivityManager sInstance;
    451 
    452     private INetworkManagementService mNMService;
    453 
    454     /**
    455      * Tests if a given integer represents a valid network type.
    456      * @param networkType the type to be tested
    457      * @return a boolean.  {@code true} if the type is valid, else {@code false}
    458      */
    459     public static boolean isNetworkTypeValid(int networkType) {
    460         return networkType >= 0 && networkType <= MAX_NETWORK_TYPE;
    461     }
    462 
    463     /**
    464      * Returns a non-localized string representing a given network type.
    465      * ONLY used for debugging output.
    466      * @param type the type needing naming
    467      * @return a String for the given type, or a string version of the type ("87")
    468      * if no name is known.
    469      * {@hide}
    470      */
    471     public static String getNetworkTypeName(int type) {
    472         switch (type) {
    473             case TYPE_MOBILE:
    474                 return "MOBILE";
    475             case TYPE_WIFI:
    476                 return "WIFI";
    477             case TYPE_MOBILE_MMS:
    478                 return "MOBILE_MMS";
    479             case TYPE_MOBILE_SUPL:
    480                 return "MOBILE_SUPL";
    481             case TYPE_MOBILE_DUN:
    482                 return "MOBILE_DUN";
    483             case TYPE_MOBILE_HIPRI:
    484                 return "MOBILE_HIPRI";
    485             case TYPE_WIMAX:
    486                 return "WIMAX";
    487             case TYPE_BLUETOOTH:
    488                 return "BLUETOOTH";
    489             case TYPE_DUMMY:
    490                 return "DUMMY";
    491             case TYPE_ETHERNET:
    492                 return "ETHERNET";
    493             case TYPE_MOBILE_FOTA:
    494                 return "MOBILE_FOTA";
    495             case TYPE_MOBILE_IMS:
    496                 return "MOBILE_IMS";
    497             case TYPE_MOBILE_CBS:
    498                 return "MOBILE_CBS";
    499             case TYPE_WIFI_P2P:
    500                 return "WIFI_P2P";
    501             case TYPE_MOBILE_IA:
    502                 return "MOBILE_IA";
    503             case TYPE_MOBILE_EMERGENCY:
    504                 return "MOBILE_EMERGENCY";
    505             case TYPE_PROXY:
    506                 return "PROXY";
    507             default:
    508                 return Integer.toString(type);
    509         }
    510     }
    511 
    512     /**
    513      * Checks if a given type uses the cellular data connection.
    514      * This should be replaced in the future by a network property.
    515      * @param networkType the type to check
    516      * @return a boolean - {@code true} if uses cellular network, else {@code false}
    517      * {@hide}
    518      */
    519     public static boolean isNetworkTypeMobile(int networkType) {
    520         switch (networkType) {
    521             case TYPE_MOBILE:
    522             case TYPE_MOBILE_MMS:
    523             case TYPE_MOBILE_SUPL:
    524             case TYPE_MOBILE_DUN:
    525             case TYPE_MOBILE_HIPRI:
    526             case TYPE_MOBILE_FOTA:
    527             case TYPE_MOBILE_IMS:
    528             case TYPE_MOBILE_CBS:
    529             case TYPE_MOBILE_IA:
    530             case TYPE_MOBILE_EMERGENCY:
    531                 return true;
    532             default:
    533                 return false;
    534         }
    535     }
    536 
    537     /**
    538      * Checks if the given network type is backed by a Wi-Fi radio.
    539      *
    540      * @hide
    541      */
    542     public static boolean isNetworkTypeWifi(int networkType) {
    543         switch (networkType) {
    544             case TYPE_WIFI:
    545             case TYPE_WIFI_P2P:
    546                 return true;
    547             default:
    548                 return false;
    549         }
    550     }
    551 
    552     /**
    553      * Specifies the preferred network type.  When the device has more
    554      * than one type available the preferred network type will be used.
    555      *
    556      * @param preference the network type to prefer over all others.  It is
    557      *         unspecified what happens to the old preferred network in the
    558      *         overall ordering.
    559      * @deprecated Functionality has been removed as it no longer makes sense,
    560      *             with many more than two networks - we'd need an array to express
    561      *             preference.  Instead we use dynamic network properties of
    562      *             the networks to describe their precedence.
    563      */
    564     public void setNetworkPreference(int preference) {
    565     }
    566 
    567     /**
    568      * Retrieves the current preferred network type.
    569      *
    570      * @return an integer representing the preferred network type
    571      *
    572      * <p>This method requires the caller to hold the permission
    573      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    574      * @deprecated Functionality has been removed as it no longer makes sense,
    575      *             with many more than two networks - we'd need an array to express
    576      *             preference.  Instead we use dynamic network properties of
    577      *             the networks to describe their precedence.
    578      */
    579     public int getNetworkPreference() {
    580         return TYPE_NONE;
    581     }
    582 
    583     /**
    584      * Returns details about the currently active default data network. When
    585      * connected, this network is the default route for outgoing connections.
    586      * You should always check {@link NetworkInfo#isConnected()} before initiating
    587      * network traffic. This may return {@code null} when there is no default
    588      * network.
    589      *
    590      * @return a {@link NetworkInfo} object for the current default network
    591      *        or {@code null} if no network default network is currently active
    592      *
    593      * <p>This method requires the call to hold the permission
    594      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    595      */
    596     public NetworkInfo getActiveNetworkInfo() {
    597         try {
    598             return mService.getActiveNetworkInfo();
    599         } catch (RemoteException e) {
    600             return null;
    601         }
    602     }
    603 
    604     /**
    605      * Returns details about the currently active default data network
    606      * for a given uid.  This is for internal use only to avoid spying
    607      * other apps.
    608      *
    609      * @return a {@link NetworkInfo} object for the current default network
    610      *        for the given uid or {@code null} if no default network is
    611      *        available for the specified uid.
    612      *
    613      * <p>This method requires the caller to hold the permission
    614      * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}
    615      * {@hide}
    616      */
    617     public NetworkInfo getActiveNetworkInfoForUid(int uid) {
    618         try {
    619             return mService.getActiveNetworkInfoForUid(uid);
    620         } catch (RemoteException e) {
    621             return null;
    622         }
    623     }
    624 
    625     /**
    626      * Returns connection status information about a particular
    627      * network type.
    628      *
    629      * @param networkType integer specifying which networkType in
    630      *        which you're interested.
    631      * @return a {@link NetworkInfo} object for the requested
    632      *        network type or {@code null} if the type is not
    633      *        supported by the device.
    634      *
    635      * <p>This method requires the caller to hold the permission
    636      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    637      */
    638     public NetworkInfo getNetworkInfo(int networkType) {
    639         try {
    640             return mService.getNetworkInfo(networkType);
    641         } catch (RemoteException e) {
    642             return null;
    643         }
    644     }
    645 
    646     /**
    647      * Returns connection status information about a particular
    648      * Network.
    649      *
    650      * @param network {@link Network} specifying which network
    651      *        in which you're interested.
    652      * @return a {@link NetworkInfo} object for the requested
    653      *        network or {@code null} if the {@code Network}
    654      *        is not valid.
    655      *
    656      * <p>This method requires the caller to hold the permission
    657      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    658      */
    659     public NetworkInfo getNetworkInfo(Network network) {
    660         try {
    661             return mService.getNetworkInfoForNetwork(network);
    662         } catch (RemoteException e) {
    663             return null;
    664         }
    665     }
    666 
    667     /**
    668      * Returns connection status information about all network
    669      * types supported by the device.
    670      *
    671      * @return an array of {@link NetworkInfo} objects.  Check each
    672      * {@link NetworkInfo#getType} for which type each applies.
    673      *
    674      * <p>This method requires the caller to hold the permission
    675      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    676      */
    677     public NetworkInfo[] getAllNetworkInfo() {
    678         try {
    679             return mService.getAllNetworkInfo();
    680         } catch (RemoteException e) {
    681             return null;
    682         }
    683     }
    684 
    685     /**
    686      * Returns the {@link Network} object currently serving a given type, or
    687      * null if the given type is not connected.
    688      *
    689      * <p>This method requires the caller to hold the permission
    690      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    691      *
    692      * @hide
    693      */
    694     public Network getNetworkForType(int networkType) {
    695         try {
    696             return mService.getNetworkForType(networkType);
    697         } catch (RemoteException e) {
    698             return null;
    699         }
    700     }
    701 
    702     /**
    703      * Returns an array of all {@link Network} currently tracked by the
    704      * framework.
    705      *
    706      * @return an array of {@link Network} objects.
    707      *
    708      * <p>This method requires the caller to hold the permission
    709      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    710      */
    711     public Network[] getAllNetworks() {
    712         try {
    713             return mService.getAllNetworks();
    714         } catch (RemoteException e) {
    715             return null;
    716         }
    717     }
    718 
    719     /**
    720      * Returns an array of of {@link NetworkCapabilities} objects, representing
    721      * the Networks that applications run by the given user will use by default.
    722      * @hide
    723      */
    724     public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
    725         try {
    726             return mService.getDefaultNetworkCapabilitiesForUser(userId);
    727         } catch (RemoteException e) {
    728             return null;
    729         }
    730     }
    731 
    732     /**
    733      * Returns details about the Provisioning or currently active default data network. When
    734      * connected, this network is the default route for outgoing connections.
    735      * You should always check {@link NetworkInfo#isConnected()} before initiating
    736      * network traffic. This may return {@code null} when there is no default
    737      * network.
    738      *
    739      * @return a {@link NetworkInfo} object for the current default network
    740      *        or {@code null} if no network default network is currently active
    741      *
    742      * <p>This method requires the call to hold the permission
    743      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    744      *
    745      * {@hide}
    746      */
    747     public NetworkInfo getProvisioningOrActiveNetworkInfo() {
    748         try {
    749             return mService.getProvisioningOrActiveNetworkInfo();
    750         } catch (RemoteException e) {
    751             return null;
    752         }
    753     }
    754 
    755     /**
    756      * Returns the IP information for the current default network.
    757      *
    758      * @return a {@link LinkProperties} object describing the IP info
    759      *        for the current default network, or {@code null} if there
    760      *        is no current default network.
    761      *
    762      * <p>This method requires the call to hold the permission
    763      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    764      * {@hide}
    765      */
    766     public LinkProperties getActiveLinkProperties() {
    767         try {
    768             return mService.getActiveLinkProperties();
    769         } catch (RemoteException e) {
    770             return null;
    771         }
    772     }
    773 
    774     /**
    775      * Returns the IP information for a given network type.
    776      *
    777      * @param networkType the network type of interest.
    778      * @return a {@link LinkProperties} object describing the IP info
    779      *        for the given networkType, or {@code null} if there is
    780      *        no current default network.
    781      *
    782      * <p>This method requires the call to hold the permission
    783      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
    784      * {@hide}
    785      */
    786     public LinkProperties getLinkProperties(int networkType) {
    787         try {
    788             return mService.getLinkPropertiesForType(networkType);
    789         } catch (RemoteException e) {
    790             return null;
    791         }
    792     }
    793 
    794     /**
    795      * Get the {@link LinkProperties} for the given {@link Network}.  This
    796      * will return {@code null} if the network is unknown.
    797      *
    798      * @param network The {@link Network} object identifying the network in question.
    799      * @return The {@link LinkProperties} for the network, or {@code null}.
    800      **/
    801     public LinkProperties getLinkProperties(Network network) {
    802         try {
    803             return mService.getLinkProperties(network);
    804         } catch (RemoteException e) {
    805             return null;
    806         }
    807     }
    808 
    809     /**
    810      * Get the {@link NetworkCapabilities} for the given {@link Network}.  This
    811      * will return {@code null} if the network is unknown.
    812      *
    813      * @param network The {@link Network} object identifying the network in question.
    814      * @return The {@link NetworkCapabilities} for the network, or {@code null}.
    815      */
    816     public NetworkCapabilities getNetworkCapabilities(Network network) {
    817         try {
    818             return mService.getNetworkCapabilities(network);
    819         } catch (RemoteException e) {
    820             return null;
    821         }
    822     }
    823 
    824     /**
    825      * Tells each network type to set its radio power state as directed.
    826      *
    827      * @param turnOn a boolean, {@code true} to turn the radios on,
    828      *        {@code false} to turn them off.
    829      * @return a boolean, {@code true} indicating success.  All network types
    830      *        will be tried, even if some fail.
    831      *
    832      * <p>This method requires the call to hold the permission
    833      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
    834      * {@hide}
    835      */
    836 // TODO - check for any callers and remove
    837 //    public boolean setRadios(boolean turnOn) {
    838 //        try {
    839 //            return mService.setRadios(turnOn);
    840 //        } catch (RemoteException e) {
    841 //            return false;
    842 //        }
    843 //    }
    844 
    845     /**
    846      * Tells a given networkType to set its radio power state as directed.
    847      *
    848      * @param networkType the int networkType of interest.
    849      * @param turnOn a boolean, {@code true} to turn the radio on,
    850      *        {@code} false to turn it off.
    851      * @return a boolean, {@code true} indicating success.
    852      *
    853      * <p>This method requires the call to hold the permission
    854      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
    855      * {@hide}
    856      */
    857 // TODO - check for any callers and remove
    858 //    public boolean setRadio(int networkType, boolean turnOn) {
    859 //        try {
    860 //            return mService.setRadio(networkType, turnOn);
    861 //        } catch (RemoteException e) {
    862 //            return false;
    863 //        }
    864 //    }
    865 
    866     /**
    867      * Tells the underlying networking system that the caller wants to
    868      * begin using the named feature. The interpretation of {@code feature}
    869      * is completely up to each networking implementation.
    870      * <p>This method requires the caller to hold the permission
    871      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
    872      * @param networkType specifies which network the request pertains to
    873      * @param feature the name of the feature to be used
    874      * @return an integer value representing the outcome of the request.
    875      * The interpretation of this value is specific to each networking
    876      * implementation+feature combination, except that the value {@code -1}
    877      * always indicates failure.
    878      *
    879      * @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
    880      */
    881     public int startUsingNetworkFeature(int networkType, String feature) {
    882         NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
    883         if (netCap == null) {
    884             Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " +
    885                     feature);
    886             return PhoneConstants.APN_REQUEST_FAILED;
    887         }
    888 
    889         NetworkRequest request = null;
    890         synchronized (sLegacyRequests) {
    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         if (removeRequestForFeature(netCap)) {
    937             Log.d(TAG, "stopUsingNetworkFeature for " + networkType + ", " + feature);
    938         }
    939         return 1;
    940     }
    941 
    942     /**
    943      * Removes the NET_CAPABILITY_NOT_RESTRICTED capability from the given
    944      * NetworkCapabilities object if all the capabilities it provides are
    945      * typically provided by restricted networks.
    946      *
    947      * TODO: consider:
    948      * - Moving to NetworkCapabilities
    949      * - Renaming it to guessRestrictedCapability and make it set the
    950      *   restricted capability bit in addition to clearing it.
    951      * @hide
    952      */
    953     public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
    954         for (int capability : nc.getCapabilities()) {
    955             switch (capability) {
    956                 case NetworkCapabilities.NET_CAPABILITY_CBS:
    957                 case NetworkCapabilities.NET_CAPABILITY_DUN:
    958                 case NetworkCapabilities.NET_CAPABILITY_EIMS:
    959                 case NetworkCapabilities.NET_CAPABILITY_FOTA:
    960                 case NetworkCapabilities.NET_CAPABILITY_IA:
    961                 case NetworkCapabilities.NET_CAPABILITY_IMS:
    962                 case NetworkCapabilities.NET_CAPABILITY_RCS:
    963                 case NetworkCapabilities.NET_CAPABILITY_XCAP:
    964                 case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED: //there by default
    965                     continue;
    966                 default:
    967                     // At least one capability usually provided by unrestricted
    968                     // networks. Conclude that this network is unrestricted.
    969                     return;
    970             }
    971         }
    972         // All the capabilities are typically provided by restricted networks.
    973         // Conclude that this network is restricted.
    974         nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
    975     }
    976 
    977     private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
    978         if (networkType == TYPE_MOBILE) {
    979             int cap = -1;
    980             if ("enableMMS".equals(feature)) {
    981                 cap = NetworkCapabilities.NET_CAPABILITY_MMS;
    982             } else if ("enableSUPL".equals(feature)) {
    983                 cap = NetworkCapabilities.NET_CAPABILITY_SUPL;
    984             } else if ("enableDUN".equals(feature) || "enableDUNAlways".equals(feature)) {
    985                 cap = NetworkCapabilities.NET_CAPABILITY_DUN;
    986             } else if ("enableHIPRI".equals(feature)) {
    987                 cap = NetworkCapabilities.NET_CAPABILITY_INTERNET;
    988             } else if ("enableFOTA".equals(feature)) {
    989                 cap = NetworkCapabilities.NET_CAPABILITY_FOTA;
    990             } else if ("enableIMS".equals(feature)) {
    991                 cap = NetworkCapabilities.NET_CAPABILITY_IMS;
    992             } else if ("enableCBS".equals(feature)) {
    993                 cap = NetworkCapabilities.NET_CAPABILITY_CBS;
    994             } else {
    995                 return null;
    996             }
    997             NetworkCapabilities netCap = new NetworkCapabilities();
    998             netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
    999             maybeMarkCapabilitiesRestricted(netCap);
   1000             return netCap;
   1001         } else if (networkType == TYPE_WIFI) {
   1002             if ("p2p".equals(feature)) {
   1003                 NetworkCapabilities netCap = new NetworkCapabilities();
   1004                 netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
   1005                 netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
   1006                 maybeMarkCapabilitiesRestricted(netCap);
   1007                 return netCap;
   1008             }
   1009         }
   1010         return null;
   1011     }
   1012 
   1013     /**
   1014      * Guess what the network request was trying to say so that the resulting
   1015      * network is accessible via the legacy (deprecated) API such as
   1016      * requestRouteToHost.
   1017      * This means we should try to be fairly preceise about transport and
   1018      * capability but ignore things such as networkSpecifier.
   1019      * If the request has more than one transport or capability it doesn't
   1020      * match the old legacy requests (they selected only single transport/capability)
   1021      * so this function cannot map the request to a single legacy type and
   1022      * the resulting network will not be available to the legacy APIs.
   1023      *
   1024      * TODO - This should be removed when the legacy APIs are removed.
   1025      */
   1026     private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
   1027         if (netCap == null) {
   1028             return TYPE_NONE;
   1029         }
   1030 
   1031         if (!netCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
   1032             return TYPE_NONE;
   1033         }
   1034 
   1035         String type = null;
   1036         int result = TYPE_NONE;
   1037 
   1038         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
   1039             type = "enableCBS";
   1040             result = TYPE_MOBILE_CBS;
   1041         } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
   1042             type = "enableIMS";
   1043             result = TYPE_MOBILE_IMS;
   1044         } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
   1045             type = "enableFOTA";
   1046             result = TYPE_MOBILE_FOTA;
   1047         } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
   1048             type = "enableDUN";
   1049             result = TYPE_MOBILE_DUN;
   1050         } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
   1051             type = "enableSUPL";
   1052             result = TYPE_MOBILE_SUPL;
   1053         } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
   1054             type = "enableMMS";
   1055             result = TYPE_MOBILE_MMS;
   1056         } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
   1057             type = "enableHIPRI";
   1058             result = TYPE_MOBILE_HIPRI;
   1059         }
   1060         if (type != null) {
   1061             NetworkCapabilities testCap = networkCapabilitiesForFeature(TYPE_MOBILE, type);
   1062             if (testCap.equalsNetCapabilities(netCap) && testCap.equalsTransportTypes(netCap)) {
   1063                 return result;
   1064             }
   1065         }
   1066         return TYPE_NONE;
   1067     }
   1068 
   1069     private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
   1070         if (netCap == null) return TYPE_NONE;
   1071         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
   1072             return TYPE_MOBILE_CBS;
   1073         }
   1074         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
   1075             return TYPE_MOBILE_IMS;
   1076         }
   1077         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
   1078             return TYPE_MOBILE_FOTA;
   1079         }
   1080         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
   1081             return TYPE_MOBILE_DUN;
   1082         }
   1083         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
   1084             return TYPE_MOBILE_SUPL;
   1085         }
   1086         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
   1087             return TYPE_MOBILE_MMS;
   1088         }
   1089         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
   1090             return TYPE_MOBILE_HIPRI;
   1091         }
   1092         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) {
   1093             return TYPE_WIFI_P2P;
   1094         }
   1095         return TYPE_NONE;
   1096     }
   1097 
   1098     private static class LegacyRequest {
   1099         NetworkCapabilities networkCapabilities;
   1100         NetworkRequest networkRequest;
   1101         int expireSequenceNumber;
   1102         Network currentNetwork;
   1103         int delay = -1;
   1104 
   1105         private void clearDnsBinding() {
   1106             if (currentNetwork != null) {
   1107                 currentNetwork = null;
   1108                 setProcessDefaultNetworkForHostResolution(null);
   1109             }
   1110         }
   1111 
   1112         NetworkCallback networkCallback = new NetworkCallback() {
   1113             @Override
   1114             public void onAvailable(Network network) {
   1115                 currentNetwork = network;
   1116                 Log.d(TAG, "startUsingNetworkFeature got Network:" + network);
   1117                 setProcessDefaultNetworkForHostResolution(network);
   1118             }
   1119             @Override
   1120             public void onLost(Network network) {
   1121                 if (network.equals(currentNetwork)) clearDnsBinding();
   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) removeRequestForFeature(netCap);
   1151         }
   1152         Log.d(TAG, "expireRequest with " + ourSeqNum + ", " + sequenceNum);
   1153     }
   1154 
   1155     private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) {
   1156         int delay = -1;
   1157         int type = legacyTypeForNetworkCapabilities(netCap);
   1158         try {
   1159             delay = mService.getRestoreDefaultNetworkDelay(type);
   1160         } catch (RemoteException e) {}
   1161         LegacyRequest l = new LegacyRequest();
   1162         l.networkCapabilities = netCap;
   1163         l.delay = delay;
   1164         l.expireSequenceNumber = 0;
   1165         l.networkRequest = sendRequestForNetwork(netCap, l.networkCallback, 0,
   1166                 REQUEST, type);
   1167         if (l.networkRequest == null) return null;
   1168         sLegacyRequests.put(netCap, l);
   1169         sendExpireMsgForFeature(netCap, l.expireSequenceNumber, delay);
   1170         return l.networkRequest;
   1171     }
   1172 
   1173     private void sendExpireMsgForFeature(NetworkCapabilities netCap, int seqNum, int delay) {
   1174         if (delay >= 0) {
   1175             Log.d(TAG, "sending expire msg with seqNum " + seqNum + " and delay " + delay);
   1176             Message msg = sCallbackHandler.obtainMessage(EXPIRE_LEGACY_REQUEST, seqNum, 0, netCap);
   1177             sCallbackHandler.sendMessageDelayed(msg, delay);
   1178         }
   1179     }
   1180 
   1181     private boolean removeRequestForFeature(NetworkCapabilities netCap) {
   1182         final LegacyRequest l;
   1183         synchronized (sLegacyRequests) {
   1184             l = sLegacyRequests.remove(netCap);
   1185         }
   1186         if (l == null) return false;
   1187         unregisterNetworkCallback(l.networkCallback);
   1188         l.clearDnsBinding();
   1189         return true;
   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                 int subId = SubscriptionManager.getDefaultDataSubId();
   1298                 Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
   1299                 boolean retVal = it.getDataEnabled(subId);
   1300                 Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
   1301                         + " retVal=" + retVal);
   1302                 return retVal;
   1303             } catch (RemoteException e) { }
   1304         }
   1305         Log.d("ConnectivityManager", "getMobileDataEnabled()- remote exception retVal=false");
   1306         return false;
   1307     }
   1308 
   1309     /**
   1310      * Callback for use with {@link ConnectivityManager#addDefaultNetworkActiveListener}
   1311      * to find out when the system default network has gone in to a high power state.
   1312      */
   1313     public interface OnNetworkActiveListener {
   1314         /**
   1315          * Called on the main thread of the process to report that the current data network
   1316          * has become active, and it is now a good time to perform any pending network
   1317          * operations.  Note that this listener only tells you when the network becomes
   1318          * active; if at any other time you want to know whether it is active (and thus okay
   1319          * to initiate network traffic), you can retrieve its instantaneous state with
   1320          * {@link ConnectivityManager#isDefaultNetworkActive}.
   1321          */
   1322         public void onNetworkActive();
   1323     }
   1324 
   1325     private INetworkManagementService getNetworkManagementService() {
   1326         synchronized (this) {
   1327             if (mNMService != null) {
   1328                 return mNMService;
   1329             }
   1330             IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
   1331             mNMService = INetworkManagementService.Stub.asInterface(b);
   1332             return mNMService;
   1333         }
   1334     }
   1335 
   1336     private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
   1337             mNetworkActivityListeners
   1338                     = new ArrayMap<OnNetworkActiveListener, INetworkActivityListener>();
   1339 
   1340     /**
   1341      * Start listening to reports when the system's default data network is active, meaning it is
   1342      * a good time to perform network traffic.  Use {@link #isDefaultNetworkActive()}
   1343      * to determine the current state of the system's default network after registering the
   1344      * listener.
   1345      * <p>
   1346      * If the process default network has been set with
   1347      * {@link ConnectivityManager#setProcessDefaultNetwork} this function will not
   1348      * reflect the process's default, but the system default.
   1349      *
   1350      * @param l The listener to be told when the network is active.
   1351      */
   1352     public void addDefaultNetworkActiveListener(final OnNetworkActiveListener l) {
   1353         INetworkActivityListener rl = new INetworkActivityListener.Stub() {
   1354             @Override
   1355             public void onNetworkActive() throws RemoteException {
   1356                 l.onNetworkActive();
   1357             }
   1358         };
   1359 
   1360         try {
   1361             getNetworkManagementService().registerNetworkActivityListener(rl);
   1362             mNetworkActivityListeners.put(l, rl);
   1363         } catch (RemoteException e) {
   1364         }
   1365     }
   1366 
   1367     /**
   1368      * Remove network active listener previously registered with
   1369      * {@link #addDefaultNetworkActiveListener}.
   1370      *
   1371      * @param l Previously registered listener.
   1372      */
   1373     public void removeDefaultNetworkActiveListener(OnNetworkActiveListener l) {
   1374         INetworkActivityListener rl = mNetworkActivityListeners.get(l);
   1375         if (rl == null) {
   1376             throw new IllegalArgumentException("Listener not registered: " + l);
   1377         }
   1378         try {
   1379             getNetworkManagementService().unregisterNetworkActivityListener(rl);
   1380         } catch (RemoteException e) {
   1381         }
   1382     }
   1383 
   1384     /**
   1385      * Return whether the data network is currently active.  An active network means that
   1386      * it is currently in a high power state for performing data transmission.  On some
   1387      * types of networks, it may be expensive to move and stay in such a state, so it is
   1388      * more power efficient to batch network traffic together when the radio is already in
   1389      * this state.  This method tells you whether right now is currently a good time to
   1390      * initiate network traffic, as the network is already active.
   1391      */
   1392     public boolean isDefaultNetworkActive() {
   1393         try {
   1394             return getNetworkManagementService().isNetworkActive();
   1395         } catch (RemoteException e) {
   1396         }
   1397         return false;
   1398     }
   1399 
   1400     /**
   1401      * {@hide}
   1402      */
   1403     public ConnectivityManager(IConnectivityManager service) {
   1404         mService = checkNotNull(service, "missing IConnectivityManager");
   1405         sInstance = this;
   1406     }
   1407 
   1408     /** {@hide} */
   1409     public static ConnectivityManager from(Context context) {
   1410         return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
   1411     }
   1412 
   1413     /** {@hide */
   1414     public static final void enforceTetherChangePermission(Context context) {
   1415         if (context.getResources().getStringArray(
   1416                 com.android.internal.R.array.config_mobile_hotspot_provision_app).length == 2) {
   1417             // Have a provisioning app - must only let system apps (which check this app)
   1418             // turn on tethering
   1419             context.enforceCallingOrSelfPermission(
   1420                     android.Manifest.permission.CONNECTIVITY_INTERNAL, "ConnectivityService");
   1421         } else {
   1422             context.enforceCallingOrSelfPermission(
   1423                     android.Manifest.permission.CHANGE_NETWORK_STATE, "ConnectivityService");
   1424         }
   1425     }
   1426 
   1427     /**
   1428      * @deprecated - use getSystemService. This is a kludge to support static access in certain
   1429      *               situations where a Context pointer is unavailable.
   1430      * @hide
   1431      */
   1432     public static ConnectivityManager getInstance() {
   1433         if (sInstance == null) {
   1434             throw new IllegalStateException("No ConnectivityManager yet constructed");
   1435         }
   1436         return sInstance;
   1437     }
   1438 
   1439     /**
   1440      * Get the set of tetherable, available interfaces.  This list is limited by
   1441      * device configuration and current interface existence.
   1442      *
   1443      * @return an array of 0 or more Strings of tetherable interface names.
   1444      *
   1445      * <p>This method requires the call to hold the permission
   1446      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1447      * {@hide}
   1448      */
   1449     public String[] getTetherableIfaces() {
   1450         try {
   1451             return mService.getTetherableIfaces();
   1452         } catch (RemoteException e) {
   1453             return new String[0];
   1454         }
   1455     }
   1456 
   1457     /**
   1458      * Get the set of tethered interfaces.
   1459      *
   1460      * @return an array of 0 or more String of currently tethered interface names.
   1461      *
   1462      * <p>This method requires the call to hold the permission
   1463      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1464      * {@hide}
   1465      */
   1466     public String[] getTetheredIfaces() {
   1467         try {
   1468             return mService.getTetheredIfaces();
   1469         } catch (RemoteException e) {
   1470             return new String[0];
   1471         }
   1472     }
   1473 
   1474     /**
   1475      * Get the set of interface names which attempted to tether but
   1476      * failed.  Re-attempting to tether may cause them to reset to the Tethered
   1477      * state.  Alternatively, causing the interface to be destroyed and recreated
   1478      * may cause them to reset to the available state.
   1479      * {@link ConnectivityManager#getLastTetherError} can be used to get more
   1480      * information on the cause of the errors.
   1481      *
   1482      * @return an array of 0 or more String indicating the interface names
   1483      *        which failed to tether.
   1484      *
   1485      * <p>This method requires the call to hold the permission
   1486      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1487      * {@hide}
   1488      */
   1489     public String[] getTetheringErroredIfaces() {
   1490         try {
   1491             return mService.getTetheringErroredIfaces();
   1492         } catch (RemoteException e) {
   1493             return new String[0];
   1494         }
   1495     }
   1496 
   1497     /**
   1498      * Get the set of tethered dhcp ranges.
   1499      *
   1500      * @return an array of 0 or more {@code String} of tethered dhcp ranges.
   1501      * {@hide}
   1502      */
   1503     public String[] getTetheredDhcpRanges() {
   1504         try {
   1505             return mService.getTetheredDhcpRanges();
   1506         } catch (RemoteException e) {
   1507             return new String[0];
   1508         }
   1509     }
   1510 
   1511     /**
   1512      * Attempt to tether the named interface.  This will setup a dhcp server
   1513      * on the interface, forward and NAT IP packets and forward DNS requests
   1514      * to the best active upstream network interface.  Note that if no upstream
   1515      * IP network interface is available, dhcp will still run and traffic will be
   1516      * allowed between the tethered devices and this device, though upstream net
   1517      * access will of course fail until an upstream network interface becomes
   1518      * active.
   1519      *
   1520      * @param iface the interface name to tether.
   1521      * @return error a {@code TETHER_ERROR} value indicating success or failure type
   1522      *
   1523      * <p>This method requires the call to hold the permission
   1524      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
   1525      * {@hide}
   1526      */
   1527     public int tether(String iface) {
   1528         try {
   1529             return mService.tether(iface);
   1530         } catch (RemoteException e) {
   1531             return TETHER_ERROR_SERVICE_UNAVAIL;
   1532         }
   1533     }
   1534 
   1535     /**
   1536      * Stop tethering the named interface.
   1537      *
   1538      * @param iface the interface name to untether.
   1539      * @return error a {@code TETHER_ERROR} value indicating success or failure type
   1540      *
   1541      * <p>This method requires the call to hold the permission
   1542      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
   1543      * {@hide}
   1544      */
   1545     public int untether(String iface) {
   1546         try {
   1547             return mService.untether(iface);
   1548         } catch (RemoteException e) {
   1549             return TETHER_ERROR_SERVICE_UNAVAIL;
   1550         }
   1551     }
   1552 
   1553     /**
   1554      * Check if the device allows for tethering.  It may be disabled via
   1555      * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
   1556      * due to device configuration.
   1557      *
   1558      * @return a boolean - {@code true} indicating Tethering is supported.
   1559      *
   1560      * <p>This method requires the call to hold the permission
   1561      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1562      * {@hide}
   1563      */
   1564     public boolean isTetheringSupported() {
   1565         try {
   1566             return mService.isTetheringSupported();
   1567         } catch (RemoteException e) {
   1568             return false;
   1569         }
   1570     }
   1571 
   1572     /**
   1573      * Get the list of regular expressions that define any tetherable
   1574      * USB network interfaces.  If USB tethering is not supported by the
   1575      * device, this list should be empty.
   1576      *
   1577      * @return an array of 0 or more regular expression Strings defining
   1578      *        what interfaces are considered tetherable usb interfaces.
   1579      *
   1580      * <p>This method requires the call to hold the permission
   1581      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1582      * {@hide}
   1583      */
   1584     public String[] getTetherableUsbRegexs() {
   1585         try {
   1586             return mService.getTetherableUsbRegexs();
   1587         } catch (RemoteException e) {
   1588             return new String[0];
   1589         }
   1590     }
   1591 
   1592     /**
   1593      * Get the list of regular expressions that define any tetherable
   1594      * Wifi network interfaces.  If Wifi tethering is not supported by the
   1595      * device, this list should be empty.
   1596      *
   1597      * @return an array of 0 or more regular expression Strings defining
   1598      *        what interfaces are considered tetherable wifi interfaces.
   1599      *
   1600      * <p>This method requires the call to hold the permission
   1601      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1602      * {@hide}
   1603      */
   1604     public String[] getTetherableWifiRegexs() {
   1605         try {
   1606             return mService.getTetherableWifiRegexs();
   1607         } catch (RemoteException e) {
   1608             return new String[0];
   1609         }
   1610     }
   1611 
   1612     /**
   1613      * Get the list of regular expressions that define any tetherable
   1614      * Bluetooth network interfaces.  If Bluetooth tethering is not supported by the
   1615      * device, this list should be empty.
   1616      *
   1617      * @return an array of 0 or more regular expression Strings defining
   1618      *        what interfaces are considered tetherable bluetooth interfaces.
   1619      *
   1620      * <p>This method requires the call to hold the permission
   1621      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1622      * {@hide}
   1623      */
   1624     public String[] getTetherableBluetoothRegexs() {
   1625         try {
   1626             return mService.getTetherableBluetoothRegexs();
   1627         } catch (RemoteException e) {
   1628             return new String[0];
   1629         }
   1630     }
   1631 
   1632     /**
   1633      * Attempt to both alter the mode of USB and Tethering of USB.  A
   1634      * utility method to deal with some of the complexity of USB - will
   1635      * attempt to switch to Rndis and subsequently tether the resulting
   1636      * interface on {@code true} or turn off tethering and switch off
   1637      * Rndis on {@code false}.
   1638      *
   1639      * @param enable a boolean - {@code true} to enable tethering
   1640      * @return error a {@code TETHER_ERROR} value indicating success or failure type
   1641      *
   1642      * <p>This method requires the call to hold the permission
   1643      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
   1644      * {@hide}
   1645      */
   1646     public int setUsbTethering(boolean enable) {
   1647         try {
   1648             return mService.setUsbTethering(enable);
   1649         } catch (RemoteException e) {
   1650             return TETHER_ERROR_SERVICE_UNAVAIL;
   1651         }
   1652     }
   1653 
   1654     /** {@hide} */
   1655     public static final int TETHER_ERROR_NO_ERROR           = 0;
   1656     /** {@hide} */
   1657     public static final int TETHER_ERROR_UNKNOWN_IFACE      = 1;
   1658     /** {@hide} */
   1659     public static final int TETHER_ERROR_SERVICE_UNAVAIL    = 2;
   1660     /** {@hide} */
   1661     public static final int TETHER_ERROR_UNSUPPORTED        = 3;
   1662     /** {@hide} */
   1663     public static final int TETHER_ERROR_UNAVAIL_IFACE      = 4;
   1664     /** {@hide} */
   1665     public static final int TETHER_ERROR_MASTER_ERROR       = 5;
   1666     /** {@hide} */
   1667     public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
   1668     /** {@hide} */
   1669     public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
   1670     /** {@hide} */
   1671     public static final int TETHER_ERROR_ENABLE_NAT_ERROR     = 8;
   1672     /** {@hide} */
   1673     public static final int TETHER_ERROR_DISABLE_NAT_ERROR    = 9;
   1674     /** {@hide} */
   1675     public static final int TETHER_ERROR_IFACE_CFG_ERROR      = 10;
   1676 
   1677     /**
   1678      * Get a more detailed error code after a Tethering or Untethering
   1679      * request asynchronously failed.
   1680      *
   1681      * @param iface The name of the interface of interest
   1682      * @return error The error code of the last error tethering or untethering the named
   1683      *               interface
   1684      *
   1685      * <p>This method requires the call to hold the permission
   1686      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1687      * {@hide}
   1688      */
   1689     public int getLastTetherError(String iface) {
   1690         try {
   1691             return mService.getLastTetherError(iface);
   1692         } catch (RemoteException e) {
   1693             return TETHER_ERROR_SERVICE_UNAVAIL;
   1694         }
   1695     }
   1696 
   1697     /**
   1698      * Report network connectivity status.  This is currently used only
   1699      * to alter status bar UI.
   1700      *
   1701      * @param networkType The type of network you want to report on
   1702      * @param percentage The quality of the connection 0 is bad, 100 is good
   1703      *
   1704      * <p>This method requires the call to hold the permission
   1705      * {@link android.Manifest.permission#STATUS_BAR}.
   1706      * {@hide}
   1707      */
   1708     public void reportInetCondition(int networkType, int percentage) {
   1709         try {
   1710             mService.reportInetCondition(networkType, percentage);
   1711         } catch (RemoteException e) {
   1712         }
   1713     }
   1714 
   1715     /**
   1716      * Report a problem network to the framework.  This provides a hint to the system
   1717      * that there might be connectivity problems on this network and may cause
   1718      * the framework to re-evaluate network connectivity and/or switch to another
   1719      * network.
   1720      *
   1721      * @param network The {@link Network} the application was attempting to use
   1722      *                or {@code null} to indicate the current default network.
   1723      */
   1724     public void reportBadNetwork(Network network) {
   1725         try {
   1726             mService.reportBadNetwork(network);
   1727         } catch (RemoteException e) {
   1728         }
   1729     }
   1730 
   1731     /**
   1732      * Set a network-independent global http proxy.  This is not normally what you want
   1733      * for typical HTTP proxies - they are general network dependent.  However if you're
   1734      * doing something unusual like general internal filtering this may be useful.  On
   1735      * a private network where the proxy is not accessible, you may break HTTP using this.
   1736      *
   1737      * @param p The a {@link ProxyInfo} object defining the new global
   1738      *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
   1739      *
   1740      * <p>This method requires the call to hold the permission
   1741      * android.Manifest.permission#CONNECTIVITY_INTERNAL.
   1742      * @hide
   1743      */
   1744     public void setGlobalProxy(ProxyInfo p) {
   1745         try {
   1746             mService.setGlobalProxy(p);
   1747         } catch (RemoteException e) {
   1748         }
   1749     }
   1750 
   1751     /**
   1752      * Retrieve any network-independent global HTTP proxy.
   1753      *
   1754      * @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
   1755      *        if no global HTTP proxy is set.
   1756      *
   1757      * <p>This method requires the call to hold the permission
   1758      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1759      * @hide
   1760      */
   1761     public ProxyInfo getGlobalProxy() {
   1762         try {
   1763             return mService.getGlobalProxy();
   1764         } catch (RemoteException e) {
   1765             return null;
   1766         }
   1767     }
   1768 
   1769     /**
   1770      * Get the current default HTTP proxy settings.  If a global proxy is set it will be returned,
   1771      * otherwise if this process is bound to a {@link Network} using
   1772      * {@link #setProcessDefaultNetwork} then that {@code Network}'s proxy is returned, otherwise
   1773      * the default network's proxy is returned.
   1774      *
   1775      * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no
   1776      *        HTTP proxy is active.
   1777      * @hide
   1778      */
   1779     public ProxyInfo getDefaultProxy() {
   1780         final Network network = getProcessDefaultNetwork();
   1781         if (network != null) {
   1782             final ProxyInfo globalProxy = getGlobalProxy();
   1783             if (globalProxy != null) return globalProxy;
   1784             final LinkProperties lp = getLinkProperties(network);
   1785             if (lp != null) return lp.getHttpProxy();
   1786             return null;
   1787         }
   1788         try {
   1789             return mService.getDefaultProxy();
   1790         } catch (RemoteException e) {
   1791             return null;
   1792         }
   1793     }
   1794 
   1795     /**
   1796      * Sets a secondary requirement bit for the given networkType.
   1797      * This requirement bit is generally under the control of the carrier
   1798      * or its agents and is not directly controlled by the user.
   1799      *
   1800      * @param networkType The network who's dependence has changed
   1801      * @param met Boolean - true if network use is OK, false if not
   1802      *
   1803      * <p>This method requires the call to hold the permission
   1804      * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
   1805      * {@hide}
   1806      */
   1807     public void setDataDependency(int networkType, boolean met) {
   1808         try {
   1809             mService.setDataDependency(networkType, met);
   1810         } catch (RemoteException e) {
   1811         }
   1812     }
   1813 
   1814     /**
   1815      * Returns true if the hardware supports the given network type
   1816      * else it returns false.  This doesn't indicate we have coverage
   1817      * or are authorized onto a network, just whether or not the
   1818      * hardware supports it.  For example a GSM phone without a SIM
   1819      * should still return {@code true} for mobile data, but a wifi only
   1820      * tablet would return {@code false}.
   1821      *
   1822      * @param networkType The network type we'd like to check
   1823      * @return {@code true} if supported, else {@code false}
   1824      *
   1825      * <p>This method requires the call to hold the permission
   1826      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1827      * @hide
   1828      */
   1829     public boolean isNetworkSupported(int networkType) {
   1830         try {
   1831             return mService.isNetworkSupported(networkType);
   1832         } catch (RemoteException e) {}
   1833         return false;
   1834     }
   1835 
   1836     /**
   1837      * Returns if the currently active data network is metered. A network is
   1838      * classified as metered when the user is sensitive to heavy data usage on
   1839      * that connection due to monetary costs, data limitations or
   1840      * battery/performance issues. You should check this before doing large
   1841      * data transfers, and warn the user or delay the operation until another
   1842      * network is available.
   1843      *
   1844      * @return {@code true} if large transfers should be avoided, otherwise
   1845      *        {@code false}.
   1846      *
   1847      * <p>This method requires the call to hold the permission
   1848      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
   1849      */
   1850     public boolean isActiveNetworkMetered() {
   1851         try {
   1852             return mService.isActiveNetworkMetered();
   1853         } catch (RemoteException e) {
   1854             return false;
   1855         }
   1856     }
   1857 
   1858     /**
   1859      * If the LockdownVpn mechanism is enabled, updates the vpn
   1860      * with a reload of its profile.
   1861      *
   1862      * @return a boolean with {@code} indicating success
   1863      *
   1864      * <p>This method can only be called by the system UID
   1865      * {@hide}
   1866      */
   1867     public boolean updateLockdownVpn() {
   1868         try {
   1869             return mService.updateLockdownVpn();
   1870         } catch (RemoteException e) {
   1871             return false;
   1872         }
   1873     }
   1874 
   1875     /**
   1876      * Signal that the captive portal check on the indicated network
   1877      * is complete and whether its a captive portal or not.
   1878      *
   1879      * @param info the {@link NetworkInfo} object for the networkType
   1880      *        in question.
   1881      * @param isCaptivePortal true/false.
   1882      *
   1883      * <p>This method requires the call to hold the permission
   1884      * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
   1885      * {@hide}
   1886      */
   1887     public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
   1888         try {
   1889             mService.captivePortalCheckCompleted(info, isCaptivePortal);
   1890         } catch (RemoteException e) {
   1891         }
   1892     }
   1893 
   1894     /**
   1895      * Supply the backend messenger for a network tracker
   1896      *
   1897      * @param networkType NetworkType to set
   1898      * @param messenger {@link Messenger}
   1899      * {@hide}
   1900      */
   1901     public void supplyMessenger(int networkType, Messenger messenger) {
   1902         try {
   1903             mService.supplyMessenger(networkType, messenger);
   1904         } catch (RemoteException e) {
   1905         }
   1906     }
   1907 
   1908     /**
   1909      * Check mobile provisioning.
   1910      *
   1911      * @param suggestedTimeOutMs, timeout in milliseconds
   1912      *
   1913      * @return time out that will be used, maybe less that suggestedTimeOutMs
   1914      * -1 if an error.
   1915      *
   1916      * {@hide}
   1917      */
   1918     public int checkMobileProvisioning(int suggestedTimeOutMs) {
   1919         int timeOutMs = -1;
   1920         try {
   1921             timeOutMs = mService.checkMobileProvisioning(suggestedTimeOutMs);
   1922         } catch (RemoteException e) {
   1923         }
   1924         return timeOutMs;
   1925     }
   1926 
   1927     /**
   1928      * Get the mobile provisioning url.
   1929      * {@hide}
   1930      */
   1931     public String getMobileProvisioningUrl() {
   1932         try {
   1933             return mService.getMobileProvisioningUrl();
   1934         } catch (RemoteException e) {
   1935         }
   1936         return null;
   1937     }
   1938 
   1939     /**
   1940      * Get the mobile redirected provisioning url.
   1941      * {@hide}
   1942      */
   1943     public String getMobileRedirectedProvisioningUrl() {
   1944         try {
   1945             return mService.getMobileRedirectedProvisioningUrl();
   1946         } catch (RemoteException e) {
   1947         }
   1948         return null;
   1949     }
   1950 
   1951     /**
   1952      * Set sign in error notification to visible or in visible
   1953      *
   1954      * @param visible
   1955      * @param networkType
   1956      *
   1957      * {@hide}
   1958      */
   1959     public void setProvisioningNotificationVisible(boolean visible, int networkType,
   1960             String action) {
   1961         try {
   1962             mService.setProvisioningNotificationVisible(visible, networkType, action);
   1963         } catch (RemoteException e) {
   1964         }
   1965     }
   1966 
   1967     /**
   1968      * Set the value for enabling/disabling airplane mode
   1969      *
   1970      * @param enable whether to enable airplane mode or not
   1971      *
   1972      * <p>This method requires the call to hold the permission
   1973      * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
   1974      * @hide
   1975      */
   1976     public void setAirplaneMode(boolean enable) {
   1977         try {
   1978             mService.setAirplaneMode(enable);
   1979         } catch (RemoteException e) {
   1980         }
   1981     }
   1982 
   1983     /** {@hide} */
   1984     public void registerNetworkFactory(Messenger messenger, String name) {
   1985         try {
   1986             mService.registerNetworkFactory(messenger, name);
   1987         } catch (RemoteException e) { }
   1988     }
   1989 
   1990     /** {@hide} */
   1991     public void unregisterNetworkFactory(Messenger messenger) {
   1992         try {
   1993             mService.unregisterNetworkFactory(messenger);
   1994         } catch (RemoteException e) { }
   1995     }
   1996 
   1997     /** {@hide} */
   1998     public void registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
   1999             NetworkCapabilities nc, int score, NetworkMisc misc) {
   2000         try {
   2001             mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc);
   2002         } catch (RemoteException e) { }
   2003     }
   2004 
   2005     /**
   2006      * Base class for NetworkRequest callbacks.  Used for notifications about network
   2007      * changes.  Should be extended by applications wanting notifications.
   2008      */
   2009     public static class NetworkCallback {
   2010         /** @hide */
   2011         public static final int PRECHECK     = 1;
   2012         /** @hide */
   2013         public static final int AVAILABLE    = 2;
   2014         /** @hide */
   2015         public static final int LOSING       = 3;
   2016         /** @hide */
   2017         public static final int LOST         = 4;
   2018         /** @hide */
   2019         public static final int UNAVAIL      = 5;
   2020         /** @hide */
   2021         public static final int CAP_CHANGED  = 6;
   2022         /** @hide */
   2023         public static final int PROP_CHANGED = 7;
   2024         /** @hide */
   2025         public static final int CANCELED     = 8;
   2026 
   2027         /**
   2028          * @hide
   2029          * Called whenever the framework connects to a network that it may use to
   2030          * satisfy this request
   2031          */
   2032         public void onPreCheck(Network network) {}
   2033 
   2034         /**
   2035          * Called when the framework connects and has declared new network ready for use.
   2036          * This callback may be called more than once if the {@link Network} that is
   2037          * satisfying the request changes.
   2038          *
   2039          * @param network The {@link Network} of the satisfying network.
   2040          */
   2041         public void onAvailable(Network network) {}
   2042 
   2043         /**
   2044          * Called when the network is about to be disconnected.  Often paired with an
   2045          * {@link NetworkCallback#onAvailable} call with the new replacement network
   2046          * for graceful handover.  This may not be called if we have a hard loss
   2047          * (loss without warning).  This may be followed by either a
   2048          * {@link NetworkCallback#onLost} call or a
   2049          * {@link NetworkCallback#onAvailable} call for this network depending
   2050          * on whether we lose or regain it.
   2051          *
   2052          * @param network The {@link Network} that is about to be disconnected.
   2053          * @param maxMsToLive The time in ms the framework will attempt to keep the
   2054          *                     network connected.  Note that the network may suffer a
   2055          *                     hard loss at any time.
   2056          */
   2057         public void onLosing(Network network, int maxMsToLive) {}
   2058 
   2059         /**
   2060          * Called when the framework has a hard loss of the network or when the
   2061          * graceful failure ends.
   2062          *
   2063          * @param network The {@link Network} lost.
   2064          */
   2065         public void onLost(Network network) {}
   2066 
   2067         /**
   2068          * Called if no network is found in the given timeout time.  If no timeout is given,
   2069          * this will not be called.
   2070          * @hide
   2071          */
   2072         public void onUnavailable() {}
   2073 
   2074         /**
   2075          * Called when the network the framework connected to for this request
   2076          * changes capabilities but still satisfies the stated need.
   2077          *
   2078          * @param network The {@link Network} whose capabilities have changed.
   2079          * @param networkCapabilities The new {@link NetworkCapabilities} for this network.
   2080          */
   2081         public void onCapabilitiesChanged(Network network,
   2082                 NetworkCapabilities networkCapabilities) {}
   2083 
   2084         /**
   2085          * Called when the network the framework connected to for this request
   2086          * changes {@link LinkProperties}.
   2087          *
   2088          * @param network The {@link Network} whose link properties have changed.
   2089          * @param linkProperties The new {@link LinkProperties} for this network.
   2090          */
   2091         public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {}
   2092 
   2093         private NetworkRequest networkRequest;
   2094     }
   2095 
   2096     private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER;
   2097     /** @hide obj = pair(NetworkRequest, Network) */
   2098     public static final int CALLBACK_PRECHECK           = BASE + 1;
   2099     /** @hide obj = pair(NetworkRequest, Network) */
   2100     public static final int CALLBACK_AVAILABLE          = BASE + 2;
   2101     /** @hide obj = pair(NetworkRequest, Network), arg1 = ttl */
   2102     public static final int CALLBACK_LOSING             = BASE + 3;
   2103     /** @hide obj = pair(NetworkRequest, Network) */
   2104     public static final int CALLBACK_LOST               = BASE + 4;
   2105     /** @hide obj = NetworkRequest */
   2106     public static final int CALLBACK_UNAVAIL            = BASE + 5;
   2107     /** @hide obj = pair(NetworkRequest, Network) */
   2108     public static final int CALLBACK_CAP_CHANGED        = BASE + 6;
   2109     /** @hide obj = pair(NetworkRequest, Network) */
   2110     public static final int CALLBACK_IP_CHANGED         = BASE + 7;
   2111     /** @hide obj = NetworkRequest */
   2112     public static final int CALLBACK_RELEASED           = BASE + 8;
   2113     /** @hide */
   2114     public static final int CALLBACK_EXIT               = BASE + 9;
   2115     /** @hide obj = NetworkCapabilities, arg1 = seq number */
   2116     private static final int EXPIRE_LEGACY_REQUEST      = BASE + 10;
   2117 
   2118     private class CallbackHandler extends Handler {
   2119         private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap;
   2120         private final AtomicInteger mRefCount;
   2121         private static final String TAG = "ConnectivityManager.CallbackHandler";
   2122         private final ConnectivityManager mCm;
   2123 
   2124         CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallback>callbackMap,
   2125                 AtomicInteger refCount, ConnectivityManager cm) {
   2126             super(looper);
   2127             mCallbackMap = callbackMap;
   2128             mRefCount = refCount;
   2129             mCm = cm;
   2130         }
   2131 
   2132         @Override
   2133         public void handleMessage(Message message) {
   2134             Log.d(TAG, "CM callback handler got msg " + message.what);
   2135             switch (message.what) {
   2136                 case CALLBACK_PRECHECK: {
   2137                     NetworkRequest request = (NetworkRequest)getObject(message,
   2138                             NetworkRequest.class);
   2139                     NetworkCallback callbacks = getCallbacks(request);
   2140                     if (callbacks != null) {
   2141                         callbacks.onPreCheck((Network)getObject(message, Network.class));
   2142                     } else {
   2143                         Log.e(TAG, "callback not found for PRECHECK message");
   2144                     }
   2145                     break;
   2146                 }
   2147                 case CALLBACK_AVAILABLE: {
   2148                     NetworkRequest request = (NetworkRequest)getObject(message,
   2149                             NetworkRequest.class);
   2150                     NetworkCallback callbacks = getCallbacks(request);
   2151                     if (callbacks != null) {
   2152                         callbacks.onAvailable((Network)getObject(message, Network.class));
   2153                     } else {
   2154                         Log.e(TAG, "callback not found for AVAILABLE message");
   2155                     }
   2156                     break;
   2157                 }
   2158                 case CALLBACK_LOSING: {
   2159                     NetworkRequest request = (NetworkRequest)getObject(message,
   2160                             NetworkRequest.class);
   2161                     NetworkCallback callbacks = getCallbacks(request);
   2162                     if (callbacks != null) {
   2163                         callbacks.onLosing((Network)getObject(message, Network.class),
   2164                                 message.arg1);
   2165                     } else {
   2166                         Log.e(TAG, "callback not found for LOSING message");
   2167                     }
   2168                     break;
   2169                 }
   2170                 case CALLBACK_LOST: {
   2171                     NetworkRequest request = (NetworkRequest)getObject(message,
   2172                             NetworkRequest.class);
   2173 
   2174                     NetworkCallback callbacks = getCallbacks(request);
   2175                     if (callbacks != null) {
   2176                         callbacks.onLost((Network)getObject(message, Network.class));
   2177                     } else {
   2178                         Log.e(TAG, "callback not found for LOST message");
   2179                     }
   2180                     break;
   2181                 }
   2182                 case CALLBACK_UNAVAIL: {
   2183                     NetworkRequest request = (NetworkRequest)getObject(message,
   2184                             NetworkRequest.class);
   2185                     NetworkCallback callbacks = null;
   2186                     synchronized(mCallbackMap) {
   2187                         callbacks = mCallbackMap.get(request);
   2188                     }
   2189                     if (callbacks != null) {
   2190                         callbacks.onUnavailable();
   2191                     } else {
   2192                         Log.e(TAG, "callback not found for UNAVAIL message");
   2193                     }
   2194                     break;
   2195                 }
   2196                 case CALLBACK_CAP_CHANGED: {
   2197                     NetworkRequest request = (NetworkRequest)getObject(message,
   2198                             NetworkRequest.class);
   2199                     NetworkCallback callbacks = getCallbacks(request);
   2200                     if (callbacks != null) {
   2201                         Network network = (Network)getObject(message, Network.class);
   2202                         NetworkCapabilities cap = (NetworkCapabilities)getObject(message,
   2203                                 NetworkCapabilities.class);
   2204 
   2205                         callbacks.onCapabilitiesChanged(network, cap);
   2206                     } else {
   2207                         Log.e(TAG, "callback not found for CAP_CHANGED message");
   2208                     }
   2209                     break;
   2210                 }
   2211                 case CALLBACK_IP_CHANGED: {
   2212                     NetworkRequest request = (NetworkRequest)getObject(message,
   2213                             NetworkRequest.class);
   2214                     NetworkCallback callbacks = getCallbacks(request);
   2215                     if (callbacks != null) {
   2216                         Network network = (Network)getObject(message, Network.class);
   2217                         LinkProperties lp = (LinkProperties)getObject(message,
   2218                                 LinkProperties.class);
   2219 
   2220                         callbacks.onLinkPropertiesChanged(network, lp);
   2221                     } else {
   2222                         Log.e(TAG, "callback not found for IP_CHANGED message");
   2223                     }
   2224                     break;
   2225                 }
   2226                 case CALLBACK_RELEASED: {
   2227                     NetworkRequest req = (NetworkRequest)getObject(message, NetworkRequest.class);
   2228                     NetworkCallback callbacks = null;
   2229                     synchronized(mCallbackMap) {
   2230                         callbacks = mCallbackMap.remove(req);
   2231                     }
   2232                     if (callbacks != null) {
   2233                         synchronized(mRefCount) {
   2234                             if (mRefCount.decrementAndGet() == 0) {
   2235                                 getLooper().quit();
   2236                             }
   2237                         }
   2238                     } else {
   2239                         Log.e(TAG, "callback not found for CANCELED message");
   2240                     }
   2241                     break;
   2242                 }
   2243                 case CALLBACK_EXIT: {
   2244                     Log.d(TAG, "Listener quiting");
   2245                     getLooper().quit();
   2246                     break;
   2247                 }
   2248                 case EXPIRE_LEGACY_REQUEST: {
   2249                     expireRequest((NetworkCapabilities)message.obj, message.arg1);
   2250                     break;
   2251                 }
   2252             }
   2253         }
   2254 
   2255         private Object getObject(Message msg, Class c) {
   2256             return msg.getData().getParcelable(c.getSimpleName());
   2257         }
   2258         private NetworkCallback getCallbacks(NetworkRequest req) {
   2259             synchronized(mCallbackMap) {
   2260                 return mCallbackMap.get(req);
   2261             }
   2262         }
   2263     }
   2264 
   2265     private void incCallbackHandlerRefCount() {
   2266         synchronized(sCallbackRefCount) {
   2267             if (sCallbackRefCount.incrementAndGet() == 1) {
   2268                 // TODO - switch this over to a ManagerThread or expire it when done
   2269                 HandlerThread callbackThread = new HandlerThread("ConnectivityManager");
   2270                 callbackThread.start();
   2271                 sCallbackHandler = new CallbackHandler(callbackThread.getLooper(),
   2272                         sNetworkCallback, sCallbackRefCount, this);
   2273             }
   2274         }
   2275     }
   2276 
   2277     private void decCallbackHandlerRefCount() {
   2278         synchronized(sCallbackRefCount) {
   2279             if (sCallbackRefCount.decrementAndGet() == 0) {
   2280                 sCallbackHandler.obtainMessage(CALLBACK_EXIT).sendToTarget();
   2281                 sCallbackHandler = null;
   2282             }
   2283         }
   2284     }
   2285 
   2286     static final HashMap<NetworkRequest, NetworkCallback> sNetworkCallback =
   2287             new HashMap<NetworkRequest, NetworkCallback>();
   2288     static final AtomicInteger sCallbackRefCount = new AtomicInteger(0);
   2289     static CallbackHandler sCallbackHandler = null;
   2290 
   2291     private final static int LISTEN  = 1;
   2292     private final static int REQUEST = 2;
   2293 
   2294     private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
   2295             NetworkCallback networkCallback, int timeoutSec, int action,
   2296             int legacyType) {
   2297         if (networkCallback == null) {
   2298             throw new IllegalArgumentException("null NetworkCallback");
   2299         }
   2300         if (need == null) throw new IllegalArgumentException("null NetworkCapabilities");
   2301         try {
   2302             incCallbackHandlerRefCount();
   2303             synchronized(sNetworkCallback) {
   2304                 if (action == LISTEN) {
   2305                     networkCallback.networkRequest = mService.listenForNetwork(need,
   2306                             new Messenger(sCallbackHandler), new Binder());
   2307                 } else {
   2308                     networkCallback.networkRequest = mService.requestNetwork(need,
   2309                             new Messenger(sCallbackHandler), timeoutSec, new Binder(), legacyType);
   2310                 }
   2311                 if (networkCallback.networkRequest != null) {
   2312                     sNetworkCallback.put(networkCallback.networkRequest, networkCallback);
   2313                 }
   2314             }
   2315         } catch (RemoteException e) {}
   2316         if (networkCallback.networkRequest == null) decCallbackHandlerRefCount();
   2317         return networkCallback.networkRequest;
   2318     }
   2319 
   2320     /**
   2321      * Request a network to satisfy a set of {@link NetworkCapabilities}.
   2322      *
   2323      * This {@link NetworkRequest} will live until released via
   2324      * {@link #unregisterNetworkCallback} or the calling application exits.
   2325      * Status of the request can be followed by listening to the various
   2326      * callbacks described in {@link NetworkCallback}.  The {@link Network}
   2327      * can be used to direct traffic to the network.
   2328      *
   2329      * @param request {@link NetworkRequest} describing this request.
   2330      * @param networkCallback The {@link NetworkCallback} to be utilized for this
   2331      *                        request.  Note the callback must not be shared - they
   2332      *                        uniquely specify this request.
   2333      */
   2334     public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) {
   2335         sendRequestForNetwork(request.networkCapabilities, networkCallback, 0,
   2336                 REQUEST, inferLegacyTypeForNetworkCapabilities(request.networkCapabilities));
   2337     }
   2338 
   2339     /**
   2340      * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
   2341      * by a timeout.
   2342      *
   2343      * This function behaves identically to the non-timedout version, but if a suitable
   2344      * network is not found within the given time (in milliseconds) the
   2345      * {@link NetworkCallback#unavailable} callback is called.  The request must
   2346      * still be released normally by calling {@link releaseNetworkRequest}.
   2347      * @param request {@link NetworkRequest} describing this request.
   2348      * @param networkCallback The callbacks to be utilized for this request.  Note
   2349      *                        the callbacks must not be shared - they uniquely specify
   2350      *                        this request.
   2351      * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
   2352      *                  before {@link NetworkCallback#unavailable} is called.
   2353      * @hide
   2354      */
   2355     public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
   2356             int timeoutMs) {
   2357         sendRequestForNetwork(request.networkCapabilities, networkCallback, timeoutMs,
   2358                 REQUEST, inferLegacyTypeForNetworkCapabilities(request.networkCapabilities));
   2359     }
   2360 
   2361     /**
   2362      * The maximum number of milliseconds the framework will look for a suitable network
   2363      * during a timeout-equiped call to {@link requestNetwork}.
   2364      * {@hide}
   2365      */
   2366     public final static int MAX_NETWORK_REQUEST_TIMEOUT_MS = 100 * 60 * 1000;
   2367 
   2368     /**
   2369      * The lookup key for a {@link Network} object included with the intent after
   2370      * successfully finding a network for the applications request.  Retrieve it with
   2371      * {@link android.content.Intent#getParcelableExtra(String)}.
   2372      * <p>
   2373      * Note that if you intend to invoke (@link #setProcessDefaultNetwork(Network)) or
   2374      * {@link Network#openConnection(java.net.URL)} then you must get a
   2375      * ConnectivityManager instance before doing so.
   2376      */
   2377     public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
   2378 
   2379     /**
   2380      * The lookup key for a {@link NetworkRequest} object included with the intent after
   2381      * successfully finding a network for the applications request.  Retrieve it with
   2382      * {@link android.content.Intent#getParcelableExtra(String)}.
   2383      */
   2384     public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
   2385 
   2386 
   2387     /**
   2388      * Request a network to satisfy a set of {@link NetworkCapabilities}.
   2389      *
   2390      * This function behaves identically to the version that takes a NetworkCallback, but instead
   2391      * of {@link NetworkCallback} a {@link PendingIntent} is used.  This means
   2392      * the request may outlive the calling application and get called back when a suitable
   2393      * network is found.
   2394      * <p>
   2395      * The operation is an Intent broadcast that goes to a broadcast receiver that
   2396      * you registered with {@link Context#registerReceiver} or through the
   2397      * &lt;receiver&gt; tag in an AndroidManifest.xml file
   2398      * <p>
   2399      * The operation Intent is delivered with two extras, a {@link Network} typed
   2400      * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest}
   2401      * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing
   2402      * the original requests parameters.  It is important to create a new,
   2403      * {@link NetworkCallback} based request before completing the processing of the
   2404      * Intent to reserve the network or it will be released shortly after the Intent
   2405      * is processed.
   2406      * <p>
   2407      * If there is already an request for this Intent registered (with the equality of
   2408      * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
   2409      * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
   2410      * <p>
   2411      * The request may be released normally by calling
   2412      * {@link #releaseNetworkRequest(android.app.PendingIntent)}.
   2413      *
   2414      * @param request {@link NetworkRequest} describing this request.
   2415      * @param operation Action to perform when the network is available (corresponds
   2416      *                  to the {@link NetworkCallback#onAvailable} call.  Typically
   2417      *                  comes from {@link PendingIntent#getBroadcast}. Cannot be null.
   2418      */
   2419     public void requestNetwork(NetworkRequest request, PendingIntent operation) {
   2420         checkPendingIntent(operation);
   2421         try {
   2422             mService.pendingRequestForNetwork(request.networkCapabilities, operation);
   2423         } catch (RemoteException e) {}
   2424     }
   2425 
   2426     /**
   2427      * Removes a request made via {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)}
   2428      * <p>
   2429      * This method has the same behavior as {@link #unregisterNetworkCallback} with respect to
   2430      * releasing network resources and disconnecting.
   2431      *
   2432      * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the
   2433      *                  PendingIntent passed to
   2434      *                  {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)} with the
   2435      *                  corresponding NetworkRequest you'd like to remove. Cannot be null.
   2436      */
   2437     public void releaseNetworkRequest(PendingIntent operation) {
   2438         checkPendingIntent(operation);
   2439         try {
   2440             mService.releasePendingNetworkRequest(operation);
   2441         } catch (RemoteException e) {}
   2442     }
   2443 
   2444     private void checkPendingIntent(PendingIntent intent) {
   2445         if (intent == null) {
   2446             throw new IllegalArgumentException("PendingIntent cannot be null.");
   2447         }
   2448     }
   2449 
   2450     /**
   2451      * Registers to receive notifications about all networks which satisfy the given
   2452      * {@link NetworkRequest}.  The callbacks will continue to be called until
   2453      * either the application exits or {@link #unregisterNetworkCallback} is called
   2454      *
   2455      * @param request {@link NetworkRequest} describing this request.
   2456      * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
   2457      *                        networks change state.
   2458      */
   2459     public void registerNetworkCallback(NetworkRequest request, NetworkCallback networkCallback) {
   2460         sendRequestForNetwork(request.networkCapabilities, networkCallback, 0, LISTEN, TYPE_NONE);
   2461     }
   2462 
   2463     /**
   2464      * Unregisters callbacks about and possibly releases networks originating from
   2465      * {@link #requestNetwork} and {@link #registerNetworkCallback} calls.  If the
   2466      * given {@code NetworkCallback} had previously been used with {@code #requestNetwork},
   2467      * any networks that had been connected to only to satisfy that request will be
   2468      * disconnected.
   2469      *
   2470      * @param networkCallback The {@link NetworkCallback} used when making the request.
   2471      */
   2472     public void unregisterNetworkCallback(NetworkCallback networkCallback) {
   2473         if (networkCallback == null || networkCallback.networkRequest == null ||
   2474                 networkCallback.networkRequest.requestId == REQUEST_ID_UNSET) {
   2475             throw new IllegalArgumentException("Invalid NetworkCallback");
   2476         }
   2477         try {
   2478             mService.releaseNetworkRequest(networkCallback.networkRequest);
   2479         } catch (RemoteException e) {}
   2480     }
   2481 
   2482     /**
   2483      * Binds the current process to {@code network}.  All Sockets created in the future
   2484      * (and not explicitly bound via a bound SocketFactory from
   2485      * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
   2486      * {@code network}.  All host name resolutions will be limited to {@code network} as well.
   2487      * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
   2488      * work and all host name resolutions will fail.  This is by design so an application doesn't
   2489      * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
   2490      * To clear binding pass {@code null} for {@code network}.  Using individually bound
   2491      * Sockets created by Network.getSocketFactory().createSocket() and
   2492      * performing network-specific host name resolutions via
   2493      * {@link Network#getAllByName Network.getAllByName} is preferred to calling
   2494      * {@code setProcessDefaultNetwork}.
   2495      *
   2496      * @param network The {@link Network} to bind the current process to, or {@code null} to clear
   2497      *                the current binding.
   2498      * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
   2499      */
   2500     public static boolean setProcessDefaultNetwork(Network network) {
   2501         int netId = (network == null) ? NETID_UNSET : network.netId;
   2502         if (netId == NetworkUtils.getNetworkBoundToProcess()) {
   2503             return true;
   2504         }
   2505         if (NetworkUtils.bindProcessToNetwork(netId)) {
   2506             // Set HTTP proxy system properties to match network.
   2507             // TODO: Deprecate this static method and replace it with a non-static version.
   2508             Proxy.setHttpProxySystemProperty(getInstance().getDefaultProxy());
   2509             // Must flush DNS cache as new network may have different DNS resolutions.
   2510             InetAddress.clearDnsCache();
   2511             // Must flush socket pool as idle sockets will be bound to previous network and may
   2512             // cause subsequent fetches to be performed on old network.
   2513             NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
   2514             return true;
   2515         } else {
   2516             return false;
   2517         }
   2518     }
   2519 
   2520     /**
   2521      * Returns the {@link Network} currently bound to this process via
   2522      * {@link #setProcessDefaultNetwork}, or {@code null} if no {@link Network} is explicitly bound.
   2523      *
   2524      * @return {@code Network} to which this process is bound, or {@code null}.
   2525      */
   2526     public static Network getProcessDefaultNetwork() {
   2527         int netId = NetworkUtils.getNetworkBoundToProcess();
   2528         if (netId == NETID_UNSET) return null;
   2529         return new Network(netId);
   2530     }
   2531 
   2532     /**
   2533      * Binds host resolutions performed by this process to {@code network}.
   2534      * {@link #setProcessDefaultNetwork} takes precedence over this setting.
   2535      *
   2536      * @param network The {@link Network} to bind host resolutions from the current process to, or
   2537      *                {@code null} to clear the current binding.
   2538      * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
   2539      * @hide
   2540      * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}.
   2541      */
   2542     public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
   2543         return NetworkUtils.bindProcessToNetworkForHostResolution(
   2544                 network == null ? NETID_UNSET : network.netId);
   2545     }
   2546 }
   2547