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