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