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