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