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.IntDef;
     21 import android.annotation.Nullable;
     22 import android.annotation.RequiresPermission;
     23 import android.annotation.SdkConstant;
     24 import android.annotation.SdkConstant.SdkConstantType;
     25 import android.annotation.SystemApi;
     26 import android.annotation.SystemService;
     27 import android.app.PendingIntent;
     28 import android.content.Context;
     29 import android.content.Intent;
     30 import android.content.pm.PackageManager;
     31 import android.os.Binder;
     32 import android.os.Build.VERSION_CODES;
     33 import android.os.Bundle;
     34 import android.os.Handler;
     35 import android.os.HandlerThread;
     36 import android.os.IBinder;
     37 import android.os.INetworkActivityListener;
     38 import android.os.INetworkManagementService;
     39 import android.os.Looper;
     40 import android.os.Message;
     41 import android.os.Messenger;
     42 import android.os.Process;
     43 import android.os.RemoteException;
     44 import android.os.ResultReceiver;
     45 import android.os.ServiceManager;
     46 import android.provider.Settings;
     47 import android.telephony.SubscriptionManager;
     48 import android.util.ArrayMap;
     49 import android.util.Log;
     50 import android.util.SparseArray;
     51 import android.util.SparseIntArray;
     52 
     53 import com.android.internal.telephony.ITelephony;
     54 import com.android.internal.telephony.PhoneConstants;
     55 import com.android.internal.util.Protocol;
     56 import com.android.internal.util.MessageUtils;
     57 
     58 import libcore.net.event.NetworkEventDispatcher;
     59 
     60 import java.lang.annotation.Retention;
     61 import java.lang.annotation.RetentionPolicy;
     62 import java.net.InetAddress;
     63 import java.util.HashMap;
     64 import java.util.concurrent.atomic.AtomicInteger;
     65 
     66 /**
     67  * Class that answers queries about the state of network connectivity. It also
     68  * notifies applications when network connectivity changes.
     69  * <p>
     70  * The primary responsibilities of this class are to:
     71  * <ol>
     72  * <li>Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)</li>
     73  * <li>Send broadcast intents when network connectivity changes</li>
     74  * <li>Attempt to "fail over" to another network when connectivity to a network
     75  * is lost</li>
     76  * <li>Provide an API that allows applications to query the coarse-grained or fine-grained
     77  * state of the available networks</li>
     78  * <li>Provide an API that allows applications to request and select networks for their data
     79  * traffic</li>
     80  * </ol>
     81  */
     82 @SystemService(Context.CONNECTIVITY_SERVICE)
     83 public class ConnectivityManager {
     84     private static final String TAG = "ConnectivityManager";
     85 
     86     /**
     87      * A change in network connectivity has occurred. A default connection has either
     88      * been established or lost. The NetworkInfo for the affected network is
     89      * sent as an extra; it should be consulted to see what kind of
     90      * connectivity event occurred.
     91      * <p/>
     92      * Apps targeting Android 7.0 (API level 24) and higher do not receive this
     93      * broadcast if they declare the broadcast receiver in their manifest. Apps
     94      * will still receive broadcasts if they register their
     95      * {@link android.content.BroadcastReceiver} with
     96      * {@link android.content.Context#registerReceiver Context.registerReceiver()}
     97      * and that context is still valid.
     98      * <p/>
     99      * If this is a connection that was the result of failing over from a
    100      * disconnected network, then the FAILOVER_CONNECTION boolean extra is
    101      * set to true.
    102      * <p/>
    103      * For a loss of connectivity, if the connectivity manager is attempting
    104      * to connect (or has already connected) to another network, the
    105      * NetworkInfo for the new network is also passed as an extra. This lets
    106      * any receivers of the broadcast know that they should not necessarily
    107      * tell the user that no data traffic will be possible. Instead, the
    108      * receiver should expect another broadcast soon, indicating either that
    109      * the failover attempt succeeded (and so there is still overall data
    110      * connectivity), or that the failover attempt failed, meaning that all
    111      * connectivity has been lost.
    112      * <p/>
    113      * For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY
    114      * is set to {@code true} if there are no connected networks at all.
    115      */
    116     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    117     public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
    118 
    119     /**
    120      * A temporary hack until SUPL system can get off the legacy APIS.
    121      * They do too many network requests and the long list of apps listening
    122      * and waking due to the CONNECTIVITY_ACTION bcast makes it expensive.
    123      * Use this bcast intent instead for SUPL requests.
    124      * @hide
    125      */
    126     public static final String CONNECTIVITY_ACTION_SUPL =
    127             "android.net.conn.CONNECTIVITY_CHANGE_SUPL";
    128 
    129     /**
    130      * The device has connected to a network that has presented a captive
    131      * portal, which is blocking Internet connectivity. The user was presented
    132      * with a notification that network sign in is required,
    133      * and the user invoked the notification's action indicating they
    134      * desire to sign in to the network. Apps handling this activity should
    135      * facilitate signing in to the network. This action includes a
    136      * {@link Network} typed extra called {@link #EXTRA_NETWORK} that represents
    137      * the network presenting the captive portal; all communication with the
    138      * captive portal must be done using this {@code Network} object.
    139      * <p/>
    140      * This activity includes a {@link CaptivePortal} extra named
    141      * {@link #EXTRA_CAPTIVE_PORTAL} that can be used to indicate different
    142      * outcomes of the captive portal sign in to the system:
    143      * <ul>
    144      * <li> When the app handling this action believes the user has signed in to
    145      * the network and the captive portal has been dismissed, the app should
    146      * call {@link CaptivePortal#reportCaptivePortalDismissed} so the system can
    147      * reevaluate the network. If reevaluation finds the network no longer
    148      * subject to a captive portal, the network may become the default active
    149      * data network. </li>
    150      * <li> When the app handling this action believes the user explicitly wants
    151      * to ignore the captive portal and the network, the app should call
    152      * {@link CaptivePortal#ignoreNetwork}. </li>
    153      * </ul>
    154      */
    155     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    156     public static final String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL";
    157 
    158     /**
    159      * The lookup key for a {@link NetworkInfo} object. Retrieve with
    160      * {@link android.content.Intent#getParcelableExtra(String)}.
    161      *
    162      * @deprecated Since {@link NetworkInfo} can vary based on UID, applications
    163      *             should always obtain network information through
    164      *             {@link #getActiveNetworkInfo()}.
    165      * @see #EXTRA_NETWORK_TYPE
    166      */
    167     @Deprecated
    168     public static final String EXTRA_NETWORK_INFO = "networkInfo";
    169 
    170     /**
    171      * Network type which triggered a {@link #CONNECTIVITY_ACTION} broadcast.
    172      *
    173      * @see android.content.Intent#getIntExtra(String, int)
    174      */
    175     public static final String EXTRA_NETWORK_TYPE = "networkType";
    176 
    177     /**
    178      * The lookup key for a boolean that indicates whether a connect event
    179      * is for a network to which the connectivity manager was failing over
    180      * following a disconnect on another network.
    181      * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
    182      */
    183     public static final String EXTRA_IS_FAILOVER = "isFailover";
    184     /**
    185      * The lookup key for a {@link NetworkInfo} object. This is supplied when
    186      * there is another network that it may be possible to connect to. Retrieve with
    187      * {@link android.content.Intent#getParcelableExtra(String)}.
    188      */
    189     public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
    190     /**
    191      * The lookup key for a boolean that indicates whether there is a
    192      * complete lack of connectivity, i.e., no network is available.
    193      * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
    194      */
    195     public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
    196     /**
    197      * The lookup key for a string that indicates why an attempt to connect
    198      * to a network failed. The string has no particular structure. It is
    199      * intended to be used in notifications presented to users. Retrieve
    200      * it with {@link android.content.Intent#getStringExtra(String)}.
    201      */
    202     public static final String EXTRA_REASON = "reason";
    203     /**
    204      * The lookup key for a string that provides optionally supplied
    205      * extra information about the network state. The information
    206      * may be passed up from the lower networking layers, and its
    207      * meaning may be specific to a particular network type. Retrieve
    208      * it with {@link android.content.Intent#getStringExtra(String)}.
    209      */
    210     public static final String EXTRA_EXTRA_INFO = "extraInfo";
    211     /**
    212      * The lookup key for an int that provides information about
    213      * our connection to the internet at large.  0 indicates no connection,
    214      * 100 indicates a great connection.  Retrieve it with
    215      * {@link android.content.Intent#getIntExtra(String, int)}.
    216      * {@hide}
    217      */
    218     public static final String EXTRA_INET_CONDITION = "inetCondition";
    219     /**
    220      * The lookup key for a {@link CaptivePortal} object included with the
    221      * {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN} intent.  The {@code CaptivePortal}
    222      * object can be used to either indicate to the system that the captive
    223      * portal has been dismissed or that the user does not want to pursue
    224      * signing in to captive portal.  Retrieve it with
    225      * {@link android.content.Intent#getParcelableExtra(String)}.
    226      */
    227     public static final String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL";
    228 
    229     /**
    230      * Key for passing a URL to the captive portal login activity.
    231      */
    232     public static final String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL";
    233 
    234     /**
    235      * Key for passing a user agent string to the captive portal login activity.
    236      * {@hide}
    237      */
    238     public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT =
    239             "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
    240 
    241     /**
    242      * Broadcast action to indicate the change of data activity status
    243      * (idle or active) on a network in a recent period.
    244      * The network becomes active when data transmission is started, or
    245      * idle if there is no data transmission for a period of time.
    246      * {@hide}
    247      */
    248     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    249     public static final String ACTION_DATA_ACTIVITY_CHANGE = "android.net.conn.DATA_ACTIVITY_CHANGE";
    250     /**
    251      * The lookup key for an enum that indicates the network device type on which this data activity
    252      * change happens.
    253      * {@hide}
    254      */
    255     public static final String EXTRA_DEVICE_TYPE = "deviceType";
    256     /**
    257      * The lookup key for a boolean that indicates the device is active or not. {@code true} means
    258      * it is actively sending or receiving data and {@code false} means it is idle.
    259      * {@hide}
    260      */
    261     public static final String EXTRA_IS_ACTIVE = "isActive";
    262     /**
    263      * The lookup key for a long that contains the timestamp (nanos) of the radio state change.
    264      * {@hide}
    265      */
    266     public static final String EXTRA_REALTIME_NS = "tsNanos";
    267 
    268     /**
    269      * Broadcast Action: The setting for background data usage has changed
    270      * values. Use {@link #getBackgroundDataSetting()} to get the current value.
    271      * <p>
    272      * If an application uses the network in the background, it should listen
    273      * for this broadcast and stop using the background data if the value is
    274      * {@code false}.
    275      * <p>
    276      *
    277      * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability
    278      *             of background data depends on several combined factors, and
    279      *             this broadcast is no longer sent. Instead, when background
    280      *             data is unavailable, {@link #getActiveNetworkInfo()} will now
    281      *             appear disconnected. During first boot after a platform
    282      *             upgrade, this broadcast will be sent once if
    283      *             {@link #getBackgroundDataSetting()} was {@code false} before
    284      *             the upgrade.
    285      */
    286     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    287     @Deprecated
    288     public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED =
    289             "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
    290 
    291     /**
    292      * Broadcast Action: The network connection may not be good
    293      * uses {@code ConnectivityManager.EXTRA_INET_CONDITION} and
    294      * {@code ConnectivityManager.EXTRA_NETWORK_INFO} to specify
    295      * the network and it's condition.
    296      * @hide
    297      */
    298     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    299     public static final String INET_CONDITION_ACTION =
    300             "android.net.conn.INET_CONDITION_ACTION";
    301 
    302     /**
    303      * Broadcast Action: A tetherable connection has come or gone.
    304      * Uses {@code ConnectivityManager.EXTRA_AVAILABLE_TETHER},
    305      * {@code ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY},
    306      * {@code ConnectivityManager.EXTRA_ACTIVE_TETHER}, and
    307      * {@code ConnectivityManager.EXTRA_ERRORED_TETHER} to indicate
    308      * the current state of tethering.  Each include a list of
    309      * interface names in that state (may be empty).
    310      * @hide
    311      */
    312     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    313     public static final String ACTION_TETHER_STATE_CHANGED =
    314             "android.net.conn.TETHER_STATE_CHANGED";
    315 
    316     /**
    317      * @hide
    318      * gives a String[] listing all the interfaces configured for
    319      * tethering and currently available for tethering.
    320      */
    321     public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
    322 
    323     /**
    324      * @hide
    325      * gives a String[] listing all the interfaces currently in local-only
    326      * mode (ie, has DHCPv4+IPv6-ULA support and no packet forwarding)
    327      */
    328     public static final String EXTRA_ACTIVE_LOCAL_ONLY = "localOnlyArray";
    329 
    330     /**
    331      * @hide
    332      * gives a String[] listing all the interfaces currently tethered
    333      * (ie, has DHCPv4 support and packets potentially forwarded/NATed)
    334      */
    335     public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
    336 
    337     /**
    338      * @hide
    339      * gives a String[] listing all the interfaces we tried to tether and
    340      * failed.  Use {@link #getLastTetherError} to find the error code
    341      * for any interfaces listed here.
    342      */
    343     public static final String EXTRA_ERRORED_TETHER = "erroredArray";
    344 
    345     /**
    346      * Broadcast Action: The captive portal tracker has finished its test.
    347      * Sent only while running Setup Wizard, in lieu of showing a user
    348      * notification.
    349      * @hide
    350      */
    351     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    352     public static final String ACTION_CAPTIVE_PORTAL_TEST_COMPLETED =
    353             "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED";
    354     /**
    355      * The lookup key for a boolean that indicates whether a captive portal was detected.
    356      * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
    357      * @hide
    358      */
    359     public static final String EXTRA_IS_CAPTIVE_PORTAL = "captivePortal";
    360 
    361     /**
    362      * Action used to display a dialog that asks the user whether to connect to a network that is
    363      * not validated. This intent is used to start the dialog in settings via startActivity.
    364      *
    365      * @hide
    366      */
    367     public static final String ACTION_PROMPT_UNVALIDATED = "android.net.conn.PROMPT_UNVALIDATED";
    368 
    369     /**
    370      * Action used to display a dialog that asks the user whether to avoid a network that is no
    371      * longer validated. This intent is used to start the dialog in settings via startActivity.
    372      *
    373      * @hide
    374      */
    375     public static final String ACTION_PROMPT_LOST_VALIDATION =
    376             "android.net.conn.PROMPT_LOST_VALIDATION";
    377 
    378     /**
    379      * Invalid tethering type.
    380      * @see #startTethering(int, OnStartTetheringCallback, boolean)
    381      * @hide
    382      */
    383     public static final int TETHERING_INVALID   = -1;
    384 
    385     /**
    386      * Wifi tethering type.
    387      * @see #startTethering(int, OnStartTetheringCallback, boolean)
    388      * @hide
    389      */
    390     @SystemApi
    391     public static final int TETHERING_WIFI      = 0;
    392 
    393     /**
    394      * USB tethering type.
    395      * @see #startTethering(int, OnStartTetheringCallback, boolean)
    396      * @hide
    397      */
    398     @SystemApi
    399     public static final int TETHERING_USB       = 1;
    400 
    401     /**
    402      * Bluetooth tethering type.
    403      * @see #startTethering(int, OnStartTetheringCallback, boolean)
    404      * @hide
    405      */
    406     @SystemApi
    407     public static final int TETHERING_BLUETOOTH = 2;
    408 
    409     /**
    410      * Extra used for communicating with the TetherService. Includes the type of tethering to
    411      * enable if any.
    412      * @hide
    413      */
    414     public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
    415 
    416     /**
    417      * Extra used for communicating with the TetherService. Includes the type of tethering for
    418      * which to cancel provisioning.
    419      * @hide
    420      */
    421     public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType";
    422 
    423     /**
    424      * Extra used for communicating with the TetherService. True to schedule a recheck of tether
    425      * provisioning.
    426      * @hide
    427      */
    428     public static final String EXTRA_SET_ALARM = "extraSetAlarm";
    429 
    430     /**
    431      * Tells the TetherService to run a provision check now.
    432      * @hide
    433      */
    434     public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
    435 
    436     /**
    437      * Extra used for communicating with the TetherService. Contains the {@link ResultReceiver}
    438      * which will receive provisioning results. Can be left empty.
    439      * @hide
    440      */
    441     public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";
    442 
    443     /**
    444      * The absence of a connection type.
    445      * @hide
    446      */
    447     public static final int TYPE_NONE        = -1;
    448 
    449     /**
    450      * The Mobile data connection.  When active, all data traffic
    451      * will use this network type's interface by default
    452      * (it has a default route)
    453      */
    454     public static final int TYPE_MOBILE      = 0;
    455     /**
    456      * The WIFI data connection.  When active, all data traffic
    457      * will use this network type's interface by default
    458      * (it has a default route).
    459      */
    460     public static final int TYPE_WIFI        = 1;
    461     /**
    462      * An MMS-specific Mobile data connection.  This network type may use the
    463      * same network interface as {@link #TYPE_MOBILE} or it may use a different
    464      * one.  This is used by applications needing to talk to the carrier's
    465      * Multimedia Messaging Service servers.
    466      *
    467      * @deprecated Applications should instead use
    468      *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that
    469      *         provides the {@link NetworkCapabilities#NET_CAPABILITY_MMS} capability.
    470      */
    471     @Deprecated
    472     public static final int TYPE_MOBILE_MMS  = 2;
    473     /**
    474      * A SUPL-specific Mobile data connection.  This network type may use the
    475      * same network interface as {@link #TYPE_MOBILE} or it may use a different
    476      * one.  This is used by applications needing to talk to the carrier's
    477      * Secure User Plane Location servers for help locating the device.
    478      *
    479      * @deprecated Applications should instead use
    480      *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that
    481      *         provides the {@link NetworkCapabilities#NET_CAPABILITY_SUPL} capability.
    482      */
    483     @Deprecated
    484     public static final int TYPE_MOBILE_SUPL = 3;
    485     /**
    486      * A DUN-specific Mobile data connection.  This network type may use the
    487      * same network interface as {@link #TYPE_MOBILE} or it may use a different
    488      * one.  This is sometimes by the system when setting up an upstream connection
    489      * for tethering so that the carrier is aware of DUN traffic.
    490      */
    491     public static final int TYPE_MOBILE_DUN  = 4;
    492     /**
    493      * A High Priority Mobile data connection.  This network type uses the
    494      * same network interface as {@link #TYPE_MOBILE} but the routing setup
    495      * is different.
    496      *
    497      * @deprecated Applications should instead use
    498      *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that
    499      *         uses the {@link NetworkCapabilities#TRANSPORT_CELLULAR} transport.
    500      */
    501     @Deprecated
    502     public static final int TYPE_MOBILE_HIPRI = 5;
    503     /**
    504      * The WiMAX data connection.  When active, all data traffic
    505      * will use this network type's interface by default
    506      * (it has a default route).
    507      */
    508     public static final int TYPE_WIMAX       = 6;
    509 
    510     /**
    511      * The Bluetooth data connection.  When active, all data traffic
    512      * will use this network type's interface by default
    513      * (it has a default route).
    514      */
    515     public static final int TYPE_BLUETOOTH   = 7;
    516 
    517     /**
    518      * Dummy data connection.  This should not be used on shipping devices.
    519      */
    520     public static final int TYPE_DUMMY       = 8;
    521 
    522     /**
    523      * The Ethernet data connection.  When active, all data traffic
    524      * will use this network type's interface by default
    525      * (it has a default route).
    526      */
    527     public static final int TYPE_ETHERNET    = 9;
    528 
    529     /**
    530      * Over the air Administration.
    531      * {@hide}
    532      */
    533     public static final int TYPE_MOBILE_FOTA = 10;
    534 
    535     /**
    536      * IP Multimedia Subsystem.
    537      * {@hide}
    538      */
    539     public static final int TYPE_MOBILE_IMS  = 11;
    540 
    541     /**
    542      * Carrier Branded Services.
    543      * {@hide}
    544      */
    545     public static final int TYPE_MOBILE_CBS  = 12;
    546 
    547     /**
    548      * A Wi-Fi p2p connection. Only requesting processes will have access to
    549      * the peers connected.
    550      * {@hide}
    551      */
    552     public static final int TYPE_WIFI_P2P    = 13;
    553 
    554     /**
    555      * The network to use for initially attaching to the network
    556      * {@hide}
    557      */
    558     public static final int TYPE_MOBILE_IA = 14;
    559 
    560     /**
    561      * Emergency PDN connection for emergency services.  This
    562      * may include IMS and MMS in emergency situations.
    563      * {@hide}
    564      */
    565     public static final int TYPE_MOBILE_EMERGENCY = 15;
    566 
    567     /**
    568      * The network that uses proxy to achieve connectivity.
    569      * {@hide}
    570      */
    571     public static final int TYPE_PROXY = 16;
    572 
    573     /**
    574      * A virtual network using one or more native bearers.
    575      * It may or may not be providing security services.
    576      */
    577     public static final int TYPE_VPN = 17;
    578 
    579     /** {@hide} */
    580     public static final int MAX_RADIO_TYPE   = TYPE_VPN;
    581 
    582     /** {@hide} */
    583     public static final int MAX_NETWORK_TYPE = TYPE_VPN;
    584 
    585     /**
    586      * If you want to set the default network preference,you can directly
    587      * change the networkAttributes array in framework's config.xml.
    588      *
    589      * @deprecated Since we support so many more networks now, the single
    590      *             network default network preference can't really express
    591      *             the hierarchy.  Instead, the default is defined by the
    592      *             networkAttributes in config.xml.  You can determine
    593      *             the current value by calling {@link #getNetworkPreference()}
    594      *             from an App.
    595      */
    596     @Deprecated
    597     public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
    598 
    599     /**
    600      * @hide
    601      */
    602     public final static int REQUEST_ID_UNSET = 0;
    603 
    604     /**
    605      * A NetID indicating no Network is selected.
    606      * Keep in sync with bionic/libc/dns/include/resolv_netid.h
    607      * @hide
    608      */
    609     public static final int NETID_UNSET = 0;
    610 
    611     private final IConnectivityManager mService;
    612     /**
    613      * A kludge to facilitate static access where a Context pointer isn't available, like in the
    614      * case of the static set/getProcessDefaultNetwork methods and from the Network class.
    615      * TODO: Remove this after deprecating the static methods in favor of non-static methods or
    616      * methods that take a Context argument.
    617      */
    618     private static ConnectivityManager sInstance;
    619 
    620     private final Context mContext;
    621 
    622     private INetworkManagementService mNMService;
    623     private INetworkPolicyManager mNPManager;
    624 
    625     /**
    626      * Tests if a given integer represents a valid network type.
    627      * @param networkType the type to be tested
    628      * @return a boolean.  {@code true} if the type is valid, else {@code false}
    629      * @deprecated All APIs accepting a network type are deprecated. There should be no need to
    630      *             validate a network type.
    631      */
    632     @Deprecated
    633     public static boolean isNetworkTypeValid(int networkType) {
    634         return networkType >= 0 && networkType <= MAX_NETWORK_TYPE;
    635     }
    636 
    637     /**
    638      * Returns a non-localized string representing a given network type.
    639      * ONLY used for debugging output.
    640      * @param type the type needing naming
    641      * @return a String for the given type, or a string version of the type ("87")
    642      * if no name is known.
    643      * {@hide}
    644      */
    645     public static String getNetworkTypeName(int type) {
    646         switch (type) {
    647             case TYPE_MOBILE:
    648                 return "MOBILE";
    649             case TYPE_WIFI:
    650                 return "WIFI";
    651             case TYPE_MOBILE_MMS:
    652                 return "MOBILE_MMS";
    653             case TYPE_MOBILE_SUPL:
    654                 return "MOBILE_SUPL";
    655             case TYPE_MOBILE_DUN:
    656                 return "MOBILE_DUN";
    657             case TYPE_MOBILE_HIPRI:
    658                 return "MOBILE_HIPRI";
    659             case TYPE_WIMAX:
    660                 return "WIMAX";
    661             case TYPE_BLUETOOTH:
    662                 return "BLUETOOTH";
    663             case TYPE_DUMMY:
    664                 return "DUMMY";
    665             case TYPE_ETHERNET:
    666                 return "ETHERNET";
    667             case TYPE_MOBILE_FOTA:
    668                 return "MOBILE_FOTA";
    669             case TYPE_MOBILE_IMS:
    670                 return "MOBILE_IMS";
    671             case TYPE_MOBILE_CBS:
    672                 return "MOBILE_CBS";
    673             case TYPE_WIFI_P2P:
    674                 return "WIFI_P2P";
    675             case TYPE_MOBILE_IA:
    676                 return "MOBILE_IA";
    677             case TYPE_MOBILE_EMERGENCY:
    678                 return "MOBILE_EMERGENCY";
    679             case TYPE_PROXY:
    680                 return "PROXY";
    681             case TYPE_VPN:
    682                 return "VPN";
    683             default:
    684                 return Integer.toString(type);
    685         }
    686     }
    687 
    688     /**
    689      * Checks if a given type uses the cellular data connection.
    690      * This should be replaced in the future by a network property.
    691      * @param networkType the type to check
    692      * @return a boolean - {@code true} if uses cellular network, else {@code false}
    693      * {@hide}
    694      */
    695     public static boolean isNetworkTypeMobile(int networkType) {
    696         switch (networkType) {
    697             case TYPE_MOBILE:
    698             case TYPE_MOBILE_MMS:
    699             case TYPE_MOBILE_SUPL:
    700             case TYPE_MOBILE_DUN:
    701             case TYPE_MOBILE_HIPRI:
    702             case TYPE_MOBILE_FOTA:
    703             case TYPE_MOBILE_IMS:
    704             case TYPE_MOBILE_CBS:
    705             case TYPE_MOBILE_IA:
    706             case TYPE_MOBILE_EMERGENCY:
    707                 return true;
    708             default:
    709                 return false;
    710         }
    711     }
    712 
    713     /**
    714      * Checks if the given network type is backed by a Wi-Fi radio.
    715      *
    716      * @hide
    717      */
    718     public static boolean isNetworkTypeWifi(int networkType) {
    719         switch (networkType) {
    720             case TYPE_WIFI:
    721             case TYPE_WIFI_P2P:
    722                 return true;
    723             default:
    724                 return false;
    725         }
    726     }
    727 
    728     /**
    729      * Specifies the preferred network type.  When the device has more
    730      * than one type available the preferred network type will be used.
    731      *
    732      * @param preference the network type to prefer over all others.  It is
    733      *         unspecified what happens to the old preferred network in the
    734      *         overall ordering.
    735      * @deprecated Functionality has been removed as it no longer makes sense,
    736      *             with many more than two networks - we'd need an array to express
    737      *             preference.  Instead we use dynamic network properties of
    738      *             the networks to describe their precedence.
    739      */
    740     @Deprecated
    741     public void setNetworkPreference(int preference) {
    742     }
    743 
    744     /**
    745      * Retrieves the current preferred network type.
    746      *
    747      * @return an integer representing the preferred network type
    748      *
    749      * @deprecated Functionality has been removed as it no longer makes sense,
    750      *             with many more than two networks - we'd need an array to express
    751      *             preference.  Instead we use dynamic network properties of
    752      *             the networks to describe their precedence.
    753      */
    754     @Deprecated
    755     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
    756     public int getNetworkPreference() {
    757         return TYPE_NONE;
    758     }
    759 
    760     /**
    761      * Returns details about the currently active default data network. When
    762      * connected, this network is the default route for outgoing connections.
    763      * You should always check {@link NetworkInfo#isConnected()} before initiating
    764      * network traffic. This may return {@code null} when there is no default
    765      * network.
    766      *
    767      * @return a {@link NetworkInfo} object for the current default network
    768      *        or {@code null} if no default network is currently active
    769      */
    770     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
    771     public NetworkInfo getActiveNetworkInfo() {
    772         try {
    773             return mService.getActiveNetworkInfo();
    774         } catch (RemoteException e) {
    775             throw e.rethrowFromSystemServer();
    776         }
    777     }
    778 
    779     /**
    780      * Returns a {@link Network} object corresponding to the currently active
    781      * default data network.  In the event that the current active default data
    782      * network disconnects, the returned {@code Network} object will no longer
    783      * be usable.  This will return {@code null} when there is no default
    784      * network.
    785      *
    786      * @return a {@link Network} object for the current default network or
    787      *        {@code null} if no default network is currently active
    788      */
    789     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
    790     public Network getActiveNetwork() {
    791         try {
    792             return mService.getActiveNetwork();
    793         } catch (RemoteException e) {
    794             throw e.rethrowFromSystemServer();
    795         }
    796     }
    797 
    798     /**
    799      * Returns a {@link Network} object corresponding to the currently active
    800      * default data network for a specific UID.  In the event that the default data
    801      * network disconnects, the returned {@code Network} object will no longer
    802      * be usable.  This will return {@code null} when there is no default
    803      * network for the UID.
    804      *
    805      * @return a {@link Network} object for the current default network for the
    806      *         given UID or {@code null} if no default network is currently active
    807      *
    808      * @hide
    809      */
    810     @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
    811     public Network getActiveNetworkForUid(int uid) {
    812         return getActiveNetworkForUid(uid, false);
    813     }
    814 
    815     /** {@hide} */
    816     public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
    817         try {
    818             return mService.getActiveNetworkForUid(uid, ignoreBlocked);
    819         } catch (RemoteException e) {
    820             throw e.rethrowFromSystemServer();
    821         }
    822     }
    823 
    824     /**
    825      * Configures an always-on VPN connection through a specific application.
    826      * This connection is automatically granted and persisted after a reboot.
    827      *
    828      * <p>The designated package should declare a {@link VpnService} in its
    829      *    manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE},
    830      *    otherwise the call will fail.
    831      *
    832      * @param userId The identifier of the user to set an always-on VPN for.
    833      * @param vpnPackage The package name for an installed VPN app on the device, or {@code null}
    834      *                   to remove an existing always-on VPN configuration.
    835      * @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or
    836      *        {@code false} otherwise.
    837      * @return {@code true} if the package is set as always-on VPN controller;
    838      *         {@code false} otherwise.
    839      * @hide
    840      */
    841     public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
    842             boolean lockdownEnabled) {
    843         try {
    844             return mService.setAlwaysOnVpnPackage(userId, vpnPackage, lockdownEnabled);
    845         } catch (RemoteException e) {
    846             throw e.rethrowFromSystemServer();
    847         }
    848     }
    849 
    850     /**
    851      * Returns the package name of the currently set always-on VPN application.
    852      * If there is no always-on VPN set, or the VPN is provided by the system instead
    853      * of by an app, {@code null} will be returned.
    854      *
    855      * @return Package name of VPN controller responsible for always-on VPN,
    856      *         or {@code null} if none is set.
    857      * @hide
    858      */
    859     public String getAlwaysOnVpnPackageForUser(int userId) {
    860         try {
    861             return mService.getAlwaysOnVpnPackage(userId);
    862         } catch (RemoteException e) {
    863             throw e.rethrowFromSystemServer();
    864         }
    865     }
    866 
    867     /**
    868      * Returns details about the currently active default data network
    869      * for a given uid.  This is for internal use only to avoid spying
    870      * other apps.
    871      *
    872      * @return a {@link NetworkInfo} object for the current default network
    873      *        for the given uid or {@code null} if no default network is
    874      *        available for the specified uid.
    875      *
    876      * {@hide}
    877      */
    878     @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
    879     public NetworkInfo getActiveNetworkInfoForUid(int uid) {
    880         return getActiveNetworkInfoForUid(uid, false);
    881     }
    882 
    883     /** {@hide} */
    884     public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
    885         try {
    886             return mService.getActiveNetworkInfoForUid(uid, ignoreBlocked);
    887         } catch (RemoteException e) {
    888             throw e.rethrowFromSystemServer();
    889         }
    890     }
    891 
    892     /**
    893      * Returns connection status information about a particular
    894      * network type.
    895      *
    896      * @param networkType integer specifying which networkType in
    897      *        which you're interested.
    898      * @return a {@link NetworkInfo} object for the requested
    899      *        network type or {@code null} if the type is not
    900      *        supported by the device.
    901      *
    902      * @deprecated This method does not support multiple connected networks
    903      *             of the same type. Use {@link #getAllNetworks} and
    904      *             {@link #getNetworkInfo(android.net.Network)} instead.
    905      */
    906     @Deprecated
    907     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
    908     public NetworkInfo getNetworkInfo(int networkType) {
    909         try {
    910             return mService.getNetworkInfo(networkType);
    911         } catch (RemoteException e) {
    912             throw e.rethrowFromSystemServer();
    913         }
    914     }
    915 
    916     /**
    917      * Returns connection status information about a particular
    918      * Network.
    919      *
    920      * @param network {@link Network} specifying which network
    921      *        in which you're interested.
    922      * @return a {@link NetworkInfo} object for the requested
    923      *        network or {@code null} if the {@code Network}
    924      *        is not valid.
    925      */
    926     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
    927     public NetworkInfo getNetworkInfo(Network network) {
    928         return getNetworkInfoForUid(network, Process.myUid(), false);
    929     }
    930 
    931     /** {@hide} */
    932     public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
    933         try {
    934             return mService.getNetworkInfoForUid(network, uid, ignoreBlocked);
    935         } catch (RemoteException e) {
    936             throw e.rethrowFromSystemServer();
    937         }
    938     }
    939 
    940     /**
    941      * Returns connection status information about all network
    942      * types supported by the device.
    943      *
    944      * @return an array of {@link NetworkInfo} objects.  Check each
    945      * {@link NetworkInfo#getType} for which type each applies.
    946      *
    947      * @deprecated This method does not support multiple connected networks
    948      *             of the same type. Use {@link #getAllNetworks} and
    949      *             {@link #getNetworkInfo(android.net.Network)} instead.
    950      */
    951     @Deprecated
    952     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
    953     public NetworkInfo[] getAllNetworkInfo() {
    954         try {
    955             return mService.getAllNetworkInfo();
    956         } catch (RemoteException e) {
    957             throw e.rethrowFromSystemServer();
    958         }
    959     }
    960 
    961     /**
    962      * Returns the {@link Network} object currently serving a given type, or
    963      * null if the given type is not connected.
    964      *
    965      * @hide
    966      * @deprecated This method does not support multiple connected networks
    967      *             of the same type. Use {@link #getAllNetworks} and
    968      *             {@link #getNetworkInfo(android.net.Network)} instead.
    969      */
    970     @Deprecated
    971     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
    972     public Network getNetworkForType(int networkType) {
    973         try {
    974             return mService.getNetworkForType(networkType);
    975         } catch (RemoteException e) {
    976             throw e.rethrowFromSystemServer();
    977         }
    978     }
    979 
    980     /**
    981      * Returns an array of all {@link Network} currently tracked by the
    982      * framework.
    983      *
    984      * @return an array of {@link Network} objects.
    985      */
    986     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
    987     public Network[] getAllNetworks() {
    988         try {
    989             return mService.getAllNetworks();
    990         } catch (RemoteException e) {
    991             throw e.rethrowFromSystemServer();
    992         }
    993     }
    994 
    995     /**
    996      * Returns an array of {@link android.net.NetworkCapabilities} objects, representing
    997      * the Networks that applications run by the given user will use by default.
    998      * @hide
    999      */
   1000     public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
   1001         try {
   1002             return mService.getDefaultNetworkCapabilitiesForUser(userId);
   1003         } catch (RemoteException e) {
   1004             throw e.rethrowFromSystemServer();
   1005         }
   1006     }
   1007 
   1008     /**
   1009      * Returns the IP information for the current default network.
   1010      *
   1011      * @return a {@link LinkProperties} object describing the IP info
   1012      *        for the current default network, or {@code null} if there
   1013      *        is no current default network.
   1014      *
   1015      * {@hide}
   1016      */
   1017     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   1018     public LinkProperties getActiveLinkProperties() {
   1019         try {
   1020             return mService.getActiveLinkProperties();
   1021         } catch (RemoteException e) {
   1022             throw e.rethrowFromSystemServer();
   1023         }
   1024     }
   1025 
   1026     /**
   1027      * Returns the IP information for a given network type.
   1028      *
   1029      * @param networkType the network type of interest.
   1030      * @return a {@link LinkProperties} object describing the IP info
   1031      *        for the given networkType, or {@code null} if there is
   1032      *        no current default network.
   1033      *
   1034      * {@hide}
   1035      * @deprecated This method does not support multiple connected networks
   1036      *             of the same type. Use {@link #getAllNetworks},
   1037      *             {@link #getNetworkInfo(android.net.Network)}, and
   1038      *             {@link #getLinkProperties(android.net.Network)} instead.
   1039      */
   1040     @Deprecated
   1041     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   1042     public LinkProperties getLinkProperties(int networkType) {
   1043         try {
   1044             return mService.getLinkPropertiesForType(networkType);
   1045         } catch (RemoteException e) {
   1046             throw e.rethrowFromSystemServer();
   1047         }
   1048     }
   1049 
   1050     /**
   1051      * Get the {@link LinkProperties} for the given {@link Network}.  This
   1052      * will return {@code null} if the network is unknown.
   1053      *
   1054      * @param network The {@link Network} object identifying the network in question.
   1055      * @return The {@link LinkProperties} for the network, or {@code null}.
   1056      */
   1057     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   1058     public LinkProperties getLinkProperties(Network network) {
   1059         try {
   1060             return mService.getLinkProperties(network);
   1061         } catch (RemoteException e) {
   1062             throw e.rethrowFromSystemServer();
   1063         }
   1064     }
   1065 
   1066     /**
   1067      * Get the {@link android.net.NetworkCapabilities} for the given {@link Network}.  This
   1068      * will return {@code null} if the network is unknown.
   1069      *
   1070      * @param network The {@link Network} object identifying the network in question.
   1071      * @return The {@link android.net.NetworkCapabilities} for the network, or {@code null}.
   1072      */
   1073     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   1074     public NetworkCapabilities getNetworkCapabilities(Network network) {
   1075         try {
   1076             return mService.getNetworkCapabilities(network);
   1077         } catch (RemoteException e) {
   1078             throw e.rethrowFromSystemServer();
   1079         }
   1080     }
   1081 
   1082     /**
   1083      * Gets the URL that should be used for resolving whether a captive portal is present.
   1084      * 1. This URL should respond with a 204 response to a GET request to indicate no captive
   1085      *    portal is present.
   1086      * 2. This URL must be HTTP as redirect responses are used to find captive portal
   1087      *    sign-in pages. Captive portals cannot respond to HTTPS requests with redirects.
   1088      *
   1089      * @hide
   1090      */
   1091     @SystemApi
   1092     public String getCaptivePortalServerUrl() {
   1093         try {
   1094             return mService.getCaptivePortalServerUrl();
   1095         } catch (RemoteException e) {
   1096             throw e.rethrowFromSystemServer();
   1097         }
   1098     }
   1099 
   1100     /**
   1101      * Tells the underlying networking system that the caller wants to
   1102      * begin using the named feature. The interpretation of {@code feature}
   1103      * is completely up to each networking implementation.
   1104      *
   1105      * <p>This method requires the caller to hold either the
   1106      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
   1107      * or the ability to modify system settings as determined by
   1108      * {@link android.provider.Settings.System#canWrite}.</p>
   1109      *
   1110      * @param networkType specifies which network the request pertains to
   1111      * @param feature the name of the feature to be used
   1112      * @return an integer value representing the outcome of the request.
   1113      * The interpretation of this value is specific to each networking
   1114      * implementation+feature combination, except that the value {@code -1}
   1115      * always indicates failure.
   1116      *
   1117      * @deprecated Deprecated in favor of the cleaner
   1118      *             {@link #requestNetwork(NetworkRequest, NetworkCallback)} API.
   1119      *             In {@link VERSION_CODES#M}, and above, this method is unsupported and will
   1120      *             throw {@code UnsupportedOperationException} if called.
   1121      * @removed
   1122      */
   1123     @Deprecated
   1124     public int startUsingNetworkFeature(int networkType, String feature) {
   1125         checkLegacyRoutingApiAccess();
   1126         NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
   1127         if (netCap == null) {
   1128             Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " +
   1129                     feature);
   1130             return PhoneConstants.APN_REQUEST_FAILED;
   1131         }
   1132 
   1133         NetworkRequest request = null;
   1134         synchronized (sLegacyRequests) {
   1135             LegacyRequest l = sLegacyRequests.get(netCap);
   1136             if (l != null) {
   1137                 Log.d(TAG, "renewing startUsingNetworkFeature request " + l.networkRequest);
   1138                 renewRequestLocked(l);
   1139                 if (l.currentNetwork != null) {
   1140                     return PhoneConstants.APN_ALREADY_ACTIVE;
   1141                 } else {
   1142                     return PhoneConstants.APN_REQUEST_STARTED;
   1143                 }
   1144             }
   1145 
   1146             request = requestNetworkForFeatureLocked(netCap);
   1147         }
   1148         if (request != null) {
   1149             Log.d(TAG, "starting startUsingNetworkFeature for request " + request);
   1150             return PhoneConstants.APN_REQUEST_STARTED;
   1151         } else {
   1152             Log.d(TAG, " request Failed");
   1153             return PhoneConstants.APN_REQUEST_FAILED;
   1154         }
   1155     }
   1156 
   1157     /**
   1158      * Tells the underlying networking system that the caller is finished
   1159      * using the named feature. The interpretation of {@code feature}
   1160      * is completely up to each networking implementation.
   1161      *
   1162      * <p>This method requires the caller to hold either the
   1163      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
   1164      * or the ability to modify system settings as determined by
   1165      * {@link android.provider.Settings.System#canWrite}.</p>
   1166      *
   1167      * @param networkType specifies which network the request pertains to
   1168      * @param feature the name of the feature that is no longer needed
   1169      * @return an integer value representing the outcome of the request.
   1170      * The interpretation of this value is specific to each networking
   1171      * implementation+feature combination, except that the value {@code -1}
   1172      * always indicates failure.
   1173      *
   1174      * @deprecated Deprecated in favor of the cleaner
   1175      *             {@link #unregisterNetworkCallback(NetworkCallback)} API.
   1176      *             In {@link VERSION_CODES#M}, and above, this method is unsupported and will
   1177      *             throw {@code UnsupportedOperationException} if called.
   1178      * @removed
   1179      */
   1180     @Deprecated
   1181     public int stopUsingNetworkFeature(int networkType, String feature) {
   1182         checkLegacyRoutingApiAccess();
   1183         NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
   1184         if (netCap == null) {
   1185             Log.d(TAG, "Can't satisfy stopUsingNetworkFeature for " + networkType + ", " +
   1186                     feature);
   1187             return -1;
   1188         }
   1189 
   1190         if (removeRequestForFeature(netCap)) {
   1191             Log.d(TAG, "stopUsingNetworkFeature for " + networkType + ", " + feature);
   1192         }
   1193         return 1;
   1194     }
   1195 
   1196     private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
   1197         if (networkType == TYPE_MOBILE) {
   1198             switch (feature) {
   1199                 case "enableCBS":
   1200                     return networkCapabilitiesForType(TYPE_MOBILE_CBS);
   1201                 case "enableDUN":
   1202                 case "enableDUNAlways":
   1203                     return networkCapabilitiesForType(TYPE_MOBILE_DUN);
   1204                 case "enableFOTA":
   1205                     return networkCapabilitiesForType(TYPE_MOBILE_FOTA);
   1206                 case "enableHIPRI":
   1207                     return networkCapabilitiesForType(TYPE_MOBILE_HIPRI);
   1208                 case "enableIMS":
   1209                     return networkCapabilitiesForType(TYPE_MOBILE_IMS);
   1210                 case "enableMMS":
   1211                     return networkCapabilitiesForType(TYPE_MOBILE_MMS);
   1212                 case "enableSUPL":
   1213                     return networkCapabilitiesForType(TYPE_MOBILE_SUPL);
   1214                 default:
   1215                     return null;
   1216             }
   1217         } else if (networkType == TYPE_WIFI && "p2p".equals(feature)) {
   1218             return networkCapabilitiesForType(TYPE_WIFI_P2P);
   1219         }
   1220         return null;
   1221     }
   1222 
   1223     /**
   1224      * Guess what the network request was trying to say so that the resulting
   1225      * network is accessible via the legacy (deprecated) API such as
   1226      * requestRouteToHost.
   1227      *
   1228      * This means we should try to be fairly precise about transport and
   1229      * capability but ignore things such as networkSpecifier.
   1230      * If the request has more than one transport or capability it doesn't
   1231      * match the old legacy requests (they selected only single transport/capability)
   1232      * so this function cannot map the request to a single legacy type and
   1233      * the resulting network will not be available to the legacy APIs.
   1234      *
   1235      * This code is only called from the requestNetwork API (L and above).
   1236      *
   1237      * Setting a legacy type causes CONNECTIVITY_ACTION broadcasts, which are expensive
   1238      * because they wake up lots of apps - see http://b/23350688 . So we currently only
   1239      * do this for SUPL requests, which are the only ones that we know need it. If
   1240      * omitting these broadcasts causes unacceptable app breakage, then for backwards
   1241      * compatibility we can send them:
   1242      *
   1243      * if (targetSdkVersion < Build.VERSION_CODES.M) &&        // legacy API unsupported >= M
   1244      *     targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP))  // requestNetwork not present < L
   1245      *
   1246      * TODO - This should be removed when the legacy APIs are removed.
   1247      */
   1248     private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
   1249         if (netCap == null) {
   1250             return TYPE_NONE;
   1251         }
   1252 
   1253         if (!netCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
   1254             return TYPE_NONE;
   1255         }
   1256 
   1257         // Do this only for SUPL, until GnssLocationProvider is fixed. http://b/25876485 .
   1258         if (!netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
   1259             // NOTE: if this causes app breakage, we should not just comment out this early return;
   1260             // instead, we should make this early return conditional on the requesting app's target
   1261             // SDK version, as described in the comment above.
   1262             return TYPE_NONE;
   1263         }
   1264 
   1265         String type = null;
   1266         int result = TYPE_NONE;
   1267 
   1268         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
   1269             type = "enableCBS";
   1270             result = TYPE_MOBILE_CBS;
   1271         } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
   1272             type = "enableIMS";
   1273             result = TYPE_MOBILE_IMS;
   1274         } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
   1275             type = "enableFOTA";
   1276             result = TYPE_MOBILE_FOTA;
   1277         } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
   1278             type = "enableDUN";
   1279             result = TYPE_MOBILE_DUN;
   1280         } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
   1281             type = "enableSUPL";
   1282             result = TYPE_MOBILE_SUPL;
   1283         // back out this hack for mms as they no longer need this and it's causing
   1284         // device slowdowns - b/23350688 (note, supl still needs this)
   1285         //} else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
   1286         //    type = "enableMMS";
   1287         //    result = TYPE_MOBILE_MMS;
   1288         } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
   1289             type = "enableHIPRI";
   1290             result = TYPE_MOBILE_HIPRI;
   1291         }
   1292         if (type != null) {
   1293             NetworkCapabilities testCap = networkCapabilitiesForFeature(TYPE_MOBILE, type);
   1294             if (testCap.equalsNetCapabilities(netCap) && testCap.equalsTransportTypes(netCap)) {
   1295                 return result;
   1296             }
   1297         }
   1298         return TYPE_NONE;
   1299     }
   1300 
   1301     private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
   1302         if (netCap == null) return TYPE_NONE;
   1303         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
   1304             return TYPE_MOBILE_CBS;
   1305         }
   1306         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
   1307             return TYPE_MOBILE_IMS;
   1308         }
   1309         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
   1310             return TYPE_MOBILE_FOTA;
   1311         }
   1312         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
   1313             return TYPE_MOBILE_DUN;
   1314         }
   1315         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
   1316             return TYPE_MOBILE_SUPL;
   1317         }
   1318         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
   1319             return TYPE_MOBILE_MMS;
   1320         }
   1321         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
   1322             return TYPE_MOBILE_HIPRI;
   1323         }
   1324         if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) {
   1325             return TYPE_WIFI_P2P;
   1326         }
   1327         return TYPE_NONE;
   1328     }
   1329 
   1330     private static class LegacyRequest {
   1331         NetworkCapabilities networkCapabilities;
   1332         NetworkRequest networkRequest;
   1333         int expireSequenceNumber;
   1334         Network currentNetwork;
   1335         int delay = -1;
   1336 
   1337         private void clearDnsBinding() {
   1338             if (currentNetwork != null) {
   1339                 currentNetwork = null;
   1340                 setProcessDefaultNetworkForHostResolution(null);
   1341             }
   1342         }
   1343 
   1344         NetworkCallback networkCallback = new NetworkCallback() {
   1345             @Override
   1346             public void onAvailable(Network network) {
   1347                 currentNetwork = network;
   1348                 Log.d(TAG, "startUsingNetworkFeature got Network:" + network);
   1349                 setProcessDefaultNetworkForHostResolution(network);
   1350             }
   1351             @Override
   1352             public void onLost(Network network) {
   1353                 if (network.equals(currentNetwork)) clearDnsBinding();
   1354                 Log.d(TAG, "startUsingNetworkFeature lost Network:" + network);
   1355             }
   1356         };
   1357     }
   1358 
   1359     private static HashMap<NetworkCapabilities, LegacyRequest> sLegacyRequests =
   1360             new HashMap<NetworkCapabilities, LegacyRequest>();
   1361 
   1362     private NetworkRequest findRequestForFeature(NetworkCapabilities netCap) {
   1363         synchronized (sLegacyRequests) {
   1364             LegacyRequest l = sLegacyRequests.get(netCap);
   1365             if (l != null) return l.networkRequest;
   1366         }
   1367         return null;
   1368     }
   1369 
   1370     private void renewRequestLocked(LegacyRequest l) {
   1371         l.expireSequenceNumber++;
   1372         Log.d(TAG, "renewing request to seqNum " + l.expireSequenceNumber);
   1373         sendExpireMsgForFeature(l.networkCapabilities, l.expireSequenceNumber, l.delay);
   1374     }
   1375 
   1376     private void expireRequest(NetworkCapabilities netCap, int sequenceNum) {
   1377         int ourSeqNum = -1;
   1378         synchronized (sLegacyRequests) {
   1379             LegacyRequest l = sLegacyRequests.get(netCap);
   1380             if (l == null) return;
   1381             ourSeqNum = l.expireSequenceNumber;
   1382             if (l.expireSequenceNumber == sequenceNum) removeRequestForFeature(netCap);
   1383         }
   1384         Log.d(TAG, "expireRequest with " + ourSeqNum + ", " + sequenceNum);
   1385     }
   1386 
   1387     private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) {
   1388         int delay = -1;
   1389         int type = legacyTypeForNetworkCapabilities(netCap);
   1390         try {
   1391             delay = mService.getRestoreDefaultNetworkDelay(type);
   1392         } catch (RemoteException e) {
   1393             throw e.rethrowFromSystemServer();
   1394         }
   1395         LegacyRequest l = new LegacyRequest();
   1396         l.networkCapabilities = netCap;
   1397         l.delay = delay;
   1398         l.expireSequenceNumber = 0;
   1399         l.networkRequest = sendRequestForNetwork(
   1400                 netCap, l.networkCallback, 0, REQUEST, type, getDefaultHandler());
   1401         if (l.networkRequest == null) return null;
   1402         sLegacyRequests.put(netCap, l);
   1403         sendExpireMsgForFeature(netCap, l.expireSequenceNumber, delay);
   1404         return l.networkRequest;
   1405     }
   1406 
   1407     private void sendExpireMsgForFeature(NetworkCapabilities netCap, int seqNum, int delay) {
   1408         if (delay >= 0) {
   1409             Log.d(TAG, "sending expire msg with seqNum " + seqNum + " and delay " + delay);
   1410             CallbackHandler handler = getDefaultHandler();
   1411             Message msg = handler.obtainMessage(EXPIRE_LEGACY_REQUEST, seqNum, 0, netCap);
   1412             handler.sendMessageDelayed(msg, delay);
   1413         }
   1414     }
   1415 
   1416     private boolean removeRequestForFeature(NetworkCapabilities netCap) {
   1417         final LegacyRequest l;
   1418         synchronized (sLegacyRequests) {
   1419             l = sLegacyRequests.remove(netCap);
   1420         }
   1421         if (l == null) return false;
   1422         unregisterNetworkCallback(l.networkCallback);
   1423         l.clearDnsBinding();
   1424         return true;
   1425     }
   1426 
   1427     private static final SparseIntArray sLegacyTypeToTransport = new SparseIntArray();
   1428     static {
   1429         sLegacyTypeToTransport.put(TYPE_MOBILE,       NetworkCapabilities.TRANSPORT_CELLULAR);
   1430         sLegacyTypeToTransport.put(TYPE_MOBILE_CBS,   NetworkCapabilities.TRANSPORT_CELLULAR);
   1431         sLegacyTypeToTransport.put(TYPE_MOBILE_DUN,   NetworkCapabilities.TRANSPORT_CELLULAR);
   1432         sLegacyTypeToTransport.put(TYPE_MOBILE_FOTA,  NetworkCapabilities.TRANSPORT_CELLULAR);
   1433         sLegacyTypeToTransport.put(TYPE_MOBILE_HIPRI, NetworkCapabilities.TRANSPORT_CELLULAR);
   1434         sLegacyTypeToTransport.put(TYPE_MOBILE_IMS,   NetworkCapabilities.TRANSPORT_CELLULAR);
   1435         sLegacyTypeToTransport.put(TYPE_MOBILE_MMS,   NetworkCapabilities.TRANSPORT_CELLULAR);
   1436         sLegacyTypeToTransport.put(TYPE_MOBILE_SUPL,  NetworkCapabilities.TRANSPORT_CELLULAR);
   1437         sLegacyTypeToTransport.put(TYPE_WIFI,         NetworkCapabilities.TRANSPORT_WIFI);
   1438         sLegacyTypeToTransport.put(TYPE_WIFI_P2P,     NetworkCapabilities.TRANSPORT_WIFI);
   1439         sLegacyTypeToTransport.put(TYPE_BLUETOOTH,    NetworkCapabilities.TRANSPORT_BLUETOOTH);
   1440         sLegacyTypeToTransport.put(TYPE_ETHERNET,     NetworkCapabilities.TRANSPORT_ETHERNET);
   1441     }
   1442 
   1443     private static final SparseIntArray sLegacyTypeToCapability = new SparseIntArray();
   1444     static {
   1445         sLegacyTypeToCapability.put(TYPE_MOBILE_CBS,  NetworkCapabilities.NET_CAPABILITY_CBS);
   1446         sLegacyTypeToCapability.put(TYPE_MOBILE_DUN,  NetworkCapabilities.NET_CAPABILITY_DUN);
   1447         sLegacyTypeToCapability.put(TYPE_MOBILE_FOTA, NetworkCapabilities.NET_CAPABILITY_FOTA);
   1448         sLegacyTypeToCapability.put(TYPE_MOBILE_IMS,  NetworkCapabilities.NET_CAPABILITY_IMS);
   1449         sLegacyTypeToCapability.put(TYPE_MOBILE_MMS,  NetworkCapabilities.NET_CAPABILITY_MMS);
   1450         sLegacyTypeToCapability.put(TYPE_MOBILE_SUPL, NetworkCapabilities.NET_CAPABILITY_SUPL);
   1451         sLegacyTypeToCapability.put(TYPE_WIFI_P2P,    NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
   1452     }
   1453 
   1454     /**
   1455      * Given a legacy type (TYPE_WIFI, ...) returns a NetworkCapabilities
   1456      * instance suitable for registering a request or callback.  Throws an
   1457      * IllegalArgumentException if no mapping from the legacy type to
   1458      * NetworkCapabilities is known.
   1459      *
   1460      * @hide
   1461      */
   1462     public static NetworkCapabilities networkCapabilitiesForType(int type) {
   1463         final NetworkCapabilities nc = new NetworkCapabilities();
   1464 
   1465         // Map from type to transports.
   1466         final int NOT_FOUND = -1;
   1467         final int transport = sLegacyTypeToTransport.get(type, NOT_FOUND);
   1468         if (transport == NOT_FOUND) {
   1469             throw new IllegalArgumentException("unknown legacy type: " + type);
   1470         }
   1471         nc.addTransportType(transport);
   1472 
   1473         // Map from type to capabilities.
   1474         nc.addCapability(sLegacyTypeToCapability.get(
   1475                 type, NetworkCapabilities.NET_CAPABILITY_INTERNET));
   1476         nc.maybeMarkCapabilitiesRestricted();
   1477         return nc;
   1478     }
   1479 
   1480     /** @hide */
   1481     public static class PacketKeepaliveCallback {
   1482         /** The requested keepalive was successfully started. */
   1483         public void onStarted() {}
   1484         /** The keepalive was successfully stopped. */
   1485         public void onStopped() {}
   1486         /** An error occurred. */
   1487         public void onError(int error) {}
   1488     }
   1489 
   1490     /**
   1491      * Allows applications to request that the system periodically send specific packets on their
   1492      * behalf, using hardware offload to save battery power.
   1493      *
   1494      * To request that the system send keepalives, call one of the methods that return a
   1495      * {@link ConnectivityManager.PacketKeepalive} object, such as {@link #startNattKeepalive},
   1496      * passing in a non-null callback. If the callback is successfully started, the callback's
   1497      * {@code onStarted} method will be called. If an error occurs, {@code onError} will be called,
   1498      * specifying one of the {@code ERROR_*} constants in this class.
   1499      *
   1500      * To stop an existing keepalive, call {@link stop}. The system will call {@code onStopped} if
   1501      * the operation was successfull or {@code onError} if an error occurred.
   1502      *
   1503      * @hide
   1504      */
   1505     public class PacketKeepalive {
   1506 
   1507         private static final String TAG = "PacketKeepalive";
   1508 
   1509         /** @hide */
   1510         public static final int SUCCESS = 0;
   1511 
   1512         /** @hide */
   1513         public static final int NO_KEEPALIVE = -1;
   1514 
   1515         /** @hide */
   1516         public static final int BINDER_DIED = -10;
   1517 
   1518         /** The specified {@code Network} is not connected. */
   1519         public static final int ERROR_INVALID_NETWORK = -20;
   1520         /** The specified IP addresses are invalid. For example, the specified source IP address is
   1521           * not configured on the specified {@code Network}. */
   1522         public static final int ERROR_INVALID_IP_ADDRESS = -21;
   1523         /** The requested port is invalid. */
   1524         public static final int ERROR_INVALID_PORT = -22;
   1525         /** The packet length is invalid (e.g., too long). */
   1526         public static final int ERROR_INVALID_LENGTH = -23;
   1527         /** The packet transmission interval is invalid (e.g., too short). */
   1528         public static final int ERROR_INVALID_INTERVAL = -24;
   1529 
   1530         /** The hardware does not support this request. */
   1531         public static final int ERROR_HARDWARE_UNSUPPORTED = -30;
   1532         /** The hardware returned an error. */
   1533         public static final int ERROR_HARDWARE_ERROR = -31;
   1534 
   1535         public static final int NATT_PORT = 4500;
   1536 
   1537         private final Network mNetwork;
   1538         private final PacketKeepaliveCallback mCallback;
   1539         private final Looper mLooper;
   1540         private final Messenger mMessenger;
   1541 
   1542         private volatile Integer mSlot;
   1543 
   1544         void stopLooper() {
   1545             mLooper.quit();
   1546         }
   1547 
   1548         public void stop() {
   1549             try {
   1550                 mService.stopKeepalive(mNetwork, mSlot);
   1551             } catch (RemoteException e) {
   1552                 Log.e(TAG, "Error stopping packet keepalive: ", e);
   1553                 stopLooper();
   1554             }
   1555         }
   1556 
   1557         private PacketKeepalive(Network network, PacketKeepaliveCallback callback) {
   1558             checkNotNull(network, "network cannot be null");
   1559             checkNotNull(callback, "callback cannot be null");
   1560             mNetwork = network;
   1561             mCallback = callback;
   1562             HandlerThread thread = new HandlerThread(TAG);
   1563             thread.start();
   1564             mLooper = thread.getLooper();
   1565             mMessenger = new Messenger(new Handler(mLooper) {
   1566                 @Override
   1567                 public void handleMessage(Message message) {
   1568                     switch (message.what) {
   1569                         case NetworkAgent.EVENT_PACKET_KEEPALIVE:
   1570                             int error = message.arg2;
   1571                             try {
   1572                                 if (error == SUCCESS) {
   1573                                     if (mSlot == null) {
   1574                                         mSlot = message.arg1;
   1575                                         mCallback.onStarted();
   1576                                     } else {
   1577                                         mSlot = null;
   1578                                         stopLooper();
   1579                                         mCallback.onStopped();
   1580                                     }
   1581                                 } else {
   1582                                     stopLooper();
   1583                                     mCallback.onError(error);
   1584                                 }
   1585                             } catch (Exception e) {
   1586                                 Log.e(TAG, "Exception in keepalive callback(" + error + ")", e);
   1587                             }
   1588                             break;
   1589                         default:
   1590                             Log.e(TAG, "Unhandled message " + Integer.toHexString(message.what));
   1591                             break;
   1592                     }
   1593                 }
   1594             });
   1595         }
   1596     }
   1597 
   1598     /**
   1599      * Starts an IPsec NAT-T keepalive packet with the specified parameters.
   1600      *
   1601      * @hide
   1602      */
   1603     public PacketKeepalive startNattKeepalive(
   1604             Network network, int intervalSeconds, PacketKeepaliveCallback callback,
   1605             InetAddress srcAddr, int srcPort, InetAddress dstAddr) {
   1606         final PacketKeepalive k = new PacketKeepalive(network, callback);
   1607         try {
   1608             mService.startNattKeepalive(network, intervalSeconds, k.mMessenger, new Binder(),
   1609                     srcAddr.getHostAddress(), srcPort, dstAddr.getHostAddress());
   1610         } catch (RemoteException e) {
   1611             Log.e(TAG, "Error starting packet keepalive: ", e);
   1612             k.stopLooper();
   1613             return null;
   1614         }
   1615         return k;
   1616     }
   1617 
   1618     /**
   1619      * Ensure that a network route exists to deliver traffic to the specified
   1620      * host via the specified network interface. An attempt to add a route that
   1621      * already exists is ignored, but treated as successful.
   1622      *
   1623      * <p>This method requires the caller to hold either the
   1624      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
   1625      * or the ability to modify system settings as determined by
   1626      * {@link android.provider.Settings.System#canWrite}.</p>
   1627      *
   1628      * @param networkType the type of the network over which traffic to the specified
   1629      * host is to be routed
   1630      * @param hostAddress the IP address of the host to which the route is desired
   1631      * @return {@code true} on success, {@code false} on failure
   1632      *
   1633      * @deprecated Deprecated in favor of the
   1634      *             {@link #requestNetwork(NetworkRequest, NetworkCallback)},
   1635      *             {@link #bindProcessToNetwork} and {@link Network#getSocketFactory} API.
   1636      *             In {@link VERSION_CODES#M}, and above, this method is unsupported and will
   1637      *             throw {@code UnsupportedOperationException} if called.
   1638      * @removed
   1639      */
   1640     @Deprecated
   1641     public boolean requestRouteToHost(int networkType, int hostAddress) {
   1642         return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress));
   1643     }
   1644 
   1645     /**
   1646      * Ensure that a network route exists to deliver traffic to the specified
   1647      * host via the specified network interface. An attempt to add a route that
   1648      * already exists is ignored, but treated as successful.
   1649      *
   1650      * <p>This method requires the caller to hold either the
   1651      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
   1652      * or the ability to modify system settings as determined by
   1653      * {@link android.provider.Settings.System#canWrite}.</p>
   1654      *
   1655      * @param networkType the type of the network over which traffic to the specified
   1656      * host is to be routed
   1657      * @param hostAddress the IP address of the host to which the route is desired
   1658      * @return {@code true} on success, {@code false} on failure
   1659      * @hide
   1660      * @deprecated Deprecated in favor of the {@link #requestNetwork} and
   1661      *             {@link #bindProcessToNetwork} API.
   1662      */
   1663     @Deprecated
   1664     public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
   1665         checkLegacyRoutingApiAccess();
   1666         try {
   1667             return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress());
   1668         } catch (RemoteException e) {
   1669             throw e.rethrowFromSystemServer();
   1670         }
   1671     }
   1672 
   1673     /**
   1674      * Returns the value of the setting for background data usage. If false,
   1675      * applications should not use the network if the application is not in the
   1676      * foreground. Developers should respect this setting, and check the value
   1677      * of this before performing any background data operations.
   1678      * <p>
   1679      * All applications that have background services that use the network
   1680      * should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}.
   1681      * <p>
   1682      * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability of
   1683      * background data depends on several combined factors, and this method will
   1684      * always return {@code true}. Instead, when background data is unavailable,
   1685      * {@link #getActiveNetworkInfo()} will now appear disconnected.
   1686      *
   1687      * @return Whether background data usage is allowed.
   1688      */
   1689     @Deprecated
   1690     public boolean getBackgroundDataSetting() {
   1691         // assume that background data is allowed; final authority is
   1692         // NetworkInfo which may be blocked.
   1693         return true;
   1694     }
   1695 
   1696     /**
   1697      * Sets the value of the setting for background data usage.
   1698      *
   1699      * @param allowBackgroundData Whether an application should use data while
   1700      *            it is in the background.
   1701      *
   1702      * @attr ref android.Manifest.permission#CHANGE_BACKGROUND_DATA_SETTING
   1703      * @see #getBackgroundDataSetting()
   1704      * @hide
   1705      */
   1706     @Deprecated
   1707     public void setBackgroundDataSetting(boolean allowBackgroundData) {
   1708         // ignored
   1709     }
   1710 
   1711     /**
   1712      * Return quota status for the current active network, or {@code null} if no
   1713      * network is active. Quota status can change rapidly, so these values
   1714      * shouldn't be cached.
   1715      *
   1716      * @hide
   1717      */
   1718     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   1719     public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
   1720         try {
   1721             return mService.getActiveNetworkQuotaInfo();
   1722         } catch (RemoteException e) {
   1723             throw e.rethrowFromSystemServer();
   1724         }
   1725     }
   1726 
   1727     /**
   1728      * @hide
   1729      * @deprecated Talk to TelephonyManager directly
   1730      */
   1731     @Deprecated
   1732     public boolean getMobileDataEnabled() {
   1733         IBinder b = ServiceManager.getService(Context.TELEPHONY_SERVICE);
   1734         if (b != null) {
   1735             try {
   1736                 ITelephony it = ITelephony.Stub.asInterface(b);
   1737                 int subId = SubscriptionManager.getDefaultDataSubscriptionId();
   1738                 Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
   1739                 boolean retVal = it.getDataEnabled(subId);
   1740                 Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
   1741                         + " retVal=" + retVal);
   1742                 return retVal;
   1743             } catch (RemoteException e) {
   1744                 throw e.rethrowFromSystemServer();
   1745             }
   1746         }
   1747         Log.d("ConnectivityManager", "getMobileDataEnabled()- remote exception retVal=false");
   1748         return false;
   1749     }
   1750 
   1751     /**
   1752      * Callback for use with {@link ConnectivityManager#addDefaultNetworkActiveListener}
   1753      * to find out when the system default network has gone in to a high power state.
   1754      */
   1755     public interface OnNetworkActiveListener {
   1756         /**
   1757          * Called on the main thread of the process to report that the current data network
   1758          * has become active, and it is now a good time to perform any pending network
   1759          * operations.  Note that this listener only tells you when the network becomes
   1760          * active; if at any other time you want to know whether it is active (and thus okay
   1761          * to initiate network traffic), you can retrieve its instantaneous state with
   1762          * {@link ConnectivityManager#isDefaultNetworkActive}.
   1763          */
   1764         public void onNetworkActive();
   1765     }
   1766 
   1767     private INetworkManagementService getNetworkManagementService() {
   1768         synchronized (this) {
   1769             if (mNMService != null) {
   1770                 return mNMService;
   1771             }
   1772             IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
   1773             mNMService = INetworkManagementService.Stub.asInterface(b);
   1774             return mNMService;
   1775         }
   1776     }
   1777 
   1778     private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
   1779             mNetworkActivityListeners
   1780                     = new ArrayMap<OnNetworkActiveListener, INetworkActivityListener>();
   1781 
   1782     /**
   1783      * Start listening to reports when the system's default data network is active, meaning it is
   1784      * a good time to perform network traffic.  Use {@link #isDefaultNetworkActive()}
   1785      * to determine the current state of the system's default network after registering the
   1786      * listener.
   1787      * <p>
   1788      * If the process default network has been set with
   1789      * {@link ConnectivityManager#bindProcessToNetwork} this function will not
   1790      * reflect the process's default, but the system default.
   1791      *
   1792      * @param l The listener to be told when the network is active.
   1793      */
   1794     public void addDefaultNetworkActiveListener(final OnNetworkActiveListener l) {
   1795         INetworkActivityListener rl = new INetworkActivityListener.Stub() {
   1796             @Override
   1797             public void onNetworkActive() throws RemoteException {
   1798                 l.onNetworkActive();
   1799             }
   1800         };
   1801 
   1802         try {
   1803             getNetworkManagementService().registerNetworkActivityListener(rl);
   1804             mNetworkActivityListeners.put(l, rl);
   1805         } catch (RemoteException e) {
   1806             throw e.rethrowFromSystemServer();
   1807         }
   1808     }
   1809 
   1810     /**
   1811      * Remove network active listener previously registered with
   1812      * {@link #addDefaultNetworkActiveListener}.
   1813      *
   1814      * @param l Previously registered listener.
   1815      */
   1816     public void removeDefaultNetworkActiveListener(OnNetworkActiveListener l) {
   1817         INetworkActivityListener rl = mNetworkActivityListeners.get(l);
   1818         if (rl == null) {
   1819             throw new IllegalArgumentException("Listener not registered: " + l);
   1820         }
   1821         try {
   1822             getNetworkManagementService().unregisterNetworkActivityListener(rl);
   1823         } catch (RemoteException e) {
   1824             throw e.rethrowFromSystemServer();
   1825         }
   1826     }
   1827 
   1828     /**
   1829      * Return whether the data network is currently active.  An active network means that
   1830      * it is currently in a high power state for performing data transmission.  On some
   1831      * types of networks, it may be expensive to move and stay in such a state, so it is
   1832      * more power efficient to batch network traffic together when the radio is already in
   1833      * this state.  This method tells you whether right now is currently a good time to
   1834      * initiate network traffic, as the network is already active.
   1835      */
   1836     public boolean isDefaultNetworkActive() {
   1837         try {
   1838             return getNetworkManagementService().isNetworkActive();
   1839         } catch (RemoteException e) {
   1840             throw e.rethrowFromSystemServer();
   1841         }
   1842     }
   1843 
   1844     /**
   1845      * {@hide}
   1846      */
   1847     public ConnectivityManager(Context context, IConnectivityManager service) {
   1848         mContext = checkNotNull(context, "missing context");
   1849         mService = checkNotNull(service, "missing IConnectivityManager");
   1850         sInstance = this;
   1851     }
   1852 
   1853     /** {@hide} */
   1854     public static ConnectivityManager from(Context context) {
   1855         return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
   1856     }
   1857 
   1858     /* TODO: These permissions checks don't belong in client-side code. Move them to
   1859      * services.jar, possibly in com.android.server.net. */
   1860 
   1861     /** {@hide} */
   1862     public static final boolean checkChangePermission(Context context) {
   1863         int uid = Binder.getCallingUid();
   1864         return Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings
   1865                 .getPackageNameForUid(context, uid), false /* throwException */);
   1866     }
   1867 
   1868     /** {@hide} */
   1869     public static final void enforceChangePermission(Context context) {
   1870         int uid = Binder.getCallingUid();
   1871         Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings
   1872                 .getPackageNameForUid(context, uid), true /* throwException */);
   1873     }
   1874 
   1875     /** {@hide */
   1876     public static final void enforceTetherChangePermission(Context context) {
   1877         if (context.getResources().getStringArray(
   1878                 com.android.internal.R.array.config_mobile_hotspot_provision_app).length == 2) {
   1879             // Have a provisioning app - must only let system apps (which check this app)
   1880             // turn on tethering
   1881             context.enforceCallingOrSelfPermission(
   1882                     android.Manifest.permission.TETHER_PRIVILEGED, "ConnectivityService");
   1883         } else {
   1884             int uid = Binder.getCallingUid();
   1885             Settings.checkAndNoteWriteSettingsOperation(context, uid, Settings
   1886                     .getPackageNameForUid(context, uid), true /* throwException */);
   1887         }
   1888     }
   1889 
   1890     /**
   1891      * @deprecated - use getSystemService. This is a kludge to support static access in certain
   1892      *               situations where a Context pointer is unavailable.
   1893      * @hide
   1894      */
   1895     @Deprecated
   1896     static ConnectivityManager getInstanceOrNull() {
   1897         return sInstance;
   1898     }
   1899 
   1900     /**
   1901      * @deprecated - use getSystemService. This is a kludge to support static access in certain
   1902      *               situations where a Context pointer is unavailable.
   1903      * @hide
   1904      */
   1905     @Deprecated
   1906     private static ConnectivityManager getInstance() {
   1907         if (getInstanceOrNull() == null) {
   1908             throw new IllegalStateException("No ConnectivityManager yet constructed");
   1909         }
   1910         return getInstanceOrNull();
   1911     }
   1912 
   1913     /**
   1914      * Get the set of tetherable, available interfaces.  This list is limited by
   1915      * device configuration and current interface existence.
   1916      *
   1917      * @return an array of 0 or more Strings of tetherable interface names.
   1918      *
   1919      * {@hide}
   1920      */
   1921     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   1922     public String[] getTetherableIfaces() {
   1923         try {
   1924             return mService.getTetherableIfaces();
   1925         } catch (RemoteException e) {
   1926             throw e.rethrowFromSystemServer();
   1927         }
   1928     }
   1929 
   1930     /**
   1931      * Get the set of tethered interfaces.
   1932      *
   1933      * @return an array of 0 or more String of currently tethered interface names.
   1934      *
   1935      * {@hide}
   1936      */
   1937     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   1938     public String[] getTetheredIfaces() {
   1939         try {
   1940             return mService.getTetheredIfaces();
   1941         } catch (RemoteException e) {
   1942             throw e.rethrowFromSystemServer();
   1943         }
   1944     }
   1945 
   1946     /**
   1947      * Get the set of interface names which attempted to tether but
   1948      * failed.  Re-attempting to tether may cause them to reset to the Tethered
   1949      * state.  Alternatively, causing the interface to be destroyed and recreated
   1950      * may cause them to reset to the available state.
   1951      * {@link ConnectivityManager#getLastTetherError} can be used to get more
   1952      * information on the cause of the errors.
   1953      *
   1954      * @return an array of 0 or more String indicating the interface names
   1955      *        which failed to tether.
   1956      *
   1957      * {@hide}
   1958      */
   1959     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   1960     public String[] getTetheringErroredIfaces() {
   1961         try {
   1962             return mService.getTetheringErroredIfaces();
   1963         } catch (RemoteException e) {
   1964             throw e.rethrowFromSystemServer();
   1965         }
   1966     }
   1967 
   1968     /**
   1969      * Get the set of tethered dhcp ranges.
   1970      *
   1971      * @return an array of 0 or more {@code String} of tethered dhcp ranges.
   1972      * {@hide}
   1973      */
   1974     public String[] getTetheredDhcpRanges() {
   1975         try {
   1976             return mService.getTetheredDhcpRanges();
   1977         } catch (RemoteException e) {
   1978             throw e.rethrowFromSystemServer();
   1979         }
   1980     }
   1981 
   1982     /**
   1983      * Attempt to tether the named interface.  This will setup a dhcp server
   1984      * on the interface, forward and NAT IP packets and forward DNS requests
   1985      * to the best active upstream network interface.  Note that if no upstream
   1986      * IP network interface is available, dhcp will still run and traffic will be
   1987      * allowed between the tethered devices and this device, though upstream net
   1988      * access will of course fail until an upstream network interface becomes
   1989      * active.
   1990      *
   1991      * <p>This method requires the caller to hold either the
   1992      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
   1993      * or the ability to modify system settings as determined by
   1994      * {@link android.provider.Settings.System#canWrite}.</p>
   1995      *
   1996      * <p>WARNING: New clients should not use this function. The only usages should be in PanService
   1997      * and WifiStateMachine which need direct access. All other clients should use
   1998      * {@link #startTethering} and {@link #stopTethering} which encapsulate proper provisioning
   1999      * logic.</p>
   2000      *
   2001      * @param iface the interface name to tether.
   2002      * @return error a {@code TETHER_ERROR} value indicating success or failure type
   2003      *
   2004      * {@hide}
   2005      */
   2006     public int tether(String iface) {
   2007         try {
   2008             return mService.tether(iface);
   2009         } catch (RemoteException e) {
   2010             throw e.rethrowFromSystemServer();
   2011         }
   2012     }
   2013 
   2014     /**
   2015      * Stop tethering the named interface.
   2016      *
   2017      * <p>This method requires the caller to hold either the
   2018      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
   2019      * or the ability to modify system settings as determined by
   2020      * {@link android.provider.Settings.System#canWrite}.</p>
   2021      *
   2022      * <p>WARNING: New clients should not use this function. The only usages should be in PanService
   2023      * and WifiStateMachine which need direct access. All other clients should use
   2024      * {@link #startTethering} and {@link #stopTethering} which encapsulate proper provisioning
   2025      * logic.</p>
   2026      *
   2027      * @param iface the interface name to untether.
   2028      * @return error a {@code TETHER_ERROR} value indicating success or failure type
   2029      *
   2030      * {@hide}
   2031      */
   2032     public int untether(String iface) {
   2033         try {
   2034             return mService.untether(iface);
   2035         } catch (RemoteException e) {
   2036             throw e.rethrowFromSystemServer();
   2037         }
   2038     }
   2039 
   2040     /**
   2041      * Check if the device allows for tethering.  It may be disabled via
   2042      * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
   2043      * due to device configuration.
   2044      *
   2045      * @return a boolean - {@code true} indicating Tethering is supported.
   2046      *
   2047      * {@hide}
   2048      */
   2049     @SystemApi
   2050     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   2051     public boolean isTetheringSupported() {
   2052         try {
   2053             return mService.isTetheringSupported();
   2054         } catch (RemoteException e) {
   2055             throw e.rethrowFromSystemServer();
   2056         }
   2057     }
   2058 
   2059     /**
   2060      * Callback for use with {@link #startTethering} to find out whether tethering succeeded.
   2061      * @hide
   2062      */
   2063     @SystemApi
   2064     public static abstract class OnStartTetheringCallback {
   2065         /**
   2066          * Called when tethering has been successfully started.
   2067          */
   2068         public void onTetheringStarted() {};
   2069 
   2070         /**
   2071          * Called when starting tethering failed.
   2072          */
   2073         public void onTetheringFailed() {};
   2074     }
   2075 
   2076     /**
   2077      * Convenient overload for
   2078      * {@link #startTethering(int, boolean, OnStartTetheringCallback, Handler)} which passes a null
   2079      * handler to run on the current thread's {@link Looper}.
   2080      * @hide
   2081      */
   2082     @SystemApi
   2083     public void startTethering(int type, boolean showProvisioningUi,
   2084             final OnStartTetheringCallback callback) {
   2085         startTethering(type, showProvisioningUi, callback, null);
   2086     }
   2087 
   2088     /**
   2089      * Runs tether provisioning for the given type if needed and then starts tethering if
   2090      * the check succeeds. If no carrier provisioning is required for tethering, tethering is
   2091      * enabled immediately. If provisioning fails, tethering will not be enabled. It also
   2092      * schedules tether provisioning re-checks if appropriate.
   2093      *
   2094      * @param type The type of tethering to start. Must be one of
   2095      *         {@link ConnectivityManager.TETHERING_WIFI},
   2096      *         {@link ConnectivityManager.TETHERING_USB}, or
   2097      *         {@link ConnectivityManager.TETHERING_BLUETOOTH}.
   2098      * @param showProvisioningUi a boolean indicating to show the provisioning app UI if there
   2099      *         is one. This should be true the first time this function is called and also any time
   2100      *         the user can see this UI. It gives users information from their carrier about the
   2101      *         check failing and how they can sign up for tethering if possible.
   2102      * @param callback an {@link OnStartTetheringCallback} which will be called to notify the caller
   2103      *         of the result of trying to tether.
   2104      * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
   2105      * @hide
   2106      */
   2107     @SystemApi
   2108     @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
   2109     public void startTethering(int type, boolean showProvisioningUi,
   2110             final OnStartTetheringCallback callback, Handler handler) {
   2111         checkNotNull(callback, "OnStartTetheringCallback cannot be null.");
   2112 
   2113         ResultReceiver wrappedCallback = new ResultReceiver(handler) {
   2114             @Override
   2115             protected void onReceiveResult(int resultCode, Bundle resultData) {
   2116                 if (resultCode == TETHER_ERROR_NO_ERROR) {
   2117                     callback.onTetheringStarted();
   2118                 } else {
   2119                     callback.onTetheringFailed();
   2120                 }
   2121             }
   2122         };
   2123 
   2124         try {
   2125             mService.startTethering(type, wrappedCallback, showProvisioningUi);
   2126         } catch (RemoteException e) {
   2127             Log.e(TAG, "Exception trying to start tethering.", e);
   2128             wrappedCallback.send(TETHER_ERROR_SERVICE_UNAVAIL, null);
   2129         }
   2130     }
   2131 
   2132     /**
   2133      * Stops tethering for the given type. Also cancels any provisioning rechecks for that type if
   2134      * applicable.
   2135      *
   2136      * @param type The type of tethering to stop. Must be one of
   2137      *         {@link ConnectivityManager.TETHERING_WIFI},
   2138      *         {@link ConnectivityManager.TETHERING_USB}, or
   2139      *         {@link ConnectivityManager.TETHERING_BLUETOOTH}.
   2140      * @hide
   2141      */
   2142     @SystemApi
   2143     @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
   2144     public void stopTethering(int type) {
   2145         try {
   2146             mService.stopTethering(type);
   2147         } catch (RemoteException e) {
   2148             throw e.rethrowFromSystemServer();
   2149         }
   2150     }
   2151 
   2152     /**
   2153      * Get the list of regular expressions that define any tetherable
   2154      * USB network interfaces.  If USB tethering is not supported by the
   2155      * device, this list should be empty.
   2156      *
   2157      * @return an array of 0 or more regular expression Strings defining
   2158      *        what interfaces are considered tetherable usb interfaces.
   2159      *
   2160      * {@hide}
   2161      */
   2162     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   2163     public String[] getTetherableUsbRegexs() {
   2164         try {
   2165             return mService.getTetherableUsbRegexs();
   2166         } catch (RemoteException e) {
   2167             throw e.rethrowFromSystemServer();
   2168         }
   2169     }
   2170 
   2171     /**
   2172      * Get the list of regular expressions that define any tetherable
   2173      * Wifi network interfaces.  If Wifi tethering is not supported by the
   2174      * device, this list should be empty.
   2175      *
   2176      * @return an array of 0 or more regular expression Strings defining
   2177      *        what interfaces are considered tetherable wifi interfaces.
   2178      *
   2179      * {@hide}
   2180      */
   2181     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   2182     public String[] getTetherableWifiRegexs() {
   2183         try {
   2184             return mService.getTetherableWifiRegexs();
   2185         } catch (RemoteException e) {
   2186             throw e.rethrowFromSystemServer();
   2187         }
   2188     }
   2189 
   2190     /**
   2191      * Get the list of regular expressions that define any tetherable
   2192      * Bluetooth network interfaces.  If Bluetooth tethering is not supported by the
   2193      * device, this list should be empty.
   2194      *
   2195      * @return an array of 0 or more regular expression Strings defining
   2196      *        what interfaces are considered tetherable bluetooth interfaces.
   2197      *
   2198      * {@hide}
   2199      */
   2200     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   2201     public String[] getTetherableBluetoothRegexs() {
   2202         try {
   2203             return mService.getTetherableBluetoothRegexs();
   2204         } catch (RemoteException e) {
   2205             throw e.rethrowFromSystemServer();
   2206         }
   2207     }
   2208 
   2209     /**
   2210      * Attempt to both alter the mode of USB and Tethering of USB.  A
   2211      * utility method to deal with some of the complexity of USB - will
   2212      * attempt to switch to Rndis and subsequently tether the resulting
   2213      * interface on {@code true} or turn off tethering and switch off
   2214      * Rndis on {@code false}.
   2215      *
   2216      * <p>This method requires the caller to hold either the
   2217      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
   2218      * or the ability to modify system settings as determined by
   2219      * {@link android.provider.Settings.System#canWrite}.</p>
   2220      *
   2221      * @param enable a boolean - {@code true} to enable tethering
   2222      * @return error a {@code TETHER_ERROR} value indicating success or failure type
   2223      *
   2224      * {@hide}
   2225      */
   2226     public int setUsbTethering(boolean enable) {
   2227         try {
   2228             return mService.setUsbTethering(enable);
   2229         } catch (RemoteException e) {
   2230             throw e.rethrowFromSystemServer();
   2231         }
   2232     }
   2233 
   2234     /** {@hide} */
   2235     public static final int TETHER_ERROR_NO_ERROR           = 0;
   2236     /** {@hide} */
   2237     public static final int TETHER_ERROR_UNKNOWN_IFACE      = 1;
   2238     /** {@hide} */
   2239     public static final int TETHER_ERROR_SERVICE_UNAVAIL    = 2;
   2240     /** {@hide} */
   2241     public static final int TETHER_ERROR_UNSUPPORTED        = 3;
   2242     /** {@hide} */
   2243     public static final int TETHER_ERROR_UNAVAIL_IFACE      = 4;
   2244     /** {@hide} */
   2245     public static final int TETHER_ERROR_MASTER_ERROR       = 5;
   2246     /** {@hide} */
   2247     public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
   2248     /** {@hide} */
   2249     public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
   2250     /** {@hide} */
   2251     public static final int TETHER_ERROR_ENABLE_NAT_ERROR     = 8;
   2252     /** {@hide} */
   2253     public static final int TETHER_ERROR_DISABLE_NAT_ERROR    = 9;
   2254     /** {@hide} */
   2255     public static final int TETHER_ERROR_IFACE_CFG_ERROR      = 10;
   2256     /** {@hide} */
   2257     public static final int TETHER_ERROR_PROVISION_FAILED     = 11;
   2258 
   2259     /**
   2260      * Get a more detailed error code after a Tethering or Untethering
   2261      * request asynchronously failed.
   2262      *
   2263      * @param iface The name of the interface of interest
   2264      * @return error The error code of the last error tethering or untethering the named
   2265      *               interface
   2266      *
   2267      * {@hide}
   2268      */
   2269     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   2270     public int getLastTetherError(String iface) {
   2271         try {
   2272             return mService.getLastTetherError(iface);
   2273         } catch (RemoteException e) {
   2274             throw e.rethrowFromSystemServer();
   2275         }
   2276     }
   2277 
   2278     /**
   2279      * Report network connectivity status.  This is currently used only
   2280      * to alter status bar UI.
   2281      * <p>This method requires the caller to hold the permission
   2282      * {@link android.Manifest.permission#STATUS_BAR}.
   2283      *
   2284      * @param networkType The type of network you want to report on
   2285      * @param percentage The quality of the connection 0 is bad, 100 is good
   2286      * {@hide}
   2287      */
   2288     public void reportInetCondition(int networkType, int percentage) {
   2289         try {
   2290             mService.reportInetCondition(networkType, percentage);
   2291         } catch (RemoteException e) {
   2292             throw e.rethrowFromSystemServer();
   2293         }
   2294     }
   2295 
   2296     /**
   2297      * Report a problem network to the framework.  This provides a hint to the system
   2298      * that there might be connectivity problems on this network and may cause
   2299      * the framework to re-evaluate network connectivity and/or switch to another
   2300      * network.
   2301      *
   2302      * @param network The {@link Network} the application was attempting to use
   2303      *                or {@code null} to indicate the current default network.
   2304      * @deprecated Use {@link #reportNetworkConnectivity} which allows reporting both
   2305      *             working and non-working connectivity.
   2306      */
   2307     @Deprecated
   2308     public void reportBadNetwork(Network network) {
   2309         try {
   2310             // One of these will be ignored because it matches system's current state.
   2311             // The other will trigger the necessary reevaluation.
   2312             mService.reportNetworkConnectivity(network, true);
   2313             mService.reportNetworkConnectivity(network, false);
   2314         } catch (RemoteException e) {
   2315             throw e.rethrowFromSystemServer();
   2316         }
   2317     }
   2318 
   2319     /**
   2320      * Report to the framework whether a network has working connectivity.
   2321      * This provides a hint to the system that a particular network is providing
   2322      * working connectivity or not.  In response the framework may re-evaluate
   2323      * the network's connectivity and might take further action thereafter.
   2324      *
   2325      * @param network The {@link Network} the application was attempting to use
   2326      *                or {@code null} to indicate the current default network.
   2327      * @param hasConnectivity {@code true} if the application was able to successfully access the
   2328      *                        Internet using {@code network} or {@code false} if not.
   2329      */
   2330     public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
   2331         try {
   2332             mService.reportNetworkConnectivity(network, hasConnectivity);
   2333         } catch (RemoteException e) {
   2334             throw e.rethrowFromSystemServer();
   2335         }
   2336     }
   2337 
   2338     /**
   2339      * Set a network-independent global http proxy.  This is not normally what you want
   2340      * for typical HTTP proxies - they are general network dependent.  However if you're
   2341      * doing something unusual like general internal filtering this may be useful.  On
   2342      * a private network where the proxy is not accessible, you may break HTTP using this.
   2343      *
   2344      * @param p A {@link ProxyInfo} object defining the new global
   2345      *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
   2346      * @hide
   2347      */
   2348     @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
   2349     public void setGlobalProxy(ProxyInfo p) {
   2350         try {
   2351             mService.setGlobalProxy(p);
   2352         } catch (RemoteException e) {
   2353             throw e.rethrowFromSystemServer();
   2354         }
   2355     }
   2356 
   2357     /**
   2358      * Retrieve any network-independent global HTTP proxy.
   2359      *
   2360      * @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
   2361      *        if no global HTTP proxy is set.
   2362      * @hide
   2363      */
   2364     public ProxyInfo getGlobalProxy() {
   2365         try {
   2366             return mService.getGlobalProxy();
   2367         } catch (RemoteException e) {
   2368             throw e.rethrowFromSystemServer();
   2369         }
   2370     }
   2371 
   2372     /**
   2373      * Retrieve the global HTTP proxy, or if no global HTTP proxy is set, a
   2374      * network-specific HTTP proxy.  If {@code network} is null, the
   2375      * network-specific proxy returned is the proxy of the default active
   2376      * network.
   2377      *
   2378      * @return {@link ProxyInfo} for the current global HTTP proxy, or if no
   2379      *         global HTTP proxy is set, {@code ProxyInfo} for {@code network},
   2380      *         or when {@code network} is {@code null},
   2381      *         the {@code ProxyInfo} for the default active network.  Returns
   2382      *         {@code null} when no proxy applies or the caller doesn't have
   2383      *         permission to use {@code network}.
   2384      * @hide
   2385      */
   2386     public ProxyInfo getProxyForNetwork(Network network) {
   2387         try {
   2388             return mService.getProxyForNetwork(network);
   2389         } catch (RemoteException e) {
   2390             throw e.rethrowFromSystemServer();
   2391         }
   2392     }
   2393 
   2394     /**
   2395      * Get the current default HTTP proxy settings.  If a global proxy is set it will be returned,
   2396      * otherwise if this process is bound to a {@link Network} using
   2397      * {@link #bindProcessToNetwork} then that {@code Network}'s proxy is returned, otherwise
   2398      * the default network's proxy is returned.
   2399      *
   2400      * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no
   2401      *        HTTP proxy is active.
   2402      */
   2403     public ProxyInfo getDefaultProxy() {
   2404         return getProxyForNetwork(getBoundNetworkForProcess());
   2405     }
   2406 
   2407     /**
   2408      * Returns true if the hardware supports the given network type
   2409      * else it returns false.  This doesn't indicate we have coverage
   2410      * or are authorized onto a network, just whether or not the
   2411      * hardware supports it.  For example a GSM phone without a SIM
   2412      * should still return {@code true} for mobile data, but a wifi only
   2413      * tablet would return {@code false}.
   2414      *
   2415      * @param networkType The network type we'd like to check
   2416      * @return {@code true} if supported, else {@code false}
   2417      *
   2418      * @hide
   2419      */
   2420     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   2421     public boolean isNetworkSupported(int networkType) {
   2422         try {
   2423             return mService.isNetworkSupported(networkType);
   2424         } catch (RemoteException e) {
   2425             throw e.rethrowFromSystemServer();
   2426         }
   2427     }
   2428 
   2429     /**
   2430      * Returns if the currently active data network is metered. A network is
   2431      * classified as metered when the user is sensitive to heavy data usage on
   2432      * that connection due to monetary costs, data limitations or
   2433      * battery/performance issues. You should check this before doing large
   2434      * data transfers, and warn the user or delay the operation until another
   2435      * network is available.
   2436      *
   2437      * @return {@code true} if large transfers should be avoided, otherwise
   2438      *        {@code false}.
   2439      */
   2440     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   2441     public boolean isActiveNetworkMetered() {
   2442         try {
   2443             return mService.isActiveNetworkMetered();
   2444         } catch (RemoteException e) {
   2445             throw e.rethrowFromSystemServer();
   2446         }
   2447     }
   2448 
   2449     /**
   2450      * If the LockdownVpn mechanism is enabled, updates the vpn
   2451      * with a reload of its profile.
   2452      *
   2453      * @return a boolean with {@code} indicating success
   2454      *
   2455      * <p>This method can only be called by the system UID
   2456      * {@hide}
   2457      */
   2458     public boolean updateLockdownVpn() {
   2459         try {
   2460             return mService.updateLockdownVpn();
   2461         } catch (RemoteException e) {
   2462             throw e.rethrowFromSystemServer();
   2463         }
   2464     }
   2465 
   2466     /**
   2467      * Check mobile provisioning.
   2468      *
   2469      * @param suggestedTimeOutMs, timeout in milliseconds
   2470      *
   2471      * @return time out that will be used, maybe less that suggestedTimeOutMs
   2472      * -1 if an error.
   2473      *
   2474      * {@hide}
   2475      */
   2476     public int checkMobileProvisioning(int suggestedTimeOutMs) {
   2477         int timeOutMs = -1;
   2478         try {
   2479             timeOutMs = mService.checkMobileProvisioning(suggestedTimeOutMs);
   2480         } catch (RemoteException e) {
   2481             throw e.rethrowFromSystemServer();
   2482         }
   2483         return timeOutMs;
   2484     }
   2485 
   2486     /**
   2487      * Get the mobile provisioning url.
   2488      * {@hide}
   2489      */
   2490     public String getMobileProvisioningUrl() {
   2491         try {
   2492             return mService.getMobileProvisioningUrl();
   2493         } catch (RemoteException e) {
   2494             throw e.rethrowFromSystemServer();
   2495         }
   2496     }
   2497 
   2498     /**
   2499      * Set sign in error notification to visible or in visible
   2500      *
   2501      * @param visible
   2502      * @param networkType
   2503      *
   2504      * {@hide}
   2505      * @deprecated Doesn't properly deal with multiple connected networks of the same type.
   2506      */
   2507     @Deprecated
   2508     public void setProvisioningNotificationVisible(boolean visible, int networkType,
   2509             String action) {
   2510         try {
   2511             mService.setProvisioningNotificationVisible(visible, networkType, action);
   2512         } catch (RemoteException e) {
   2513             throw e.rethrowFromSystemServer();
   2514         }
   2515     }
   2516 
   2517     /**
   2518      * Set the value for enabling/disabling airplane mode
   2519      *
   2520      * @param enable whether to enable airplane mode or not
   2521      *
   2522      * @hide
   2523      */
   2524     @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
   2525     public void setAirplaneMode(boolean enable) {
   2526         try {
   2527             mService.setAirplaneMode(enable);
   2528         } catch (RemoteException e) {
   2529             throw e.rethrowFromSystemServer();
   2530         }
   2531     }
   2532 
   2533     /** {@hide} */
   2534     public void registerNetworkFactory(Messenger messenger, String name) {
   2535         try {
   2536             mService.registerNetworkFactory(messenger, name);
   2537         } catch (RemoteException e) {
   2538             throw e.rethrowFromSystemServer();
   2539         }
   2540     }
   2541 
   2542     /** {@hide} */
   2543     public void unregisterNetworkFactory(Messenger messenger) {
   2544         try {
   2545             mService.unregisterNetworkFactory(messenger);
   2546         } catch (RemoteException e) {
   2547             throw e.rethrowFromSystemServer();
   2548         }
   2549     }
   2550 
   2551     /**
   2552      * @hide
   2553      * Register a NetworkAgent with ConnectivityService.
   2554      * @return NetID corresponding to NetworkAgent.
   2555      */
   2556     public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
   2557             NetworkCapabilities nc, int score, NetworkMisc misc) {
   2558         try {
   2559             return mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc);
   2560         } catch (RemoteException e) {
   2561             throw e.rethrowFromSystemServer();
   2562         }
   2563     }
   2564 
   2565     /**
   2566      * Base class for NetworkRequest callbacks.  Used for notifications about network
   2567      * changes.  Should be extended by applications wanting notifications.
   2568      */
   2569     public static class NetworkCallback {
   2570         /**
   2571          * Called when the framework connects to a new network to evaluate whether it satisfies this
   2572          * request. If evaluation succeeds, this callback may be followed by an {@link #onAvailable}
   2573          * callback. There is no guarantee that this new network will satisfy any requests, or that
   2574          * the network will stay connected for longer than the time necessary to evaluate it.
   2575          * <p>
   2576          * Most applications <b>should not</b> act on this callback, and should instead use
   2577          * {@link #onAvailable}. This callback is intended for use by applications that can assist
   2578          * the framework in properly evaluating the network &mdash; for example, an application that
   2579          * can automatically log in to a captive portal without user intervention.
   2580          *
   2581          * @param network The {@link Network} of the network that is being evaluated.
   2582          *
   2583          * @hide
   2584          */
   2585         public void onPreCheck(Network network) {}
   2586 
   2587         /**
   2588          * Called when the framework connects and has declared a new network ready for use.
   2589          * This callback may be called more than once if the {@link Network} that is
   2590          * satisfying the request changes.
   2591          *
   2592          * @param network The {@link Network} of the satisfying network.
   2593          */
   2594         public void onAvailable(Network network) {}
   2595 
   2596         /**
   2597          * Called when the network is about to be disconnected.  Often paired with an
   2598          * {@link NetworkCallback#onAvailable} call with the new replacement network
   2599          * for graceful handover.  This may not be called if we have a hard loss
   2600          * (loss without warning).  This may be followed by either a
   2601          * {@link NetworkCallback#onLost} call or a
   2602          * {@link NetworkCallback#onAvailable} call for this network depending
   2603          * on whether we lose or regain it.
   2604          *
   2605          * @param network The {@link Network} that is about to be disconnected.
   2606          * @param maxMsToLive The time in ms the framework will attempt to keep the
   2607          *                     network connected.  Note that the network may suffer a
   2608          *                     hard loss at any time.
   2609          */
   2610         public void onLosing(Network network, int maxMsToLive) {}
   2611 
   2612         /**
   2613          * Called when the framework has a hard loss of the network or when the
   2614          * graceful failure ends.
   2615          *
   2616          * @param network The {@link Network} lost.
   2617          */
   2618         public void onLost(Network network) {}
   2619 
   2620         /**
   2621          * Called if no network is found in the timeout time specified in
   2622          * {@link #requestNetwork(NetworkRequest, int, NetworkCallback)} call. This callback is not
   2623          * called for the version of {@link #requestNetwork(NetworkRequest, NetworkCallback)}
   2624          * without timeout. When this callback is invoked the associated
   2625          * {@link NetworkRequest} will have already been removed and released, as if
   2626          * {@link #unregisterNetworkCallback(NetworkCallback)} had been called.
   2627          */
   2628         public void onUnavailable() {}
   2629 
   2630         /**
   2631          * Called when the network the framework connected to for this request
   2632          * changes capabilities but still satisfies the stated need.
   2633          *
   2634          * @param network The {@link Network} whose capabilities have changed.
   2635          * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this network.
   2636          */
   2637         public void onCapabilitiesChanged(Network network,
   2638                 NetworkCapabilities networkCapabilities) {}
   2639 
   2640         /**
   2641          * Called when the network the framework connected to for this request
   2642          * changes {@link LinkProperties}.
   2643          *
   2644          * @param network The {@link Network} whose link properties have changed.
   2645          * @param linkProperties The new {@link LinkProperties} for this network.
   2646          */
   2647         public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {}
   2648 
   2649         /**
   2650          * Called when the network the framework connected to for this request
   2651          * goes into {@link NetworkInfo.DetailedState.SUSPENDED}.
   2652          * This generally means that while the TCP connections are still live,
   2653          * temporarily network data fails to transfer.  Specifically this is used
   2654          * on cellular networks to mask temporary outages when driving through
   2655          * a tunnel, etc.
   2656          * @hide
   2657          */
   2658         public void onNetworkSuspended(Network network) {}
   2659 
   2660         /**
   2661          * Called when the network the framework connected to for this request
   2662          * returns from a {@link NetworkInfo.DetailedState.SUSPENDED} state.
   2663          * This should always be preceeded by a matching {@code onNetworkSuspended}
   2664          * call.
   2665          * @hide
   2666          */
   2667         public void onNetworkResumed(Network network) {}
   2668 
   2669         private NetworkRequest networkRequest;
   2670     }
   2671 
   2672     private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER;
   2673     /** @hide */
   2674     public static final int CALLBACK_PRECHECK            = BASE + 1;
   2675     /** @hide */
   2676     public static final int CALLBACK_AVAILABLE           = BASE + 2;
   2677     /** @hide arg1 = TTL */
   2678     public static final int CALLBACK_LOSING              = BASE + 3;
   2679     /** @hide */
   2680     public static final int CALLBACK_LOST                = BASE + 4;
   2681     /** @hide */
   2682     public static final int CALLBACK_UNAVAIL             = BASE + 5;
   2683     /** @hide */
   2684     public static final int CALLBACK_CAP_CHANGED         = BASE + 6;
   2685     /** @hide */
   2686     public static final int CALLBACK_IP_CHANGED          = BASE + 7;
   2687     /** @hide */
   2688     public static final int CALLBACK_RELEASED            = BASE + 8;
   2689     // TODO: consider deleting CALLBACK_EXIT and shifting following enum codes down by 1.
   2690     /** @hide */
   2691     public static final int CALLBACK_EXIT                = BASE + 9;
   2692     /** @hide obj = NetworkCapabilities, arg1 = seq number */
   2693     private static final int EXPIRE_LEGACY_REQUEST       = BASE + 10;
   2694     /** @hide */
   2695     public static final int CALLBACK_SUSPENDED           = BASE + 11;
   2696     /** @hide */
   2697     public static final int CALLBACK_RESUMED             = BASE + 12;
   2698 
   2699     /** @hide */
   2700     public static String getCallbackName(int whichCallback) {
   2701         switch (whichCallback) {
   2702             case CALLBACK_PRECHECK:     return "CALLBACK_PRECHECK";
   2703             case CALLBACK_AVAILABLE:    return "CALLBACK_AVAILABLE";
   2704             case CALLBACK_LOSING:       return "CALLBACK_LOSING";
   2705             case CALLBACK_LOST:         return "CALLBACK_LOST";
   2706             case CALLBACK_UNAVAIL:      return "CALLBACK_UNAVAIL";
   2707             case CALLBACK_CAP_CHANGED:  return "CALLBACK_CAP_CHANGED";
   2708             case CALLBACK_IP_CHANGED:   return "CALLBACK_IP_CHANGED";
   2709             case CALLBACK_RELEASED:     return "CALLBACK_RELEASED";
   2710             case CALLBACK_EXIT:         return "CALLBACK_EXIT";
   2711             case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST";
   2712             case CALLBACK_SUSPENDED:    return "CALLBACK_SUSPENDED";
   2713             case CALLBACK_RESUMED:      return "CALLBACK_RESUMED";
   2714             default:
   2715                 return Integer.toString(whichCallback);
   2716         }
   2717     }
   2718 
   2719     private class CallbackHandler extends Handler {
   2720         private static final String TAG = "ConnectivityManager.CallbackHandler";
   2721         private static final boolean DBG = false;
   2722 
   2723         CallbackHandler(Looper looper) {
   2724             super(looper);
   2725         }
   2726 
   2727         CallbackHandler(Handler handler) {
   2728             this(handler.getLooper());
   2729         }
   2730 
   2731         @Override
   2732         public void handleMessage(Message message) {
   2733             NetworkRequest request = getObject(message, NetworkRequest.class);
   2734             Network network = getObject(message, Network.class);
   2735             if (DBG) {
   2736                 Log.d(TAG, whatToString(message.what) + " for network " + network);
   2737             }
   2738             switch (message.what) {
   2739                 case CALLBACK_PRECHECK: {
   2740                     NetworkCallback callback = getCallback(request, "PRECHECK");
   2741                     if (callback != null) {
   2742                         callback.onPreCheck(network);
   2743                     }
   2744                     break;
   2745                 }
   2746                 case CALLBACK_AVAILABLE: {
   2747                     NetworkCallback callback = getCallback(request, "AVAILABLE");
   2748                     if (callback != null) {
   2749                         callback.onAvailable(network);
   2750                     }
   2751                     break;
   2752                 }
   2753                 case CALLBACK_LOSING: {
   2754                     NetworkCallback callback = getCallback(request, "LOSING");
   2755                     if (callback != null) {
   2756                         callback.onLosing(network, message.arg1);
   2757                     }
   2758                     break;
   2759                 }
   2760                 case CALLBACK_LOST: {
   2761                     NetworkCallback callback = getCallback(request, "LOST");
   2762                     if (callback != null) {
   2763                         callback.onLost(network);
   2764                     }
   2765                     break;
   2766                 }
   2767                 case CALLBACK_UNAVAIL: {
   2768                     NetworkCallback callback = getCallback(request, "UNAVAIL");
   2769                     if (callback != null) {
   2770                         callback.onUnavailable();
   2771                     }
   2772                     break;
   2773                 }
   2774                 case CALLBACK_CAP_CHANGED: {
   2775                     NetworkCallback callback = getCallback(request, "CAP_CHANGED");
   2776                     if (callback != null) {
   2777                         NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
   2778                         callback.onCapabilitiesChanged(network, cap);
   2779                     }
   2780                     break;
   2781                 }
   2782                 case CALLBACK_IP_CHANGED: {
   2783                     NetworkCallback callback = getCallback(request, "IP_CHANGED");
   2784                     if (callback != null) {
   2785                         LinkProperties lp = getObject(message, LinkProperties.class);
   2786                         callback.onLinkPropertiesChanged(network, lp);
   2787                     }
   2788                     break;
   2789                 }
   2790                 case CALLBACK_SUSPENDED: {
   2791                     NetworkCallback callback = getCallback(request, "SUSPENDED");
   2792                     if (callback != null) {
   2793                         callback.onNetworkSuspended(network);
   2794                     }
   2795                     break;
   2796                 }
   2797                 case CALLBACK_RESUMED: {
   2798                     NetworkCallback callback = getCallback(request, "RESUMED");
   2799                     if (callback != null) {
   2800                         callback.onNetworkResumed(network);
   2801                     }
   2802                     break;
   2803                 }
   2804                 case CALLBACK_RELEASED: {
   2805                     final NetworkCallback callback;
   2806                     synchronized(sCallbacks) {
   2807                         callback = sCallbacks.remove(request);
   2808                     }
   2809                     if (callback == null) {
   2810                         Log.e(TAG, "callback not found for RELEASED message");
   2811                     }
   2812                     break;
   2813                 }
   2814                 case CALLBACK_EXIT: {
   2815                     break;
   2816                 }
   2817                 case EXPIRE_LEGACY_REQUEST: {
   2818                     expireRequest((NetworkCapabilities)message.obj, message.arg1);
   2819                     break;
   2820                 }
   2821             }
   2822         }
   2823 
   2824         private <T> T getObject(Message msg, Class<T> c) {
   2825             return (T) msg.getData().getParcelable(c.getSimpleName());
   2826         }
   2827 
   2828         private NetworkCallback getCallback(NetworkRequest req, String name) {
   2829             NetworkCallback callback;
   2830             synchronized(sCallbacks) {
   2831                 callback = sCallbacks.get(req);
   2832             }
   2833             if (callback == null) {
   2834                 Log.e(TAG, "callback not found for " + name + " message");
   2835             }
   2836             return callback;
   2837         }
   2838     }
   2839 
   2840     private CallbackHandler getDefaultHandler() {
   2841         synchronized (sCallbacks) {
   2842             if (sCallbackHandler == null) {
   2843                 sCallbackHandler = new CallbackHandler(ConnectivityThread.getInstanceLooper());
   2844             }
   2845             return sCallbackHandler;
   2846         }
   2847     }
   2848 
   2849     private static final HashMap<NetworkRequest, NetworkCallback> sCallbacks = new HashMap<>();
   2850     private static CallbackHandler sCallbackHandler;
   2851 
   2852     private static final int LISTEN  = 1;
   2853     private static final int REQUEST = 2;
   2854 
   2855     private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, NetworkCallback callback,
   2856             int timeoutMs, int action, int legacyType, CallbackHandler handler) {
   2857         if (callback == null) {
   2858             throw new IllegalArgumentException("null NetworkCallback");
   2859         }
   2860         if (need == null && action != REQUEST) {
   2861             throw new IllegalArgumentException("null NetworkCapabilities");
   2862         }
   2863         // TODO: throw an exception if callback.networkRequest is not null.
   2864         // http://b/20701525
   2865         final NetworkRequest request;
   2866         try {
   2867             synchronized(sCallbacks) {
   2868                 Messenger messenger = new Messenger(handler);
   2869                 Binder binder = new Binder();
   2870                 if (action == LISTEN) {
   2871                     request = mService.listenForNetwork(need, messenger, binder);
   2872                 } else {
   2873                     request = mService.requestNetwork(
   2874                             need, messenger, timeoutMs, binder, legacyType);
   2875                 }
   2876                 if (request != null) {
   2877                     sCallbacks.put(request, callback);
   2878                 }
   2879                 callback.networkRequest = request;
   2880             }
   2881         } catch (RemoteException e) {
   2882             throw e.rethrowFromSystemServer();
   2883         }
   2884         return request;
   2885     }
   2886 
   2887     /**
   2888      * Helper function to request a network with a particular legacy type.
   2889      *
   2890      * This is temporarily public @hide so it can be called by system code that uses the
   2891      * NetworkRequest API to request networks but relies on CONNECTIVITY_ACTION broadcasts for
   2892      * instead network notifications.
   2893      *
   2894      * TODO: update said system code to rely on NetworkCallbacks and make this method private.
   2895      *
   2896      * @hide
   2897      */
   2898     public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
   2899             int timeoutMs, int legacyType, Handler handler) {
   2900         CallbackHandler cbHandler = new CallbackHandler(handler);
   2901         NetworkCapabilities nc = request.networkCapabilities;
   2902         sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, legacyType, cbHandler);
   2903     }
   2904 
   2905     /**
   2906      * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
   2907      *
   2908      * This {@link NetworkRequest} will live until released via
   2909      * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits. A
   2910      * version of the method which takes a timeout is
   2911      * {@link #requestNetwork(NetworkRequest, int, NetworkCallback)}.
   2912      * Status of the request can be followed by listening to the various
   2913      * callbacks described in {@link NetworkCallback}.  The {@link Network}
   2914      * can be used to direct traffic to the network.
   2915      * <p>It is presently unsupported to request a network with mutable
   2916      * {@link NetworkCapabilities} such as
   2917      * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
   2918      * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
   2919      * as these {@code NetworkCapabilities} represent states that a particular
   2920      * network may never attain, and whether a network will attain these states
   2921      * is unknown prior to bringing up the network so the framework does not
   2922      * know how to go about satisfing a request with these capabilities.
   2923      *
   2924      * <p>This method requires the caller to hold either the
   2925      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
   2926      * or the ability to modify system settings as determined by
   2927      * {@link android.provider.Settings.System#canWrite}.</p>
   2928      *
   2929      * @param request {@link NetworkRequest} describing this request.
   2930      * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
   2931      *                        the callback must not be shared - it uniquely specifies this request.
   2932      *                        The callback is invoked on the default internal Handler.
   2933      * @throws IllegalArgumentException if {@code request} specifies any mutable
   2934      *         {@code NetworkCapabilities}.
   2935      */
   2936     public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) {
   2937         requestNetwork(request, networkCallback, getDefaultHandler());
   2938     }
   2939 
   2940     /**
   2941      * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
   2942      *
   2943      * This {@link NetworkRequest} will live until released via
   2944      * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits. A
   2945      * version of the method which takes a timeout is
   2946      * {@link #requestNetwork(NetworkRequest, int, NetworkCallback)}.
   2947      * Status of the request can be followed by listening to the various
   2948      * callbacks described in {@link NetworkCallback}.  The {@link Network}
   2949      * can be used to direct traffic to the network.
   2950      * <p>It is presently unsupported to request a network with mutable
   2951      * {@link NetworkCapabilities} such as
   2952      * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
   2953      * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
   2954      * as these {@code NetworkCapabilities} represent states that a particular
   2955      * network may never attain, and whether a network will attain these states
   2956      * is unknown prior to bringing up the network so the framework does not
   2957      * know how to go about satisfing a request with these capabilities.
   2958      *
   2959      * <p>This method requires the caller to hold either the
   2960      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
   2961      * or the ability to modify system settings as determined by
   2962      * {@link android.provider.Settings.System#canWrite}.</p>
   2963      *
   2964      * @param request {@link NetworkRequest} describing this request.
   2965      * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
   2966      *                        the callback must not be shared - it uniquely specifies this request.
   2967      * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
   2968      * @throws IllegalArgumentException if {@code request} specifies any mutable
   2969      *         {@code NetworkCapabilities}.
   2970      */
   2971     public void requestNetwork(
   2972             NetworkRequest request, NetworkCallback networkCallback, Handler handler) {
   2973         int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
   2974         CallbackHandler cbHandler = new CallbackHandler(handler);
   2975         requestNetwork(request, networkCallback, 0, legacyType, cbHandler);
   2976     }
   2977 
   2978     /**
   2979      * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
   2980      * by a timeout.
   2981      *
   2982      * This function behaves identically to the non-timed-out version
   2983      * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, but if a suitable network
   2984      * is not found within the given time (in milliseconds) the
   2985      * {@link NetworkCallback#onUnavailable()} callback is called. The request can still be
   2986      * released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)} but does
   2987      * not have to be released if timed-out (it is automatically released). Unregistering a
   2988      * request that timed out is not an error.
   2989      *
   2990      * <p>Do not use this method to poll for the existence of specific networks (e.g. with a small
   2991      * timeout) - {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} is provided
   2992      * for that purpose. Calling this method will attempt to bring up the requested network.
   2993      *
   2994      * <p>This method requires the caller to hold either the
   2995      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
   2996      * or the ability to modify system settings as determined by
   2997      * {@link android.provider.Settings.System#canWrite}.</p>
   2998      *
   2999      * @param request {@link NetworkRequest} describing this request.
   3000      * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
   3001      *                        the callback must not be shared - it uniquely specifies this request.
   3002      * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
   3003      *                  before {@link NetworkCallback#onUnavailable()} is called. The timeout must
   3004      *                  be a positive value (i.e. >0).
   3005      */
   3006     public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
   3007             int timeoutMs) {
   3008         if (timeoutMs <= 0) {
   3009             throw new IllegalArgumentException("Non-positive timeoutMs: " + timeoutMs);
   3010         }
   3011         int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
   3012         requestNetwork(request, networkCallback, timeoutMs, legacyType, getDefaultHandler());
   3013     }
   3014 
   3015 
   3016     /**
   3017      * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
   3018      * by a timeout.
   3019      *
   3020      * This function behaves identically to the non-timedout version, but if a suitable
   3021      * network is not found within the given time (in milliseconds) the
   3022      * {@link NetworkCallback#onUnavailable} callback is called. The request can still be
   3023      * released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)} but does
   3024      * not have to be released if timed-out (it is automatically released). Unregistering a
   3025      * request that timed out is not an error.
   3026      *
   3027      * <p>Do not use this method to poll for the existence of specific networks (e.g. with a small
   3028      * timeout) - {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} is provided
   3029      * for that purpose. Calling this method will attempt to bring up the requested network.
   3030      *
   3031      * <p>This method requires the caller to hold either the
   3032      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
   3033      * or the ability to modify system settings as determined by
   3034      * {@link android.provider.Settings.System#canWrite}.</p>
   3035      *
   3036      * @param request {@link NetworkRequest} describing this request.
   3037      * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
   3038      *                        the callback must not be shared - it uniquely specifies this request.
   3039      * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
   3040      * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
   3041      *                  before {@link NetworkCallback#onUnavailable} is called.
   3042      */
   3043     public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
   3044             Handler handler, int timeoutMs) {
   3045         if (timeoutMs <= 0) {
   3046             throw new IllegalArgumentException("Non-positive timeoutMs");
   3047         }
   3048         int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
   3049         CallbackHandler cbHandler = new CallbackHandler(handler);
   3050         requestNetwork(request, networkCallback, timeoutMs, legacyType, cbHandler);
   3051     }
   3052 
   3053     /**
   3054      * The lookup key for a {@link Network} object included with the intent after
   3055      * successfully finding a network for the applications request.  Retrieve it with
   3056      * {@link android.content.Intent#getParcelableExtra(String)}.
   3057      * <p>
   3058      * Note that if you intend to invoke {@link Network#openConnection(java.net.URL)}
   3059      * then you must get a ConnectivityManager instance before doing so.
   3060      */
   3061     public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
   3062 
   3063     /**
   3064      * The lookup key for a {@link NetworkRequest} object included with the intent after
   3065      * successfully finding a network for the applications request.  Retrieve it with
   3066      * {@link android.content.Intent#getParcelableExtra(String)}.
   3067      */
   3068     public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
   3069 
   3070 
   3071     /**
   3072      * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
   3073      *
   3074      * This function behaves identically to the version that takes a NetworkCallback, but instead
   3075      * of {@link NetworkCallback} a {@link PendingIntent} is used.  This means
   3076      * the request may outlive the calling application and get called back when a suitable
   3077      * network is found.
   3078      * <p>
   3079      * The operation is an Intent broadcast that goes to a broadcast receiver that
   3080      * you registered with {@link Context#registerReceiver} or through the
   3081      * &lt;receiver&gt; tag in an AndroidManifest.xml file
   3082      * <p>
   3083      * The operation Intent is delivered with two extras, a {@link Network} typed
   3084      * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest}
   3085      * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing
   3086      * the original requests parameters.  It is important to create a new,
   3087      * {@link NetworkCallback} based request before completing the processing of the
   3088      * Intent to reserve the network or it will be released shortly after the Intent
   3089      * is processed.
   3090      * <p>
   3091      * If there is already a request for this Intent registered (with the equality of
   3092      * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
   3093      * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
   3094      * <p>
   3095      * The request may be released normally by calling
   3096      * {@link #releaseNetworkRequest(android.app.PendingIntent)}.
   3097      * <p>It is presently unsupported to request a network with either
   3098      * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
   3099      * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
   3100      * as these {@code NetworkCapabilities} represent states that a particular
   3101      * network may never attain, and whether a network will attain these states
   3102      * is unknown prior to bringing up the network so the framework does not
   3103      * know how to go about satisfing a request with these capabilities.
   3104      *
   3105      * <p>This method requires the caller to hold either the
   3106      * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
   3107      * or the ability to modify system settings as determined by
   3108      * {@link android.provider.Settings.System#canWrite}.</p>
   3109      *
   3110      * @param request {@link NetworkRequest} describing this request.
   3111      * @param operation Action to perform when the network is available (corresponds
   3112      *                  to the {@link NetworkCallback#onAvailable} call.  Typically
   3113      *                  comes from {@link PendingIntent#getBroadcast}. Cannot be null.
   3114      * @throws IllegalArgumentException if {@code request} contains either
   3115      *         {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
   3116      *         {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}.
   3117      */
   3118     public void requestNetwork(NetworkRequest request, PendingIntent operation) {
   3119         checkPendingIntent(operation);
   3120         try {
   3121             mService.pendingRequestForNetwork(request.networkCapabilities, operation);
   3122         } catch (RemoteException e) {
   3123             throw e.rethrowFromSystemServer();
   3124         }
   3125     }
   3126 
   3127     /**
   3128      * Removes a request made via {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)}
   3129      * <p>
   3130      * This method has the same behavior as
   3131      * {@link #unregisterNetworkCallback(android.app.PendingIntent)} with respect to
   3132      * releasing network resources and disconnecting.
   3133      *
   3134      * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the
   3135      *                  PendingIntent passed to
   3136      *                  {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)} with the
   3137      *                  corresponding NetworkRequest you'd like to remove. Cannot be null.
   3138      */
   3139     public void releaseNetworkRequest(PendingIntent operation) {
   3140         checkPendingIntent(operation);
   3141         try {
   3142             mService.releasePendingNetworkRequest(operation);
   3143         } catch (RemoteException e) {
   3144             throw e.rethrowFromSystemServer();
   3145         }
   3146     }
   3147 
   3148     private void checkPendingIntent(PendingIntent intent) {
   3149         if (intent == null) {
   3150             throw new IllegalArgumentException("PendingIntent cannot be null.");
   3151         }
   3152     }
   3153 
   3154     /**
   3155      * Registers to receive notifications about all networks which satisfy the given
   3156      * {@link NetworkRequest}.  The callbacks will continue to be called until
   3157      * either the application exits or link #unregisterNetworkCallback(NetworkCallback)} is called.
   3158      *
   3159      * @param request {@link NetworkRequest} describing this request.
   3160      * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
   3161      *                        networks change state.
   3162      *                        The callback is invoked on the default internal Handler.
   3163      */
   3164     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   3165     public void registerNetworkCallback(NetworkRequest request, NetworkCallback networkCallback) {
   3166         registerNetworkCallback(request, networkCallback, getDefaultHandler());
   3167     }
   3168 
   3169     /**
   3170      * Registers to receive notifications about all networks which satisfy the given
   3171      * {@link NetworkRequest}.  The callbacks will continue to be called until
   3172      * either the application exits or link #unregisterNetworkCallback(NetworkCallback)} is called.
   3173      *
   3174      * @param request {@link NetworkRequest} describing this request.
   3175      * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
   3176      *                        networks change state.
   3177      * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
   3178      */
   3179     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   3180     public void registerNetworkCallback(
   3181             NetworkRequest request, NetworkCallback networkCallback, Handler handler) {
   3182         CallbackHandler cbHandler = new CallbackHandler(handler);
   3183         NetworkCapabilities nc = request.networkCapabilities;
   3184         sendRequestForNetwork(nc, networkCallback, 0, LISTEN, TYPE_NONE, cbHandler);
   3185     }
   3186 
   3187     /**
   3188      * Registers a PendingIntent to be sent when a network is available which satisfies the given
   3189      * {@link NetworkRequest}.
   3190      *
   3191      * This function behaves identically to the version that takes a NetworkCallback, but instead
   3192      * of {@link NetworkCallback} a {@link PendingIntent} is used.  This means
   3193      * the request may outlive the calling application and get called back when a suitable
   3194      * network is found.
   3195      * <p>
   3196      * The operation is an Intent broadcast that goes to a broadcast receiver that
   3197      * you registered with {@link Context#registerReceiver} or through the
   3198      * &lt;receiver&gt; tag in an AndroidManifest.xml file
   3199      * <p>
   3200      * The operation Intent is delivered with two extras, a {@link Network} typed
   3201      * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest}
   3202      * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing
   3203      * the original requests parameters.
   3204      * <p>
   3205      * If there is already a request for this Intent registered (with the equality of
   3206      * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
   3207      * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
   3208      * <p>
   3209      * The request may be released normally by calling
   3210      * {@link #unregisterNetworkCallback(android.app.PendingIntent)}.
   3211      * @param request {@link NetworkRequest} describing this request.
   3212      * @param operation Action to perform when the network is available (corresponds
   3213      *                  to the {@link NetworkCallback#onAvailable} call.  Typically
   3214      *                  comes from {@link PendingIntent#getBroadcast}. Cannot be null.
   3215      */
   3216     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   3217     public void registerNetworkCallback(NetworkRequest request, PendingIntent operation) {
   3218         checkPendingIntent(operation);
   3219         try {
   3220             mService.pendingListenForNetwork(request.networkCapabilities, operation);
   3221         } catch (RemoteException e) {
   3222             throw e.rethrowFromSystemServer();
   3223         }
   3224     }
   3225 
   3226     /**
   3227      * Registers to receive notifications about changes in the system default network. The callbacks
   3228      * will continue to be called until either the application exits or
   3229      * {@link #unregisterNetworkCallback(NetworkCallback)} is called.
   3230      *
   3231      * @param networkCallback The {@link NetworkCallback} that the system will call as the
   3232      *                        system default network changes.
   3233      *                        The callback is invoked on the default internal Handler.
   3234      */
   3235     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   3236     public void registerDefaultNetworkCallback(NetworkCallback networkCallback) {
   3237         registerDefaultNetworkCallback(networkCallback, getDefaultHandler());
   3238     }
   3239 
   3240     /**
   3241      * Registers to receive notifications about changes in the system default network. The callbacks
   3242      * will continue to be called until either the application exits or
   3243      * {@link #unregisterNetworkCallback(NetworkCallback)} is called.
   3244      *
   3245      * @param networkCallback The {@link NetworkCallback} that the system will call as the
   3246      *                        system default network changes.
   3247      * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
   3248      */
   3249     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   3250     public void registerDefaultNetworkCallback(NetworkCallback networkCallback, Handler handler) {
   3251         // This works because if the NetworkCapabilities are null,
   3252         // ConnectivityService takes them from the default request.
   3253         //
   3254         // Since the capabilities are exactly the same as the default request's
   3255         // capabilities, this request is guaranteed, at all times, to be
   3256         // satisfied by the same network, if any, that satisfies the default
   3257         // request, i.e., the system default network.
   3258         CallbackHandler cbHandler = new CallbackHandler(handler);
   3259         sendRequestForNetwork(null, networkCallback, 0, REQUEST, TYPE_NONE, cbHandler);
   3260     }
   3261 
   3262     /**
   3263      * Requests bandwidth update for a given {@link Network} and returns whether the update request
   3264      * is accepted by ConnectivityService. Once accepted, ConnectivityService will poll underlying
   3265      * network connection for updated bandwidth information. The caller will be notified via
   3266      * {@link ConnectivityManager.NetworkCallback} if there is an update. Notice that this
   3267      * method assumes that the caller has previously called
   3268      * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} to listen for network
   3269      * changes.
   3270      *
   3271      * @param network {@link Network} specifying which network you're interested.
   3272      * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
   3273      */
   3274     public boolean requestBandwidthUpdate(Network network) {
   3275         try {
   3276             return mService.requestBandwidthUpdate(network);
   3277         } catch (RemoteException e) {
   3278             throw e.rethrowFromSystemServer();
   3279         }
   3280     }
   3281 
   3282     /**
   3283      * Unregisters callbacks about and possibly releases networks originating from
   3284      * {@link #requestNetwork(NetworkRequest, NetworkCallback)} and
   3285      * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} calls.
   3286      * If the given {@code NetworkCallback} had previously been used with
   3287      * {@code #requestNetwork}, any networks that had been connected to only to satisfy that request
   3288      * will be disconnected.
   3289      *
   3290      * @param networkCallback The {@link NetworkCallback} used when making the request.
   3291      */
   3292     public void unregisterNetworkCallback(NetworkCallback networkCallback) {
   3293         if (networkCallback == null || networkCallback.networkRequest == null ||
   3294                 networkCallback.networkRequest.requestId == REQUEST_ID_UNSET) {
   3295             throw new IllegalArgumentException("Invalid NetworkCallback");
   3296         }
   3297         try {
   3298             // CallbackHandler will release callback when receiving CALLBACK_RELEASED.
   3299             mService.releaseNetworkRequest(networkCallback.networkRequest);
   3300         } catch (RemoteException e) {
   3301             throw e.rethrowFromSystemServer();
   3302         }
   3303     }
   3304 
   3305     /**
   3306      * Unregisters a callback previously registered via
   3307      * {@link #registerNetworkCallback(NetworkRequest, android.app.PendingIntent)}.
   3308      *
   3309      * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the
   3310      *                  PendingIntent passed to
   3311      *                  {@link #registerNetworkCallback(NetworkRequest, android.app.PendingIntent)}.
   3312      *                  Cannot be null.
   3313      */
   3314     public void unregisterNetworkCallback(PendingIntent operation) {
   3315         releaseNetworkRequest(operation);
   3316     }
   3317 
   3318     /**
   3319      * Informs the system whether it should switch to {@code network} regardless of whether it is
   3320      * validated or not. If {@code accept} is true, and the network was explicitly selected by the
   3321      * user (e.g., by selecting a Wi-Fi network in the Settings app), then the network will become
   3322      * the system default network regardless of any other network that's currently connected. If
   3323      * {@code always} is true, then the choice is remembered, so that the next time the user
   3324      * connects to this network, the system will switch to it.
   3325      *
   3326      * @param network The network to accept.
   3327      * @param accept Whether to accept the network even if unvalidated.
   3328      * @param always Whether to remember this choice in the future.
   3329      *
   3330      * @hide
   3331      */
   3332     @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
   3333     public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
   3334         try {
   3335             mService.setAcceptUnvalidated(network, accept, always);
   3336         } catch (RemoteException e) {
   3337             throw e.rethrowFromSystemServer();
   3338         }
   3339     }
   3340 
   3341     /**
   3342      * Informs the system to penalize {@code network}'s score when it becomes unvalidated. This is
   3343      * only meaningful if the system is configured not to penalize such networks, e.g., if the
   3344      * {@code config_networkAvoidBadWifi} configuration variable is set to 0 and the {@code
   3345      * NETWORK_AVOID_BAD_WIFI setting is unset}.
   3346      *
   3347      * @param network The network to accept.
   3348      *
   3349      * @hide
   3350      */
   3351     @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
   3352     public void setAvoidUnvalidated(Network network) {
   3353         try {
   3354             mService.setAvoidUnvalidated(network);
   3355         } catch (RemoteException e) {
   3356             throw e.rethrowFromSystemServer();
   3357         }
   3358     }
   3359 
   3360     /**
   3361      * Requests that the system open the captive portal app on the specified network.
   3362      *
   3363      * @param network The network to log into.
   3364      *
   3365      * @hide
   3366      */
   3367     @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
   3368     public void startCaptivePortalApp(Network network) {
   3369         try {
   3370             mService.startCaptivePortalApp(network);
   3371         } catch (RemoteException e) {
   3372             throw e.rethrowFromSystemServer();
   3373         }
   3374     }
   3375 
   3376     /**
   3377      * It is acceptable to briefly use multipath data to provide seamless connectivity for
   3378      * time-sensitive user-facing operations when the system default network is temporarily
   3379      * unresponsive. The amount of data should be limited (less than one megabyte for every call to
   3380      * this method), and the operation should be infrequent to ensure that data usage is limited.
   3381      *
   3382      * An example of such an operation might be a time-sensitive foreground activity, such as a
   3383      * voice command, that the user is performing while walking out of range of a Wi-Fi network.
   3384      */
   3385     public static final int MULTIPATH_PREFERENCE_HANDOVER = 1 << 0;
   3386 
   3387     /**
   3388      * It is acceptable to use small amounts of multipath data on an ongoing basis to provide
   3389      * a backup channel for traffic that is primarily going over another network.
   3390      *
   3391      * An example might be maintaining backup connections to peers or servers for the purpose of
   3392      * fast fallback if the default network is temporarily unresponsive or disconnects. The traffic
   3393      * on backup paths should be negligible compared to the traffic on the main path.
   3394      */
   3395     public static final int MULTIPATH_PREFERENCE_RELIABILITY = 1 << 1;
   3396 
   3397     /**
   3398      * It is acceptable to use metered data to improve network latency and performance.
   3399      */
   3400     public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 1 << 2;
   3401 
   3402     /**
   3403      * Return value to use for unmetered networks. On such networks we currently set all the flags
   3404      * to true.
   3405      * @hide
   3406      */
   3407     public static final int MULTIPATH_PREFERENCE_UNMETERED =
   3408             MULTIPATH_PREFERENCE_HANDOVER |
   3409             MULTIPATH_PREFERENCE_RELIABILITY |
   3410             MULTIPATH_PREFERENCE_PERFORMANCE;
   3411 
   3412     /** @hide */
   3413     @Retention(RetentionPolicy.SOURCE)
   3414     @IntDef(flag = true, value = {
   3415             MULTIPATH_PREFERENCE_HANDOVER,
   3416             MULTIPATH_PREFERENCE_RELIABILITY,
   3417             MULTIPATH_PREFERENCE_PERFORMANCE,
   3418     })
   3419     public @interface MultipathPreference {
   3420     }
   3421 
   3422     /**
   3423      * Provides a hint to the calling application on whether it is desirable to use the
   3424      * multinetwork APIs (e.g., {@link Network#openConnection}, {@link Network#bindSocket}, etc.)
   3425      * for multipath data transfer on this network when it is not the system default network.
   3426      * Applications desiring to use multipath network protocols should call this method before
   3427      * each such operation.
   3428      *
   3429      * @param network The network on which the application desires to use multipath data.
   3430      *                If {@code null}, this method will return the a preference that will generally
   3431      *                apply to metered networks.
   3432      * @return a bitwise OR of zero or more of the  {@code MULTIPATH_PREFERENCE_*} constants.
   3433      */
   3434     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
   3435     public @MultipathPreference int getMultipathPreference(Network network) {
   3436         try {
   3437             return mService.getMultipathPreference(network);
   3438         } catch (RemoteException e) {
   3439             throw e.rethrowFromSystemServer();
   3440         }
   3441     }
   3442 
   3443     /**
   3444      * Resets all connectivity manager settings back to factory defaults.
   3445      * @hide
   3446      */
   3447     public void factoryReset() {
   3448         try {
   3449             mService.factoryReset();
   3450         } catch (RemoteException e) {
   3451             throw e.rethrowFromSystemServer();
   3452         }
   3453     }
   3454 
   3455     /**
   3456      * Binds the current process to {@code network}.  All Sockets created in the future
   3457      * (and not explicitly bound via a bound SocketFactory from
   3458      * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
   3459      * {@code network}.  All host name resolutions will be limited to {@code network} as well.
   3460      * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
   3461      * work and all host name resolutions will fail.  This is by design so an application doesn't
   3462      * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
   3463      * To clear binding pass {@code null} for {@code network}.  Using individually bound
   3464      * Sockets created by Network.getSocketFactory().createSocket() and
   3465      * performing network-specific host name resolutions via
   3466      * {@link Network#getAllByName Network.getAllByName} is preferred to calling
   3467      * {@code bindProcessToNetwork}.
   3468      *
   3469      * @param network The {@link Network} to bind the current process to, or {@code null} to clear
   3470      *                the current binding.
   3471      * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
   3472      */
   3473     public boolean bindProcessToNetwork(Network network) {
   3474         // Forcing callers to call thru non-static function ensures ConnectivityManager
   3475         // instantiated.
   3476         return setProcessDefaultNetwork(network);
   3477     }
   3478 
   3479     /**
   3480      * Binds the current process to {@code network}.  All Sockets created in the future
   3481      * (and not explicitly bound via a bound SocketFactory from
   3482      * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
   3483      * {@code network}.  All host name resolutions will be limited to {@code network} as well.
   3484      * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
   3485      * work and all host name resolutions will fail.  This is by design so an application doesn't
   3486      * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
   3487      * To clear binding pass {@code null} for {@code network}.  Using individually bound
   3488      * Sockets created by Network.getSocketFactory().createSocket() and
   3489      * performing network-specific host name resolutions via
   3490      * {@link Network#getAllByName Network.getAllByName} is preferred to calling
   3491      * {@code setProcessDefaultNetwork}.
   3492      *
   3493      * @param network The {@link Network} to bind the current process to, or {@code null} to clear
   3494      *                the current binding.
   3495      * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
   3496      * @deprecated This function can throw {@link IllegalStateException}.  Use
   3497      *             {@link #bindProcessToNetwork} instead.  {@code bindProcessToNetwork}
   3498      *             is a direct replacement.
   3499      */
   3500     @Deprecated
   3501     public static boolean setProcessDefaultNetwork(Network network) {
   3502         int netId = (network == null) ? NETID_UNSET : network.netId;
   3503         if (netId == NetworkUtils.getBoundNetworkForProcess()) {
   3504             return true;
   3505         }
   3506         if (NetworkUtils.bindProcessToNetwork(netId)) {
   3507             // Set HTTP proxy system properties to match network.
   3508             // TODO: Deprecate this static method and replace it with a non-static version.
   3509             try {
   3510                 Proxy.setHttpProxySystemProperty(getInstance().getDefaultProxy());
   3511             } catch (SecurityException e) {
   3512                 // The process doesn't have ACCESS_NETWORK_STATE, so we can't fetch the proxy.
   3513                 Log.e(TAG, "Can't set proxy properties", e);
   3514             }
   3515             // Must flush DNS cache as new network may have different DNS resolutions.
   3516             InetAddress.clearDnsCache();
   3517             // Must flush socket pool as idle sockets will be bound to previous network and may
   3518             // cause subsequent fetches to be performed on old network.
   3519             NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
   3520             return true;
   3521         } else {
   3522             return false;
   3523         }
   3524     }
   3525 
   3526     /**
   3527      * Returns the {@link Network} currently bound to this process via
   3528      * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
   3529      *
   3530      * @return {@code Network} to which this process is bound, or {@code null}.
   3531      */
   3532     public Network getBoundNetworkForProcess() {
   3533         // Forcing callers to call thru non-static function ensures ConnectivityManager
   3534         // instantiated.
   3535         return getProcessDefaultNetwork();
   3536     }
   3537 
   3538     /**
   3539      * Returns the {@link Network} currently bound to this process via
   3540      * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
   3541      *
   3542      * @return {@code Network} to which this process is bound, or {@code null}.
   3543      * @deprecated Using this function can lead to other functions throwing
   3544      *             {@link IllegalStateException}.  Use {@link #getBoundNetworkForProcess} instead.
   3545      *             {@code getBoundNetworkForProcess} is a direct replacement.
   3546      */
   3547     @Deprecated
   3548     public static Network getProcessDefaultNetwork() {
   3549         int netId = NetworkUtils.getBoundNetworkForProcess();
   3550         if (netId == NETID_UNSET) return null;
   3551         return new Network(netId);
   3552     }
   3553 
   3554     private void unsupportedStartingFrom(int version) {
   3555         if (Process.myUid() == Process.SYSTEM_UID) {
   3556             // The getApplicationInfo() call we make below is not supported in system context, and
   3557             // we want to allow the system to use these APIs anyway.
   3558             return;
   3559         }
   3560 
   3561         if (mContext.getApplicationInfo().targetSdkVersion >= version) {
   3562             throw new UnsupportedOperationException(
   3563                     "This method is not supported in target SDK version " + version + " and above");
   3564         }
   3565     }
   3566 
   3567     // Checks whether the calling app can use the legacy routing API (startUsingNetworkFeature,
   3568     // stopUsingNetworkFeature, requestRouteToHost), and if not throw UnsupportedOperationException.
   3569     // TODO: convert the existing system users (Tethering, GnssLocationProvider) to the new APIs and
   3570     // remove these exemptions. Note that this check is not secure, and apps can still access these
   3571     // functions by accessing ConnectivityService directly. However, it should be clear that doing
   3572     // so is unsupported and may break in the future. http://b/22728205
   3573     private void checkLegacyRoutingApiAccess() {
   3574         if (mContext.checkCallingOrSelfPermission("com.android.permission.INJECT_OMADM_SETTINGS")
   3575                 == PackageManager.PERMISSION_GRANTED) {
   3576             return;
   3577         }
   3578 
   3579         unsupportedStartingFrom(VERSION_CODES.M);
   3580     }
   3581 
   3582     /**
   3583      * Binds host resolutions performed by this process to {@code network}.
   3584      * {@link #bindProcessToNetwork} takes precedence over this setting.
   3585      *
   3586      * @param network The {@link Network} to bind host resolutions from the current process to, or
   3587      *                {@code null} to clear the current binding.
   3588      * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
   3589      * @hide
   3590      * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}.
   3591      */
   3592     @Deprecated
   3593     public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
   3594         return NetworkUtils.bindProcessToNetworkForHostResolution(
   3595                 network == null ? NETID_UNSET : network.netId);
   3596     }
   3597 
   3598     /**
   3599      * Device is not restricting metered network activity while application is running on
   3600      * background.
   3601      */
   3602     public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1;
   3603 
   3604     /**
   3605      * Device is restricting metered network activity while application is running on background,
   3606      * but application is allowed to bypass it.
   3607      * <p>
   3608      * In this state, application should take action to mitigate metered network access.
   3609      * For example, a music streaming application should switch to a low-bandwidth bitrate.
   3610      */
   3611     public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2;
   3612 
   3613     /**
   3614      * Device is restricting metered network activity while application is running on background.
   3615      * <p>
   3616      * In this state, application should not try to use the network while running on background,
   3617      * because it would be denied.
   3618      */
   3619     public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3;
   3620 
   3621     /**
   3622      * A change in the background metered network activity restriction has occurred.
   3623      * <p>
   3624      * Applications should call {@link #getRestrictBackgroundStatus()} to check if the restriction
   3625      * applies to them.
   3626      * <p>
   3627      * This is only sent to registered receivers, not manifest receivers.
   3628      */
   3629     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
   3630     public static final String ACTION_RESTRICT_BACKGROUND_CHANGED =
   3631             "android.net.conn.RESTRICT_BACKGROUND_CHANGED";
   3632 
   3633     /** @hide */
   3634     @Retention(RetentionPolicy.SOURCE)
   3635     @IntDef(flag = false, value = {
   3636             RESTRICT_BACKGROUND_STATUS_DISABLED,
   3637             RESTRICT_BACKGROUND_STATUS_WHITELISTED,
   3638             RESTRICT_BACKGROUND_STATUS_ENABLED,
   3639     })
   3640     public @interface RestrictBackgroundStatus {
   3641     }
   3642 
   3643     private INetworkPolicyManager getNetworkPolicyManager() {
   3644         synchronized (this) {
   3645             if (mNPManager != null) {
   3646                 return mNPManager;
   3647             }
   3648             mNPManager = INetworkPolicyManager.Stub.asInterface(ServiceManager
   3649                     .getService(Context.NETWORK_POLICY_SERVICE));
   3650             return mNPManager;
   3651         }
   3652     }
   3653 
   3654     /**
   3655      * Determines if the calling application is subject to metered network restrictions while
   3656      * running on background.
   3657      *
   3658      * @return {@link #RESTRICT_BACKGROUND_STATUS_DISABLED},
   3659      * {@link #RESTRICT_BACKGROUND_STATUS_ENABLED},
   3660      * or {@link #RESTRICT_BACKGROUND_STATUS_WHITELISTED}
   3661      */
   3662     public @RestrictBackgroundStatus int getRestrictBackgroundStatus() {
   3663         try {
   3664             return getNetworkPolicyManager().getRestrictBackgroundByCaller();
   3665         } catch (RemoteException e) {
   3666             throw e.rethrowFromSystemServer();
   3667         }
   3668     }
   3669 
   3670     /**
   3671      * A holder class for debug info (mapping CALLBACK values to field names). This is stored
   3672      * in a holder for two reasons:
   3673      * 1) The reflection necessary to establish the map can't be run at compile-time. Thus, this
   3674      *    code will make the enclosing class not compile-time initializeable, deferring its
   3675      *    initialization to zygote startup. This leads to dirty (but shared) memory.
   3676      *    As this is debug info, use a holder that isn't initialized by default. This way the map
   3677      *    will be created on demand, while ConnectivityManager can be compile-time initialized.
   3678      * 2) Static initialization is still preferred for its strong thread safety guarantees without
   3679      *    requiring a lock.
   3680      */
   3681     private static class NoPreloadHolder {
   3682         public static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(
   3683                 new Class[]{ConnectivityManager.class}, new String[]{"CALLBACK_"});
   3684     }
   3685 
   3686     static {
   3687         // When debug is enabled, aggressively initialize the holder by touching the field (which
   3688         // will guarantee static initialization).
   3689         if (CallbackHandler.DBG) {
   3690             Object dummy = NoPreloadHolder.sMagicDecoderRing;
   3691         }
   3692     }
   3693 
   3694     private static final String whatToString(int what) {
   3695         return NoPreloadHolder.sMagicDecoderRing.get(what, Integer.toString(what));
   3696     }
   3697 }
   3698