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