ConnectivityManager.java revision 0d719cab11ab5670f516466645f8b22ae65d4c91
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.net;
17
18import static com.android.internal.util.Preconditions.checkNotNull;
19
20import android.annotation.SdkConstant;
21import android.annotation.SdkConstant.SdkConstantType;
22import android.app.PendingIntent;
23import android.content.Context;
24import android.content.Intent;
25import android.net.NetworkUtils;
26import android.os.Binder;
27import android.os.Build.VERSION_CODES;
28import android.os.Bundle;
29import android.os.Handler;
30import android.os.HandlerThread;
31import android.os.IBinder;
32import android.os.INetworkActivityListener;
33import android.os.INetworkManagementService;
34import android.os.Looper;
35import android.os.Message;
36import android.os.Messenger;
37import android.os.RemoteException;
38import android.os.ServiceManager;
39import android.provider.Settings;
40import android.telephony.SubscriptionManager;
41import android.telephony.TelephonyManager;
42import android.util.ArrayMap;
43import android.util.Log;
44
45import com.android.internal.telephony.ITelephony;
46import com.android.internal.telephony.PhoneConstants;
47import com.android.internal.util.Protocol;
48
49import java.net.InetAddress;
50import java.util.concurrent.atomic.AtomicInteger;
51import java.util.HashMap;
52
53import libcore.net.event.NetworkEventDispatcher;
54
55/**
56 * Class that answers queries about the state of network connectivity. It also
57 * notifies applications when network connectivity changes. Get an instance
58 * of this class by calling
59 * {@link android.content.Context#getSystemService(String) Context.getSystemService(Context.CONNECTIVITY_SERVICE)}.
60 * <p>
61 * The primary responsibilities of this class are to:
62 * <ol>
63 * <li>Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)</li>
64 * <li>Send broadcast intents when network connectivity changes</li>
65 * <li>Attempt to "fail over" to another network when connectivity to a network
66 * is lost</li>
67 * <li>Provide an API that allows applications to query the coarse-grained or fine-grained
68 * state of the available networks</li>
69 * <li>Provide an API that allows applications to request and select networks for their data
70 * traffic</li>
71 * </ol>
72 */
73public class ConnectivityManager {
74    private static final String TAG = "ConnectivityManager";
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     * historic {@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     * @hide
433     */
434    public final static int REQUEST_ID_UNSET = 0;
435
436    /**
437     * A NetID indicating no Network is selected.
438     * Keep in sync with bionic/libc/dns/include/resolv_netid.h
439     * @hide
440     */
441    public static final int NETID_UNSET = 0;
442
443    private final IConnectivityManager mService;
444    /**
445     * A kludge to facilitate static access where a Context pointer isn't available, like in the
446     * case of the static set/getProcessDefaultNetwork methods and from the Network class.
447     * TODO: Remove this after deprecating the static methods in favor of non-static methods or
448     * methods that take a Context argument.
449     */
450    private static ConnectivityManager sInstance;
451
452    private INetworkManagementService mNMService;
453
454    /**
455     * Tests if a given integer represents a valid network type.
456     * @param networkType the type to be tested
457     * @return a boolean.  {@code true} if the type is valid, else {@code false}
458     */
459    public static boolean isNetworkTypeValid(int networkType) {
460        return networkType >= 0 && networkType <= MAX_NETWORK_TYPE;
461    }
462
463    /**
464     * Returns a non-localized string representing a given network type.
465     * ONLY used for debugging output.
466     * @param type the type needing naming
467     * @return a String for the given type, or a string version of the type ("87")
468     * if no name is known.
469     * {@hide}
470     */
471    public static String getNetworkTypeName(int type) {
472        switch (type) {
473            case TYPE_MOBILE:
474                return "MOBILE";
475            case TYPE_WIFI:
476                return "WIFI";
477            case TYPE_MOBILE_MMS:
478                return "MOBILE_MMS";
479            case TYPE_MOBILE_SUPL:
480                return "MOBILE_SUPL";
481            case TYPE_MOBILE_DUN:
482                return "MOBILE_DUN";
483            case TYPE_MOBILE_HIPRI:
484                return "MOBILE_HIPRI";
485            case TYPE_WIMAX:
486                return "WIMAX";
487            case TYPE_BLUETOOTH:
488                return "BLUETOOTH";
489            case TYPE_DUMMY:
490                return "DUMMY";
491            case TYPE_ETHERNET:
492                return "ETHERNET";
493            case TYPE_MOBILE_FOTA:
494                return "MOBILE_FOTA";
495            case TYPE_MOBILE_IMS:
496                return "MOBILE_IMS";
497            case TYPE_MOBILE_CBS:
498                return "MOBILE_CBS";
499            case TYPE_WIFI_P2P:
500                return "WIFI_P2P";
501            case TYPE_MOBILE_IA:
502                return "MOBILE_IA";
503            case TYPE_MOBILE_EMERGENCY:
504                return "MOBILE_EMERGENCY";
505            case TYPE_PROXY:
506                return "PROXY";
507            default:
508                return Integer.toString(type);
509        }
510    }
511
512    /**
513     * Checks if a given type uses the cellular data connection.
514     * This should be replaced in the future by a network property.
515     * @param networkType the type to check
516     * @return a boolean - {@code true} if uses cellular network, else {@code false}
517     * {@hide}
518     */
519    public static boolean isNetworkTypeMobile(int networkType) {
520        switch (networkType) {
521            case TYPE_MOBILE:
522            case TYPE_MOBILE_MMS:
523            case TYPE_MOBILE_SUPL:
524            case TYPE_MOBILE_DUN:
525            case TYPE_MOBILE_HIPRI:
526            case TYPE_MOBILE_FOTA:
527            case TYPE_MOBILE_IMS:
528            case TYPE_MOBILE_CBS:
529            case TYPE_MOBILE_IA:
530            case TYPE_MOBILE_EMERGENCY:
531                return true;
532            default:
533                return false;
534        }
535    }
536
537    /**
538     * Checks if the given network type is backed by a Wi-Fi radio.
539     *
540     * @hide
541     */
542    public static boolean isNetworkTypeWifi(int networkType) {
543        switch (networkType) {
544            case TYPE_WIFI:
545            case TYPE_WIFI_P2P:
546                return true;
547            default:
548                return false;
549        }
550    }
551
552    /**
553     * Specifies the preferred network type.  When the device has more
554     * than one type available the preferred network type will be used.
555     *
556     * @param preference the network type to prefer over all others.  It is
557     *         unspecified what happens to the old preferred network in the
558     *         overall ordering.
559     * @deprecated Functionality has been removed as it no longer makes sense,
560     *             with many more than two networks - we'd need an array to express
561     *             preference.  Instead we use dynamic network properties of
562     *             the networks to describe their precedence.
563     */
564    public void setNetworkPreference(int preference) {
565    }
566
567    /**
568     * Retrieves the current preferred network type.
569     *
570     * @return an integer representing the preferred network type
571     *
572     * <p>This method requires the caller to hold the permission
573     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
574     * @deprecated Functionality has been removed as it no longer makes sense,
575     *             with many more than two networks - we'd need an array to express
576     *             preference.  Instead we use dynamic network properties of
577     *             the networks to describe their precedence.
578     */
579    public int getNetworkPreference() {
580        return TYPE_NONE;
581    }
582
583    /**
584     * Returns details about the currently active default data network. When
585     * connected, this network is the default route for outgoing connections.
586     * You should always check {@link NetworkInfo#isConnected()} before initiating
587     * network traffic. This may return {@code null} when there is no default
588     * network.
589     *
590     * @return a {@link NetworkInfo} object for the current default network
591     *        or {@code null} if no default network is currently active
592     *
593     * <p>This method requires the caller to hold the permission
594     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
595     */
596    public NetworkInfo getActiveNetworkInfo() {
597        try {
598            return mService.getActiveNetworkInfo();
599        } catch (RemoteException e) {
600            return null;
601        }
602    }
603
604    /**
605     * Returns details about the currently active default data network
606     * for a given uid.  This is for internal use only to avoid spying
607     * other apps.
608     *
609     * @return a {@link NetworkInfo} object for the current default network
610     *        for the given uid or {@code null} if no default network is
611     *        available for the specified uid.
612     *
613     * <p>This method requires the caller to hold the permission
614     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}
615     * {@hide}
616     */
617    public NetworkInfo getActiveNetworkInfoForUid(int uid) {
618        try {
619            return mService.getActiveNetworkInfoForUid(uid);
620        } catch (RemoteException e) {
621            return null;
622        }
623    }
624
625    /**
626     * Returns connection status information about a particular
627     * network type.
628     *
629     * @param networkType integer specifying which networkType in
630     *        which you're interested.
631     * @return a {@link NetworkInfo} object for the requested
632     *        network type or {@code null} if the type is not
633     *        supported by the device.
634     *
635     * <p>This method requires the caller to hold the permission
636     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
637     */
638    public NetworkInfo getNetworkInfo(int networkType) {
639        try {
640            return mService.getNetworkInfo(networkType);
641        } catch (RemoteException e) {
642            return null;
643        }
644    }
645
646    /**
647     * Returns connection status information about a particular
648     * Network.
649     *
650     * @param network {@link Network} specifying which network
651     *        in which you're interested.
652     * @return a {@link NetworkInfo} object for the requested
653     *        network or {@code null} if the {@code Network}
654     *        is not valid.
655     *
656     * <p>This method requires the caller to hold the permission
657     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
658     */
659    public NetworkInfo getNetworkInfo(Network network) {
660        try {
661            return mService.getNetworkInfoForNetwork(network);
662        } catch (RemoteException e) {
663            return null;
664        }
665    }
666
667    /**
668     * Returns connection status information about all network
669     * types supported by the device.
670     *
671     * @return an array of {@link NetworkInfo} objects.  Check each
672     * {@link NetworkInfo#getType} for which type each applies.
673     *
674     * <p>This method requires the caller to hold the permission
675     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
676     */
677    public NetworkInfo[] getAllNetworkInfo() {
678        try {
679            return mService.getAllNetworkInfo();
680        } catch (RemoteException e) {
681            return null;
682        }
683    }
684
685    /**
686     * Returns the {@link Network} object currently serving a given type, or
687     * null if the given type is not connected.
688     *
689     * <p>This method requires the caller to hold the permission
690     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
691     *
692     * @hide
693     */
694    public Network getNetworkForType(int networkType) {
695        try {
696            return mService.getNetworkForType(networkType);
697        } catch (RemoteException e) {
698            return null;
699        }
700    }
701
702    /**
703     * Returns an array of all {@link Network} currently tracked by the
704     * framework.
705     *
706     * @return an array of {@link Network} objects.
707     *
708     * <p>This method requires the caller to hold the permission
709     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
710     */
711    public Network[] getAllNetworks() {
712        try {
713            return mService.getAllNetworks();
714        } catch (RemoteException e) {
715            return null;
716        }
717    }
718
719    /**
720     * Returns an array of of {@link NetworkCapabilities} objects, representing
721     * the Networks that applications run by the given user will use by default.
722     * @hide
723     */
724    public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
725        try {
726            return mService.getDefaultNetworkCapabilitiesForUser(userId);
727        } catch (RemoteException e) {
728            return null;
729        }
730    }
731
732    /**
733     * Returns details about the Provisioning or currently active default data network. When
734     * connected, this network is the default route for outgoing connections.
735     * You should always check {@link NetworkInfo#isConnected()} before initiating
736     * network traffic. This may return {@code null} when there is no default
737     * network.
738     *
739     * @return a {@link NetworkInfo} object for the current default network
740     *        or {@code null} if no default network is currently active
741     *
742     * <p>This method requires the caller to hold the permission
743     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
744     *
745     * {@hide}
746     */
747    public NetworkInfo getProvisioningOrActiveNetworkInfo() {
748        try {
749            return mService.getProvisioningOrActiveNetworkInfo();
750        } catch (RemoteException e) {
751            return null;
752        }
753    }
754
755    /**
756     * Returns the IP information for the current default network.
757     *
758     * @return a {@link LinkProperties} object describing the IP info
759     *        for the current default network, or {@code null} if there
760     *        is no current default network.
761     *
762     * <p>This method requires the caller to hold the permission
763     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
764     * {@hide}
765     */
766    public LinkProperties getActiveLinkProperties() {
767        try {
768            return mService.getActiveLinkProperties();
769        } catch (RemoteException e) {
770            return null;
771        }
772    }
773
774    /**
775     * Returns the IP information for a given network type.
776     *
777     * @param networkType the network type of interest.
778     * @return a {@link LinkProperties} object describing the IP info
779     *        for the given networkType, or {@code null} if there is
780     *        no current default network.
781     *
782     * <p>This method requires the caller to hold the permission
783     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
784     * {@hide}
785     */
786    public LinkProperties getLinkProperties(int networkType) {
787        try {
788            return mService.getLinkPropertiesForType(networkType);
789        } catch (RemoteException e) {
790            return null;
791        }
792    }
793
794    /**
795     * Get the {@link LinkProperties} for the given {@link Network}.  This
796     * will return {@code null} if the network is unknown.
797     *
798     * @param network The {@link Network} object identifying the network in question.
799     * @return The {@link LinkProperties} for the network, or {@code null}.
800     **/
801    public LinkProperties getLinkProperties(Network network) {
802        try {
803            return mService.getLinkProperties(network);
804        } catch (RemoteException e) {
805            return null;
806        }
807    }
808
809    /**
810     * Get the {@link NetworkCapabilities} for the given {@link Network}.  This
811     * will return {@code null} if the network is unknown.
812     *
813     * @param network The {@link Network} object identifying the network in question.
814     * @return The {@link NetworkCapabilities} for the network, or {@code null}.
815     */
816    public NetworkCapabilities getNetworkCapabilities(Network network) {
817        try {
818            return mService.getNetworkCapabilities(network);
819        } catch (RemoteException e) {
820            return null;
821        }
822    }
823
824    /**
825     * Tells each network type to set its radio power state as directed.
826     *
827     * @param turnOn a boolean, {@code true} to turn the radios on,
828     *        {@code false} to turn them off.
829     * @return a boolean, {@code true} indicating success.  All network types
830     *        will be tried, even if some fail.
831     *
832     * <p>This method requires the caller to hold the permission
833     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
834     * {@hide}
835     */
836// TODO - check for any callers and remove
837//    public boolean setRadios(boolean turnOn) {
838//        try {
839//            return mService.setRadios(turnOn);
840//        } catch (RemoteException e) {
841//            return false;
842//        }
843//    }
844
845    /**
846     * Tells a given networkType to set its radio power state as directed.
847     *
848     * @param networkType the int networkType of interest.
849     * @param turnOn a boolean, {@code true} to turn the radio on,
850     *        {@code} false to turn it off.
851     * @return a boolean, {@code true} indicating success.
852     *
853     * <p>This method requires the caller to hold the permission
854     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
855     * {@hide}
856     */
857// TODO - check for any callers and remove
858//    public boolean setRadio(int networkType, boolean turnOn) {
859//        try {
860//            return mService.setRadio(networkType, turnOn);
861//        } catch (RemoteException e) {
862//            return false;
863//        }
864//    }
865
866    /**
867     * Tells the underlying networking system that the caller wants to
868     * begin using the named feature. The interpretation of {@code feature}
869     * is completely up to each networking implementation.
870     * <p>This method requires the caller to hold the permission
871     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
872     * @param networkType specifies which network the request pertains to
873     * @param feature the name of the feature to be used
874     * @return an integer value representing the outcome of the request.
875     * The interpretation of this value is specific to each networking
876     * implementation+feature combination, except that the value {@code -1}
877     * always indicates failure.
878     *
879     * @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
880     */
881    public int startUsingNetworkFeature(int networkType, String feature) {
882        NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
883        if (netCap == null) {
884            Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " +
885                    feature);
886            return PhoneConstants.APN_REQUEST_FAILED;
887        }
888
889        NetworkRequest request = null;
890        synchronized (sLegacyRequests) {
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        if (removeRequestForFeature(netCap)) {
937            Log.d(TAG, "stopUsingNetworkFeature for " + networkType + ", " + feature);
938        }
939        return 1;
940    }
941
942    /**
943     * Removes the NET_CAPABILITY_NOT_RESTRICTED capability from the given
944     * NetworkCapabilities object if all the capabilities it provides are
945     * typically provided by restricted networks.
946     *
947     * TODO: consider:
948     * - Moving to NetworkCapabilities
949     * - Renaming it to guessRestrictedCapability and make it set the
950     *   restricted capability bit in addition to clearing it.
951     * @hide
952     */
953    public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
954        for (int capability : nc.getCapabilities()) {
955            switch (capability) {
956                case NetworkCapabilities.NET_CAPABILITY_CBS:
957                case NetworkCapabilities.NET_CAPABILITY_DUN:
958                case NetworkCapabilities.NET_CAPABILITY_EIMS:
959                case NetworkCapabilities.NET_CAPABILITY_FOTA:
960                case NetworkCapabilities.NET_CAPABILITY_IA:
961                case NetworkCapabilities.NET_CAPABILITY_IMS:
962                case NetworkCapabilities.NET_CAPABILITY_RCS:
963                case NetworkCapabilities.NET_CAPABILITY_XCAP:
964                case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED: //there by default
965                    continue;
966                default:
967                    // At least one capability usually provided by unrestricted
968                    // networks. Conclude that this network is unrestricted.
969                    return;
970            }
971        }
972        // All the capabilities are typically provided by restricted networks.
973        // Conclude that this network is restricted.
974        nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
975    }
976
977    private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
978        if (networkType == TYPE_MOBILE) {
979            int cap = -1;
980            if ("enableMMS".equals(feature)) {
981                cap = NetworkCapabilities.NET_CAPABILITY_MMS;
982            } else if ("enableSUPL".equals(feature)) {
983                cap = NetworkCapabilities.NET_CAPABILITY_SUPL;
984            } else if ("enableDUN".equals(feature) || "enableDUNAlways".equals(feature)) {
985                cap = NetworkCapabilities.NET_CAPABILITY_DUN;
986            } else if ("enableHIPRI".equals(feature)) {
987                cap = NetworkCapabilities.NET_CAPABILITY_INTERNET;
988            } else if ("enableFOTA".equals(feature)) {
989                cap = NetworkCapabilities.NET_CAPABILITY_FOTA;
990            } else if ("enableIMS".equals(feature)) {
991                cap = NetworkCapabilities.NET_CAPABILITY_IMS;
992            } else if ("enableCBS".equals(feature)) {
993                cap = NetworkCapabilities.NET_CAPABILITY_CBS;
994            } else {
995                return null;
996            }
997            NetworkCapabilities netCap = new NetworkCapabilities();
998            netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
999            maybeMarkCapabilitiesRestricted(netCap);
1000            return netCap;
1001        } else if (networkType == TYPE_WIFI) {
1002            if ("p2p".equals(feature)) {
1003                NetworkCapabilities netCap = new NetworkCapabilities();
1004                netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
1005                netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
1006                maybeMarkCapabilitiesRestricted(netCap);
1007                return netCap;
1008            }
1009        }
1010        return null;
1011    }
1012
1013    /**
1014     * Guess what the network request was trying to say so that the resulting
1015     * network is accessible via the legacy (deprecated) API such as
1016     * requestRouteToHost.
1017     * This means we should try to be fairly preceise about transport and
1018     * capability but ignore things such as networkSpecifier.
1019     * If the request has more than one transport or capability it doesn't
1020     * match the old legacy requests (they selected only single transport/capability)
1021     * so this function cannot map the request to a single legacy type and
1022     * the resulting network will not be available to the legacy APIs.
1023     *
1024     * TODO - This should be removed when the legacy APIs are removed.
1025     */
1026    private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
1027        if (netCap == null) {
1028            return TYPE_NONE;
1029        }
1030
1031        if (!netCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
1032            return TYPE_NONE;
1033        }
1034
1035        String type = null;
1036        int result = TYPE_NONE;
1037
1038        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
1039            type = "enableCBS";
1040            result = TYPE_MOBILE_CBS;
1041        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
1042            type = "enableIMS";
1043            result = TYPE_MOBILE_IMS;
1044        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
1045            type = "enableFOTA";
1046            result = TYPE_MOBILE_FOTA;
1047        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
1048            type = "enableDUN";
1049            result = TYPE_MOBILE_DUN;
1050        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
1051            type = "enableSUPL";
1052            result = TYPE_MOBILE_SUPL;
1053        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
1054            type = "enableMMS";
1055            result = TYPE_MOBILE_MMS;
1056        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
1057            type = "enableHIPRI";
1058            result = TYPE_MOBILE_HIPRI;
1059        }
1060        if (type != null) {
1061            NetworkCapabilities testCap = networkCapabilitiesForFeature(TYPE_MOBILE, type);
1062            if (testCap.equalsNetCapabilities(netCap) && testCap.equalsTransportTypes(netCap)) {
1063                return result;
1064            }
1065        }
1066        return TYPE_NONE;
1067    }
1068
1069    private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
1070        if (netCap == null) return TYPE_NONE;
1071        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
1072            return TYPE_MOBILE_CBS;
1073        }
1074        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
1075            return TYPE_MOBILE_IMS;
1076        }
1077        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
1078            return TYPE_MOBILE_FOTA;
1079        }
1080        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
1081            return TYPE_MOBILE_DUN;
1082        }
1083        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
1084            return TYPE_MOBILE_SUPL;
1085        }
1086        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
1087            return TYPE_MOBILE_MMS;
1088        }
1089        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
1090            return TYPE_MOBILE_HIPRI;
1091        }
1092        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) {
1093            return TYPE_WIFI_P2P;
1094        }
1095        return TYPE_NONE;
1096    }
1097
1098    private static class LegacyRequest {
1099        NetworkCapabilities networkCapabilities;
1100        NetworkRequest networkRequest;
1101        int expireSequenceNumber;
1102        Network currentNetwork;
1103        int delay = -1;
1104
1105        private void clearDnsBinding() {
1106            if (currentNetwork != null) {
1107                currentNetwork = null;
1108                setProcessDefaultNetworkForHostResolution(null);
1109            }
1110        }
1111
1112        NetworkCallback networkCallback = new NetworkCallback() {
1113            @Override
1114            public void onAvailable(Network network) {
1115                currentNetwork = network;
1116                Log.d(TAG, "startUsingNetworkFeature got Network:" + network);
1117                setProcessDefaultNetworkForHostResolution(network);
1118            }
1119            @Override
1120            public void onLost(Network network) {
1121                if (network.equals(currentNetwork)) clearDnsBinding();
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) removeRequestForFeature(netCap);
1151        }
1152        Log.d(TAG, "expireRequest with " + ourSeqNum + ", " + sequenceNum);
1153    }
1154
1155    private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) {
1156        int delay = -1;
1157        int type = legacyTypeForNetworkCapabilities(netCap);
1158        try {
1159            delay = mService.getRestoreDefaultNetworkDelay(type);
1160        } catch (RemoteException e) {}
1161        LegacyRequest l = new LegacyRequest();
1162        l.networkCapabilities = netCap;
1163        l.delay = delay;
1164        l.expireSequenceNumber = 0;
1165        l.networkRequest = sendRequestForNetwork(netCap, l.networkCallback, 0,
1166                REQUEST, type);
1167        if (l.networkRequest == null) return null;
1168        sLegacyRequests.put(netCap, l);
1169        sendExpireMsgForFeature(netCap, l.expireSequenceNumber, delay);
1170        return l.networkRequest;
1171    }
1172
1173    private void sendExpireMsgForFeature(NetworkCapabilities netCap, int seqNum, int delay) {
1174        if (delay >= 0) {
1175            Log.d(TAG, "sending expire msg with seqNum " + seqNum + " and delay " + delay);
1176            Message msg = sCallbackHandler.obtainMessage(EXPIRE_LEGACY_REQUEST, seqNum, 0, netCap);
1177            sCallbackHandler.sendMessageDelayed(msg, delay);
1178        }
1179    }
1180
1181    private boolean removeRequestForFeature(NetworkCapabilities netCap) {
1182        final LegacyRequest l;
1183        synchronized (sLegacyRequests) {
1184            l = sLegacyRequests.remove(netCap);
1185        }
1186        if (l == null) return false;
1187        unregisterNetworkCallback(l.networkCallback);
1188        l.clearDnsBinding();
1189        return true;
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 #bindProcessToNetwork} 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 #bindProcessToNetwork} 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 caller 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                int subId = SubscriptionManager.getDefaultDataSubId();
1298                Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
1299                boolean retVal = it.getDataEnabled(subId);
1300                Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
1301                        + " retVal=" + retVal);
1302                return retVal;
1303            } catch (RemoteException e) { }
1304        }
1305        Log.d("ConnectivityManager", "getMobileDataEnabled()- remote exception retVal=false");
1306        return false;
1307    }
1308
1309    /**
1310     * Callback for use with {@link ConnectivityManager#addDefaultNetworkActiveListener}
1311     * to find out when the system default network has gone in to a high power state.
1312     */
1313    public interface OnNetworkActiveListener {
1314        /**
1315         * Called on the main thread of the process to report that the current data network
1316         * has become active, and it is now a good time to perform any pending network
1317         * operations.  Note that this listener only tells you when the network becomes
1318         * active; if at any other time you want to know whether it is active (and thus okay
1319         * to initiate network traffic), you can retrieve its instantaneous state with
1320         * {@link ConnectivityManager#isDefaultNetworkActive}.
1321         */
1322        public void onNetworkActive();
1323    }
1324
1325    private INetworkManagementService getNetworkManagementService() {
1326        synchronized (this) {
1327            if (mNMService != null) {
1328                return mNMService;
1329            }
1330            IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
1331            mNMService = INetworkManagementService.Stub.asInterface(b);
1332            return mNMService;
1333        }
1334    }
1335
1336    private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
1337            mNetworkActivityListeners
1338                    = new ArrayMap<OnNetworkActiveListener, INetworkActivityListener>();
1339
1340    /**
1341     * Start listening to reports when the system's default data network is active, meaning it is
1342     * a good time to perform network traffic.  Use {@link #isDefaultNetworkActive()}
1343     * to determine the current state of the system's default network after registering the
1344     * listener.
1345     * <p>
1346     * If the process default network has been set with
1347     * {@link ConnectivityManager#bindProcessToNetwork} this function will not
1348     * reflect the process's default, but the system default.
1349     *
1350     * @param l The listener to be told when the network is active.
1351     */
1352    public void addDefaultNetworkActiveListener(final OnNetworkActiveListener l) {
1353        INetworkActivityListener rl = new INetworkActivityListener.Stub() {
1354            @Override
1355            public void onNetworkActive() throws RemoteException {
1356                l.onNetworkActive();
1357            }
1358        };
1359
1360        try {
1361            getNetworkManagementService().registerNetworkActivityListener(rl);
1362            mNetworkActivityListeners.put(l, rl);
1363        } catch (RemoteException e) {
1364        }
1365    }
1366
1367    /**
1368     * Remove network active listener previously registered with
1369     * {@link #addDefaultNetworkActiveListener}.
1370     *
1371     * @param l Previously registered listener.
1372     */
1373    public void removeDefaultNetworkActiveListener(OnNetworkActiveListener l) {
1374        INetworkActivityListener rl = mNetworkActivityListeners.get(l);
1375        if (rl == null) {
1376            throw new IllegalArgumentException("Listener not registered: " + l);
1377        }
1378        try {
1379            getNetworkManagementService().unregisterNetworkActivityListener(rl);
1380        } catch (RemoteException e) {
1381        }
1382    }
1383
1384    /**
1385     * Return whether the data network is currently active.  An active network means that
1386     * it is currently in a high power state for performing data transmission.  On some
1387     * types of networks, it may be expensive to move and stay in such a state, so it is
1388     * more power efficient to batch network traffic together when the radio is already in
1389     * this state.  This method tells you whether right now is currently a good time to
1390     * initiate network traffic, as the network is already active.
1391     */
1392    public boolean isDefaultNetworkActive() {
1393        try {
1394            return getNetworkManagementService().isNetworkActive();
1395        } catch (RemoteException e) {
1396        }
1397        return false;
1398    }
1399
1400    /**
1401     * {@hide}
1402     */
1403    public ConnectivityManager(IConnectivityManager service) {
1404        mService = checkNotNull(service, "missing IConnectivityManager");
1405        sInstance = this;
1406    }
1407
1408    /** {@hide} */
1409    public static ConnectivityManager from(Context context) {
1410        return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
1411    }
1412
1413    /** {@hide */
1414    public static final void enforceTetherChangePermission(Context context) {
1415        if (context.getResources().getStringArray(
1416                com.android.internal.R.array.config_mobile_hotspot_provision_app).length == 2) {
1417            // Have a provisioning app - must only let system apps (which check this app)
1418            // turn on tethering
1419            context.enforceCallingOrSelfPermission(
1420                    android.Manifest.permission.CONNECTIVITY_INTERNAL, "ConnectivityService");
1421        } else {
1422            context.enforceCallingOrSelfPermission(
1423                    android.Manifest.permission.CHANGE_NETWORK_STATE, "ConnectivityService");
1424        }
1425    }
1426
1427    /**
1428     * @deprecated - use getSystemService. This is a kludge to support static access in certain
1429     *               situations where a Context pointer is unavailable.
1430     * @hide
1431     */
1432    static ConnectivityManager getInstanceOrNull() {
1433        return sInstance;
1434    }
1435
1436    /**
1437     * @deprecated - use getSystemService. This is a kludge to support static access in certain
1438     *               situations where a Context pointer is unavailable.
1439     * @hide
1440     */
1441    private static ConnectivityManager getInstance() {
1442        if (getInstanceOrNull() == null) {
1443            throw new IllegalStateException("No ConnectivityManager yet constructed");
1444        }
1445        return getInstanceOrNull();
1446    }
1447
1448    /**
1449     * Get the set of tetherable, available interfaces.  This list is limited by
1450     * device configuration and current interface existence.
1451     *
1452     * @return an array of 0 or more Strings of tetherable interface names.
1453     *
1454     * <p>This method requires the caller to hold the permission
1455     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1456     * {@hide}
1457     */
1458    public String[] getTetherableIfaces() {
1459        try {
1460            return mService.getTetherableIfaces();
1461        } catch (RemoteException e) {
1462            return new String[0];
1463        }
1464    }
1465
1466    /**
1467     * Get the set of tethered interfaces.
1468     *
1469     * @return an array of 0 or more String of currently tethered interface names.
1470     *
1471     * <p>This method requires the caller to hold the permission
1472     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1473     * {@hide}
1474     */
1475    public String[] getTetheredIfaces() {
1476        try {
1477            return mService.getTetheredIfaces();
1478        } catch (RemoteException e) {
1479            return new String[0];
1480        }
1481    }
1482
1483    /**
1484     * Get the set of interface names which attempted to tether but
1485     * failed.  Re-attempting to tether may cause them to reset to the Tethered
1486     * state.  Alternatively, causing the interface to be destroyed and recreated
1487     * may cause them to reset to the available state.
1488     * {@link ConnectivityManager#getLastTetherError} can be used to get more
1489     * information on the cause of the errors.
1490     *
1491     * @return an array of 0 or more String indicating the interface names
1492     *        which failed to tether.
1493     *
1494     * <p>This method requires the caller to hold the permission
1495     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1496     * {@hide}
1497     */
1498    public String[] getTetheringErroredIfaces() {
1499        try {
1500            return mService.getTetheringErroredIfaces();
1501        } catch (RemoteException e) {
1502            return new String[0];
1503        }
1504    }
1505
1506    /**
1507     * Get the set of tethered dhcp ranges.
1508     *
1509     * @return an array of 0 or more {@code String} of tethered dhcp ranges.
1510     * {@hide}
1511     */
1512    public String[] getTetheredDhcpRanges() {
1513        try {
1514            return mService.getTetheredDhcpRanges();
1515        } catch (RemoteException e) {
1516            return new String[0];
1517        }
1518    }
1519
1520    /**
1521     * Attempt to tether the named interface.  This will setup a dhcp server
1522     * on the interface, forward and NAT IP packets and forward DNS requests
1523     * to the best active upstream network interface.  Note that if no upstream
1524     * IP network interface is available, dhcp will still run and traffic will be
1525     * allowed between the tethered devices and this device, though upstream net
1526     * access will of course fail until an upstream network interface becomes
1527     * active.
1528     *
1529     * @param iface the interface name to tether.
1530     * @return error a {@code TETHER_ERROR} value indicating success or failure type
1531     *
1532     * <p>This method requires the caller to hold the permission
1533     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
1534     * {@hide}
1535     */
1536    public int tether(String iface) {
1537        try {
1538            return mService.tether(iface);
1539        } catch (RemoteException e) {
1540            return TETHER_ERROR_SERVICE_UNAVAIL;
1541        }
1542    }
1543
1544    /**
1545     * Stop tethering the named interface.
1546     *
1547     * @param iface the interface name to untether.
1548     * @return error a {@code TETHER_ERROR} value indicating success or failure type
1549     *
1550     * <p>This method requires the caller to hold the permission
1551     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
1552     * {@hide}
1553     */
1554    public int untether(String iface) {
1555        try {
1556            return mService.untether(iface);
1557        } catch (RemoteException e) {
1558            return TETHER_ERROR_SERVICE_UNAVAIL;
1559        }
1560    }
1561
1562    /**
1563     * Check if the device allows for tethering.  It may be disabled via
1564     * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
1565     * due to device configuration.
1566     *
1567     * @return a boolean - {@code true} indicating Tethering is supported.
1568     *
1569     * <p>This method requires the caller to hold the permission
1570     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1571     * {@hide}
1572     */
1573    public boolean isTetheringSupported() {
1574        try {
1575            return mService.isTetheringSupported();
1576        } catch (RemoteException e) {
1577            return false;
1578        }
1579    }
1580
1581    /**
1582     * Get the list of regular expressions that define any tetherable
1583     * USB network interfaces.  If USB tethering is not supported by the
1584     * device, this list should be empty.
1585     *
1586     * @return an array of 0 or more regular expression Strings defining
1587     *        what interfaces are considered tetherable usb interfaces.
1588     *
1589     * <p>This method requires the caller to hold the permission
1590     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1591     * {@hide}
1592     */
1593    public String[] getTetherableUsbRegexs() {
1594        try {
1595            return mService.getTetherableUsbRegexs();
1596        } catch (RemoteException e) {
1597            return new String[0];
1598        }
1599    }
1600
1601    /**
1602     * Get the list of regular expressions that define any tetherable
1603     * Wifi network interfaces.  If Wifi tethering is not supported by the
1604     * device, this list should be empty.
1605     *
1606     * @return an array of 0 or more regular expression Strings defining
1607     *        what interfaces are considered tetherable wifi interfaces.
1608     *
1609     * <p>This method requires the caller to hold the permission
1610     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1611     * {@hide}
1612     */
1613    public String[] getTetherableWifiRegexs() {
1614        try {
1615            return mService.getTetherableWifiRegexs();
1616        } catch (RemoteException e) {
1617            return new String[0];
1618        }
1619    }
1620
1621    /**
1622     * Get the list of regular expressions that define any tetherable
1623     * Bluetooth network interfaces.  If Bluetooth tethering is not supported by the
1624     * device, this list should be empty.
1625     *
1626     * @return an array of 0 or more regular expression Strings defining
1627     *        what interfaces are considered tetherable bluetooth interfaces.
1628     *
1629     * <p>This method requires the caller to hold the permission
1630     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1631     * {@hide}
1632     */
1633    public String[] getTetherableBluetoothRegexs() {
1634        try {
1635            return mService.getTetherableBluetoothRegexs();
1636        } catch (RemoteException e) {
1637            return new String[0];
1638        }
1639    }
1640
1641    /**
1642     * Attempt to both alter the mode of USB and Tethering of USB.  A
1643     * utility method to deal with some of the complexity of USB - will
1644     * attempt to switch to Rndis and subsequently tether the resulting
1645     * interface on {@code true} or turn off tethering and switch off
1646     * Rndis on {@code false}.
1647     *
1648     * @param enable a boolean - {@code true} to enable tethering
1649     * @return error a {@code TETHER_ERROR} value indicating success or failure type
1650     *
1651     * <p>This method requires the caller to hold the permission
1652     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
1653     * {@hide}
1654     */
1655    public int setUsbTethering(boolean enable) {
1656        try {
1657            return mService.setUsbTethering(enable);
1658        } catch (RemoteException e) {
1659            return TETHER_ERROR_SERVICE_UNAVAIL;
1660        }
1661    }
1662
1663    /** {@hide} */
1664    public static final int TETHER_ERROR_NO_ERROR           = 0;
1665    /** {@hide} */
1666    public static final int TETHER_ERROR_UNKNOWN_IFACE      = 1;
1667    /** {@hide} */
1668    public static final int TETHER_ERROR_SERVICE_UNAVAIL    = 2;
1669    /** {@hide} */
1670    public static final int TETHER_ERROR_UNSUPPORTED        = 3;
1671    /** {@hide} */
1672    public static final int TETHER_ERROR_UNAVAIL_IFACE      = 4;
1673    /** {@hide} */
1674    public static final int TETHER_ERROR_MASTER_ERROR       = 5;
1675    /** {@hide} */
1676    public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
1677    /** {@hide} */
1678    public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
1679    /** {@hide} */
1680    public static final int TETHER_ERROR_ENABLE_NAT_ERROR     = 8;
1681    /** {@hide} */
1682    public static final int TETHER_ERROR_DISABLE_NAT_ERROR    = 9;
1683    /** {@hide} */
1684    public static final int TETHER_ERROR_IFACE_CFG_ERROR      = 10;
1685
1686    /**
1687     * Get a more detailed error code after a Tethering or Untethering
1688     * request asynchronously failed.
1689     *
1690     * @param iface The name of the interface of interest
1691     * @return error The error code of the last error tethering or untethering the named
1692     *               interface
1693     *
1694     * <p>This method requires the caller to hold the permission
1695     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1696     * {@hide}
1697     */
1698    public int getLastTetherError(String iface) {
1699        try {
1700            return mService.getLastTetherError(iface);
1701        } catch (RemoteException e) {
1702            return TETHER_ERROR_SERVICE_UNAVAIL;
1703        }
1704    }
1705
1706    /**
1707     * Report network connectivity status.  This is currently used only
1708     * to alter status bar UI.
1709     *
1710     * @param networkType The type of network you want to report on
1711     * @param percentage The quality of the connection 0 is bad, 100 is good
1712     *
1713     * <p>This method requires the caller to hold the permission
1714     * {@link android.Manifest.permission#STATUS_BAR}.
1715     * {@hide}
1716     */
1717    public void reportInetCondition(int networkType, int percentage) {
1718        try {
1719            mService.reportInetCondition(networkType, percentage);
1720        } catch (RemoteException e) {
1721        }
1722    }
1723
1724    /**
1725     * Report a problem network to the framework.  This provides a hint to the system
1726     * that there might be connectivity problems on this network and may cause
1727     * the framework to re-evaluate network connectivity and/or switch to another
1728     * network.
1729     *
1730     * @param network The {@link Network} the application was attempting to use
1731     *                or {@code null} to indicate the current default network.
1732     */
1733    public void reportBadNetwork(Network network) {
1734        try {
1735            mService.reportBadNetwork(network);
1736        } catch (RemoteException e) {
1737        }
1738    }
1739
1740    /**
1741     * Set a network-independent global http proxy.  This is not normally what you want
1742     * for typical HTTP proxies - they are general network dependent.  However if you're
1743     * doing something unusual like general internal filtering this may be useful.  On
1744     * a private network where the proxy is not accessible, you may break HTTP using this.
1745     *
1746     * @param p The a {@link ProxyInfo} object defining the new global
1747     *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
1748     *
1749     * <p>This method requires the caller to hold the permission
1750     * android.Manifest.permission#CONNECTIVITY_INTERNAL.
1751     * @hide
1752     */
1753    public void setGlobalProxy(ProxyInfo p) {
1754        try {
1755            mService.setGlobalProxy(p);
1756        } catch (RemoteException e) {
1757        }
1758    }
1759
1760    /**
1761     * Retrieve any network-independent global HTTP proxy.
1762     *
1763     * @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
1764     *        if no global HTTP proxy is set.
1765     *
1766     * <p>This method requires the caller to hold the permission
1767     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1768     * @hide
1769     */
1770    public ProxyInfo getGlobalProxy() {
1771        try {
1772            return mService.getGlobalProxy();
1773        } catch (RemoteException e) {
1774            return null;
1775        }
1776    }
1777
1778    /**
1779     * Get the current default HTTP proxy settings.  If a global proxy is set it will be returned,
1780     * otherwise if this process is bound to a {@link Network} using
1781     * {@link #bindProcessToNetwork} then that {@code Network}'s proxy is returned, otherwise
1782     * the default network's proxy is returned.
1783     *
1784     * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no
1785     *        HTTP proxy is active.
1786     */
1787    public ProxyInfo getDefaultProxy() {
1788        final Network network = getBoundNetworkForProcess();
1789        if (network != null) {
1790            final ProxyInfo globalProxy = getGlobalProxy();
1791            if (globalProxy != null) return globalProxy;
1792            final LinkProperties lp = getLinkProperties(network);
1793            if (lp != null) return lp.getHttpProxy();
1794            return null;
1795        }
1796        try {
1797            return mService.getDefaultProxy();
1798        } catch (RemoteException e) {
1799            return null;
1800        }
1801    }
1802
1803    /**
1804     * Returns true if the hardware supports the given network type
1805     * else it returns false.  This doesn't indicate we have coverage
1806     * or are authorized onto a network, just whether or not the
1807     * hardware supports it.  For example a GSM phone without a SIM
1808     * should still return {@code true} for mobile data, but a wifi only
1809     * tablet would return {@code false}.
1810     *
1811     * @param networkType The network type we'd like to check
1812     * @return {@code true} if supported, else {@code false}
1813     *
1814     * <p>This method requires the caller to hold the permission
1815     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1816     * @hide
1817     */
1818    public boolean isNetworkSupported(int networkType) {
1819        try {
1820            return mService.isNetworkSupported(networkType);
1821        } catch (RemoteException e) {}
1822        return false;
1823    }
1824
1825    /**
1826     * Returns if the currently active data network is metered. A network is
1827     * classified as metered when the user is sensitive to heavy data usage on
1828     * that connection due to monetary costs, data limitations or
1829     * battery/performance issues. You should check this before doing large
1830     * data transfers, and warn the user or delay the operation until another
1831     * network is available.
1832     *
1833     * @return {@code true} if large transfers should be avoided, otherwise
1834     *        {@code false}.
1835     *
1836     * <p>This method requires the caller to hold the permission
1837     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1838     */
1839    public boolean isActiveNetworkMetered() {
1840        try {
1841            return mService.isActiveNetworkMetered();
1842        } catch (RemoteException e) {
1843            return false;
1844        }
1845    }
1846
1847    /**
1848     * If the LockdownVpn mechanism is enabled, updates the vpn
1849     * with a reload of its profile.
1850     *
1851     * @return a boolean with {@code} indicating success
1852     *
1853     * <p>This method can only be called by the system UID
1854     * {@hide}
1855     */
1856    public boolean updateLockdownVpn() {
1857        try {
1858            return mService.updateLockdownVpn();
1859        } catch (RemoteException e) {
1860            return false;
1861        }
1862    }
1863
1864    /**
1865     * Signal that the captive portal check on the indicated network
1866     * is complete and whether its a captive portal or not.
1867     *
1868     * @param info the {@link NetworkInfo} object for the networkType
1869     *        in question.
1870     * @param isCaptivePortal true/false.
1871     *
1872     * <p>This method requires the caller to hold the permission
1873     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
1874     * {@hide}
1875     */
1876    public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
1877        try {
1878            mService.captivePortalCheckCompleted(info, isCaptivePortal);
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     * Set sign in error notification to visible or in visible
1928     *
1929     * @param visible
1930     * @param networkType
1931     *
1932     * {@hide}
1933     */
1934    public void setProvisioningNotificationVisible(boolean visible, int networkType,
1935            String action) {
1936        try {
1937            mService.setProvisioningNotificationVisible(visible, networkType, action);
1938        } catch (RemoteException e) {
1939        }
1940    }
1941
1942    /**
1943     * Set the value for enabling/disabling airplane mode
1944     *
1945     * @param enable whether to enable airplane mode or not
1946     *
1947     * <p>This method requires the caller to hold the permission
1948     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
1949     * @hide
1950     */
1951    public void setAirplaneMode(boolean enable) {
1952        try {
1953            mService.setAirplaneMode(enable);
1954        } catch (RemoteException e) {
1955        }
1956    }
1957
1958    /** {@hide} */
1959    public void registerNetworkFactory(Messenger messenger, String name) {
1960        try {
1961            mService.registerNetworkFactory(messenger, name);
1962        } catch (RemoteException e) { }
1963    }
1964
1965    /** {@hide} */
1966    public void unregisterNetworkFactory(Messenger messenger) {
1967        try {
1968            mService.unregisterNetworkFactory(messenger);
1969        } catch (RemoteException e) { }
1970    }
1971
1972    /** {@hide} */
1973    public void registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
1974            NetworkCapabilities nc, int score, NetworkMisc misc) {
1975        try {
1976            mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc);
1977        } catch (RemoteException e) { }
1978    }
1979
1980    /**
1981     * Base class for NetworkRequest callbacks.  Used for notifications about network
1982     * changes.  Should be extended by applications wanting notifications.
1983     */
1984    public static class NetworkCallback {
1985        /** @hide */
1986        public static final int PRECHECK     = 1;
1987        /** @hide */
1988        public static final int AVAILABLE    = 2;
1989        /** @hide */
1990        public static final int LOSING       = 3;
1991        /** @hide */
1992        public static final int LOST         = 4;
1993        /** @hide */
1994        public static final int UNAVAIL      = 5;
1995        /** @hide */
1996        public static final int CAP_CHANGED  = 6;
1997        /** @hide */
1998        public static final int PROP_CHANGED = 7;
1999        /** @hide */
2000        public static final int CANCELED     = 8;
2001
2002        /**
2003         * @hide
2004         * Called whenever the framework connects to a network that it may use to
2005         * satisfy this request
2006         */
2007        public void onPreCheck(Network network) {}
2008
2009        /**
2010         * Called when the framework connects and has declared new network ready for use.
2011         * This callback may be called more than once if the {@link Network} that is
2012         * satisfying the request changes.
2013         *
2014         * @param network The {@link Network} of the satisfying network.
2015         */
2016        public void onAvailable(Network network) {}
2017
2018        /**
2019         * Called when the network is about to be disconnected.  Often paired with an
2020         * {@link NetworkCallback#onAvailable} call with the new replacement network
2021         * for graceful handover.  This may not be called if we have a hard loss
2022         * (loss without warning).  This may be followed by either a
2023         * {@link NetworkCallback#onLost} call or a
2024         * {@link NetworkCallback#onAvailable} call for this network depending
2025         * on whether we lose or regain it.
2026         *
2027         * @param network The {@link Network} that is about to be disconnected.
2028         * @param maxMsToLive The time in ms the framework will attempt to keep the
2029         *                     network connected.  Note that the network may suffer a
2030         *                     hard loss at any time.
2031         */
2032        public void onLosing(Network network, int maxMsToLive) {}
2033
2034        /**
2035         * Called when the framework has a hard loss of the network or when the
2036         * graceful failure ends.
2037         *
2038         * @param network The {@link Network} lost.
2039         */
2040        public void onLost(Network network) {}
2041
2042        /**
2043         * Called if no network is found in the given timeout time.  If no timeout is given,
2044         * this will not be called.
2045         * @hide
2046         */
2047        public void onUnavailable() {}
2048
2049        /**
2050         * Called when the network the framework connected to for this request
2051         * changes capabilities but still satisfies the stated need.
2052         *
2053         * @param network The {@link Network} whose capabilities have changed.
2054         * @param networkCapabilities The new {@link NetworkCapabilities} for this network.
2055         */
2056        public void onCapabilitiesChanged(Network network,
2057                NetworkCapabilities networkCapabilities) {}
2058
2059        /**
2060         * Called when the network the framework connected to for this request
2061         * changes {@link LinkProperties}.
2062         *
2063         * @param network The {@link Network} whose link properties have changed.
2064         * @param linkProperties The new {@link LinkProperties} for this network.
2065         */
2066        public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {}
2067
2068        private NetworkRequest networkRequest;
2069    }
2070
2071    private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER;
2072    /** @hide obj = pair(NetworkRequest, Network) */
2073    public static final int CALLBACK_PRECHECK           = BASE + 1;
2074    /** @hide obj = pair(NetworkRequest, Network) */
2075    public static final int CALLBACK_AVAILABLE          = BASE + 2;
2076    /** @hide obj = pair(NetworkRequest, Network), arg1 = ttl */
2077    public static final int CALLBACK_LOSING             = BASE + 3;
2078    /** @hide obj = pair(NetworkRequest, Network) */
2079    public static final int CALLBACK_LOST               = BASE + 4;
2080    /** @hide obj = NetworkRequest */
2081    public static final int CALLBACK_UNAVAIL            = BASE + 5;
2082    /** @hide obj = pair(NetworkRequest, Network) */
2083    public static final int CALLBACK_CAP_CHANGED        = BASE + 6;
2084    /** @hide obj = pair(NetworkRequest, Network) */
2085    public static final int CALLBACK_IP_CHANGED         = BASE + 7;
2086    /** @hide obj = NetworkRequest */
2087    public static final int CALLBACK_RELEASED           = BASE + 8;
2088    /** @hide */
2089    public static final int CALLBACK_EXIT               = BASE + 9;
2090    /** @hide obj = NetworkCapabilities, arg1 = seq number */
2091    private static final int EXPIRE_LEGACY_REQUEST      = BASE + 10;
2092
2093    private class CallbackHandler extends Handler {
2094        private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap;
2095        private final AtomicInteger mRefCount;
2096        private static final String TAG = "ConnectivityManager.CallbackHandler";
2097        private final ConnectivityManager mCm;
2098
2099        CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallback>callbackMap,
2100                AtomicInteger refCount, ConnectivityManager cm) {
2101            super(looper);
2102            mCallbackMap = callbackMap;
2103            mRefCount = refCount;
2104            mCm = cm;
2105        }
2106
2107        @Override
2108        public void handleMessage(Message message) {
2109            Log.d(TAG, "CM callback handler got msg " + message.what);
2110            switch (message.what) {
2111                case CALLBACK_PRECHECK: {
2112                    NetworkRequest request = (NetworkRequest)getObject(message,
2113                            NetworkRequest.class);
2114                    NetworkCallback callbacks = getCallbacks(request);
2115                    if (callbacks != null) {
2116                        callbacks.onPreCheck((Network)getObject(message, Network.class));
2117                    } else {
2118                        Log.e(TAG, "callback not found for PRECHECK message");
2119                    }
2120                    break;
2121                }
2122                case CALLBACK_AVAILABLE: {
2123                    NetworkRequest request = (NetworkRequest)getObject(message,
2124                            NetworkRequest.class);
2125                    NetworkCallback callbacks = getCallbacks(request);
2126                    if (callbacks != null) {
2127                        callbacks.onAvailable((Network)getObject(message, Network.class));
2128                    } else {
2129                        Log.e(TAG, "callback not found for AVAILABLE message");
2130                    }
2131                    break;
2132                }
2133                case CALLBACK_LOSING: {
2134                    NetworkRequest request = (NetworkRequest)getObject(message,
2135                            NetworkRequest.class);
2136                    NetworkCallback callbacks = getCallbacks(request);
2137                    if (callbacks != null) {
2138                        callbacks.onLosing((Network)getObject(message, Network.class),
2139                                message.arg1);
2140                    } else {
2141                        Log.e(TAG, "callback not found for LOSING message");
2142                    }
2143                    break;
2144                }
2145                case CALLBACK_LOST: {
2146                    NetworkRequest request = (NetworkRequest)getObject(message,
2147                            NetworkRequest.class);
2148
2149                    NetworkCallback callbacks = getCallbacks(request);
2150                    if (callbacks != null) {
2151                        callbacks.onLost((Network)getObject(message, Network.class));
2152                    } else {
2153                        Log.e(TAG, "callback not found for LOST message");
2154                    }
2155                    break;
2156                }
2157                case CALLBACK_UNAVAIL: {
2158                    NetworkRequest request = (NetworkRequest)getObject(message,
2159                            NetworkRequest.class);
2160                    NetworkCallback callbacks = null;
2161                    synchronized(mCallbackMap) {
2162                        callbacks = mCallbackMap.get(request);
2163                    }
2164                    if (callbacks != null) {
2165                        callbacks.onUnavailable();
2166                    } else {
2167                        Log.e(TAG, "callback not found for UNAVAIL message");
2168                    }
2169                    break;
2170                }
2171                case CALLBACK_CAP_CHANGED: {
2172                    NetworkRequest request = (NetworkRequest)getObject(message,
2173                            NetworkRequest.class);
2174                    NetworkCallback callbacks = getCallbacks(request);
2175                    if (callbacks != null) {
2176                        Network network = (Network)getObject(message, Network.class);
2177                        NetworkCapabilities cap = (NetworkCapabilities)getObject(message,
2178                                NetworkCapabilities.class);
2179
2180                        callbacks.onCapabilitiesChanged(network, cap);
2181                    } else {
2182                        Log.e(TAG, "callback not found for CAP_CHANGED message");
2183                    }
2184                    break;
2185                }
2186                case CALLBACK_IP_CHANGED: {
2187                    NetworkRequest request = (NetworkRequest)getObject(message,
2188                            NetworkRequest.class);
2189                    NetworkCallback callbacks = getCallbacks(request);
2190                    if (callbacks != null) {
2191                        Network network = (Network)getObject(message, Network.class);
2192                        LinkProperties lp = (LinkProperties)getObject(message,
2193                                LinkProperties.class);
2194
2195                        callbacks.onLinkPropertiesChanged(network, lp);
2196                    } else {
2197                        Log.e(TAG, "callback not found for IP_CHANGED message");
2198                    }
2199                    break;
2200                }
2201                case CALLBACK_RELEASED: {
2202                    NetworkRequest req = (NetworkRequest)getObject(message, NetworkRequest.class);
2203                    NetworkCallback callbacks = null;
2204                    synchronized(mCallbackMap) {
2205                        callbacks = mCallbackMap.remove(req);
2206                    }
2207                    if (callbacks != null) {
2208                        synchronized(mRefCount) {
2209                            if (mRefCount.decrementAndGet() == 0) {
2210                                getLooper().quit();
2211                            }
2212                        }
2213                    } else {
2214                        Log.e(TAG, "callback not found for CANCELED message");
2215                    }
2216                    break;
2217                }
2218                case CALLBACK_EXIT: {
2219                    Log.d(TAG, "Listener quiting");
2220                    getLooper().quit();
2221                    break;
2222                }
2223                case EXPIRE_LEGACY_REQUEST: {
2224                    expireRequest((NetworkCapabilities)message.obj, message.arg1);
2225                    break;
2226                }
2227            }
2228        }
2229
2230        private Object getObject(Message msg, Class c) {
2231            return msg.getData().getParcelable(c.getSimpleName());
2232        }
2233        private NetworkCallback getCallbacks(NetworkRequest req) {
2234            synchronized(mCallbackMap) {
2235                return mCallbackMap.get(req);
2236            }
2237        }
2238    }
2239
2240    private void incCallbackHandlerRefCount() {
2241        synchronized(sCallbackRefCount) {
2242            if (sCallbackRefCount.incrementAndGet() == 1) {
2243                // TODO - switch this over to a ManagerThread or expire it when done
2244                HandlerThread callbackThread = new HandlerThread("ConnectivityManager");
2245                callbackThread.start();
2246                sCallbackHandler = new CallbackHandler(callbackThread.getLooper(),
2247                        sNetworkCallback, sCallbackRefCount, this);
2248            }
2249        }
2250    }
2251
2252    private void decCallbackHandlerRefCount() {
2253        synchronized(sCallbackRefCount) {
2254            if (sCallbackRefCount.decrementAndGet() == 0) {
2255                sCallbackHandler.obtainMessage(CALLBACK_EXIT).sendToTarget();
2256                sCallbackHandler = null;
2257            }
2258        }
2259    }
2260
2261    static final HashMap<NetworkRequest, NetworkCallback> sNetworkCallback =
2262            new HashMap<NetworkRequest, NetworkCallback>();
2263    static final AtomicInteger sCallbackRefCount = new AtomicInteger(0);
2264    static CallbackHandler sCallbackHandler = null;
2265
2266    private final static int LISTEN  = 1;
2267    private final static int REQUEST = 2;
2268
2269    private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
2270            NetworkCallback networkCallback, int timeoutSec, int action,
2271            int legacyType) {
2272        if (networkCallback == null) {
2273            throw new IllegalArgumentException("null NetworkCallback");
2274        }
2275        if (need == null) throw new IllegalArgumentException("null NetworkCapabilities");
2276        try {
2277            incCallbackHandlerRefCount();
2278            synchronized(sNetworkCallback) {
2279                if (action == LISTEN) {
2280                    networkCallback.networkRequest = mService.listenForNetwork(need,
2281                            new Messenger(sCallbackHandler), new Binder());
2282                } else {
2283                    networkCallback.networkRequest = mService.requestNetwork(need,
2284                            new Messenger(sCallbackHandler), timeoutSec, new Binder(), legacyType);
2285                }
2286                if (networkCallback.networkRequest != null) {
2287                    sNetworkCallback.put(networkCallback.networkRequest, networkCallback);
2288                }
2289            }
2290        } catch (RemoteException e) {}
2291        if (networkCallback.networkRequest == null) decCallbackHandlerRefCount();
2292        return networkCallback.networkRequest;
2293    }
2294
2295    /**
2296     * Request a network to satisfy a set of {@link NetworkCapabilities}.
2297     *
2298     * This {@link NetworkRequest} will live until released via
2299     * {@link #unregisterNetworkCallback} or the calling application exits.
2300     * Status of the request can be followed by listening to the various
2301     * callbacks described in {@link NetworkCallback}.  The {@link Network}
2302     * can be used to direct traffic to the network.
2303     *
2304     * @param request {@link NetworkRequest} describing this request.
2305     * @param networkCallback The {@link NetworkCallback} to be utilized for this
2306     *                        request.  Note the callback must not be shared - they
2307     *                        uniquely specify this request.
2308     */
2309    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) {
2310        sendRequestForNetwork(request.networkCapabilities, networkCallback, 0,
2311                REQUEST, inferLegacyTypeForNetworkCapabilities(request.networkCapabilities));
2312    }
2313
2314    /**
2315     * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
2316     * by a timeout.
2317     *
2318     * This function behaves identically to the non-timedout version, but if a suitable
2319     * network is not found within the given time (in milliseconds) the
2320     * {@link NetworkCallback#unavailable} callback is called.  The request must
2321     * still be released normally by calling {@link releaseNetworkRequest}.
2322     * @param request {@link NetworkRequest} describing this request.
2323     * @param networkCallback The callbacks to be utilized for this request.  Note
2324     *                        the callbacks must not be shared - they uniquely specify
2325     *                        this request.
2326     * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
2327     *                  before {@link NetworkCallback#unavailable} is called.
2328     * @hide
2329     */
2330    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
2331            int timeoutMs) {
2332        sendRequestForNetwork(request.networkCapabilities, networkCallback, timeoutMs,
2333                REQUEST, inferLegacyTypeForNetworkCapabilities(request.networkCapabilities));
2334    }
2335
2336    /**
2337     * The maximum number of milliseconds the framework will look for a suitable network
2338     * during a timeout-equiped call to {@link requestNetwork}.
2339     * {@hide}
2340     */
2341    public final static int MAX_NETWORK_REQUEST_TIMEOUT_MS = 100 * 60 * 1000;
2342
2343    /**
2344     * The lookup key for a {@link Network} object included with the intent after
2345     * successfully finding a network for the applications request.  Retrieve it with
2346     * {@link android.content.Intent#getParcelableExtra(String)}.
2347     * <p>
2348     * Note that if you intend to invoke {@link Network#openConnection(java.net.URL)}
2349     * then you must get a ConnectivityManager instance before doing so.
2350     */
2351    public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
2352
2353    /**
2354     * The lookup key for a {@link NetworkRequest} object included with the intent after
2355     * successfully finding a network for the applications request.  Retrieve it with
2356     * {@link android.content.Intent#getParcelableExtra(String)}.
2357     */
2358    public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
2359
2360
2361    /**
2362     * Request a network to satisfy a set of {@link NetworkCapabilities}.
2363     *
2364     * This function behaves identically to the version that takes a NetworkCallback, but instead
2365     * of {@link NetworkCallback} a {@link PendingIntent} is used.  This means
2366     * the request may outlive the calling application and get called back when a suitable
2367     * network is found.
2368     * <p>
2369     * The operation is an Intent broadcast that goes to a broadcast receiver that
2370     * you registered with {@link Context#registerReceiver} or through the
2371     * &lt;receiver&gt; tag in an AndroidManifest.xml file
2372     * <p>
2373     * The operation Intent is delivered with two extras, a {@link Network} typed
2374     * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest}
2375     * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing
2376     * the original requests parameters.  It is important to create a new,
2377     * {@link NetworkCallback} based request before completing the processing of the
2378     * Intent to reserve the network or it will be released shortly after the Intent
2379     * is processed.
2380     * <p>
2381     * If there is already an request for this Intent registered (with the equality of
2382     * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
2383     * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
2384     * <p>
2385     * The request may be released normally by calling
2386     * {@link #releaseNetworkRequest(android.app.PendingIntent)}.
2387     *
2388     * @param request {@link NetworkRequest} describing this request.
2389     * @param operation Action to perform when the network is available (corresponds
2390     *                  to the {@link NetworkCallback#onAvailable} call.  Typically
2391     *                  comes from {@link PendingIntent#getBroadcast}. Cannot be null.
2392     */
2393    public void requestNetwork(NetworkRequest request, PendingIntent operation) {
2394        checkPendingIntent(operation);
2395        try {
2396            mService.pendingRequestForNetwork(request.networkCapabilities, operation);
2397        } catch (RemoteException e) {}
2398    }
2399
2400    /**
2401     * Removes a request made via {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)}
2402     * <p>
2403     * This method has the same behavior as {@link #unregisterNetworkCallback} with respect to
2404     * releasing network resources and disconnecting.
2405     *
2406     * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the
2407     *                  PendingIntent passed to
2408     *                  {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)} with the
2409     *                  corresponding NetworkRequest you'd like to remove. Cannot be null.
2410     */
2411    public void releaseNetworkRequest(PendingIntent operation) {
2412        checkPendingIntent(operation);
2413        try {
2414            mService.releasePendingNetworkRequest(operation);
2415        } catch (RemoteException e) {}
2416    }
2417
2418    private void checkPendingIntent(PendingIntent intent) {
2419        if (intent == null) {
2420            throw new IllegalArgumentException("PendingIntent cannot be null.");
2421        }
2422    }
2423
2424    /**
2425     * Registers to receive notifications about all networks which satisfy the given
2426     * {@link NetworkRequest}.  The callbacks will continue to be called until
2427     * either the application exits or {@link #unregisterNetworkCallback} is called
2428     *
2429     * @param request {@link NetworkRequest} describing this request.
2430     * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
2431     *                        networks change state.
2432     */
2433    public void registerNetworkCallback(NetworkRequest request, NetworkCallback networkCallback) {
2434        sendRequestForNetwork(request.networkCapabilities, networkCallback, 0, LISTEN, TYPE_NONE);
2435    }
2436
2437    /**
2438     * Unregisters callbacks about and possibly releases networks originating from
2439     * {@link #requestNetwork} and {@link #registerNetworkCallback} calls.  If the
2440     * given {@code NetworkCallback} had previously been used with {@code #requestNetwork},
2441     * any networks that had been connected to only to satisfy that request will be
2442     * disconnected.
2443     *
2444     * @param networkCallback The {@link NetworkCallback} used when making the request.
2445     */
2446    public void unregisterNetworkCallback(NetworkCallback networkCallback) {
2447        if (networkCallback == null || networkCallback.networkRequest == null ||
2448                networkCallback.networkRequest.requestId == REQUEST_ID_UNSET) {
2449            throw new IllegalArgumentException("Invalid NetworkCallback");
2450        }
2451        try {
2452            mService.releaseNetworkRequest(networkCallback.networkRequest);
2453        } catch (RemoteException e) {}
2454    }
2455
2456    /**
2457     * Binds the current process to {@code network}.  All Sockets created in the future
2458     * (and not explicitly bound via a bound SocketFactory from
2459     * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
2460     * {@code network}.  All host name resolutions will be limited to {@code network} as well.
2461     * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
2462     * work and all host name resolutions will fail.  This is by design so an application doesn't
2463     * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
2464     * To clear binding pass {@code null} for {@code network}.  Using individually bound
2465     * Sockets created by Network.getSocketFactory().createSocket() and
2466     * performing network-specific host name resolutions via
2467     * {@link Network#getAllByName Network.getAllByName} is preferred to calling
2468     * {@code bindProcessToNetwork}.
2469     *
2470     * @param network The {@link Network} to bind the current process to, or {@code null} to clear
2471     *                the current binding.
2472     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
2473     */
2474    public boolean bindProcessToNetwork(Network network) {
2475        // Forcing callers to call thru non-static function ensures ConnectivityManager
2476        // instantiated.
2477        return setProcessDefaultNetwork(network);
2478    }
2479
2480    /**
2481     * Binds the current process to {@code network}.  All Sockets created in the future
2482     * (and not explicitly bound via a bound SocketFactory from
2483     * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
2484     * {@code network}.  All host name resolutions will be limited to {@code network} as well.
2485     * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
2486     * work and all host name resolutions will fail.  This is by design so an application doesn't
2487     * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
2488     * To clear binding pass {@code null} for {@code network}.  Using individually bound
2489     * Sockets created by Network.getSocketFactory().createSocket() and
2490     * performing network-specific host name resolutions via
2491     * {@link Network#getAllByName Network.getAllByName} is preferred to calling
2492     * {@code setProcessDefaultNetwork}.
2493     *
2494     * @param network The {@link Network} to bind the current process to, or {@code null} to clear
2495     *                the current binding.
2496     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
2497     * @deprecated This function can throw {@link IllegalStateException}.  Use
2498     *             {@link #bindProcessToNetwork} instead.  {@code bindProcessToNetwork}
2499     *             is a direct replacement.
2500     */
2501    public static boolean setProcessDefaultNetwork(Network network) {
2502        int netId = (network == null) ? NETID_UNSET : network.netId;
2503        if (netId == NetworkUtils.getBoundNetworkForProcess()) {
2504            return true;
2505        }
2506        if (NetworkUtils.bindProcessToNetwork(netId)) {
2507            // Set HTTP proxy system properties to match network.
2508            // TODO: Deprecate this static method and replace it with a non-static version.
2509            Proxy.setHttpProxySystemProperty(getInstance().getDefaultProxy());
2510            // Must flush DNS cache as new network may have different DNS resolutions.
2511            InetAddress.clearDnsCache();
2512            // Must flush socket pool as idle sockets will be bound to previous network and may
2513            // cause subsequent fetches to be performed on old network.
2514            NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
2515            return true;
2516        } else {
2517            return false;
2518        }
2519    }
2520
2521    /**
2522     * Returns the {@link Network} currently bound to this process via
2523     * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
2524     *
2525     * @return {@code Network} to which this process is bound, or {@code null}.
2526     */
2527    public Network getBoundNetworkForProcess() {
2528        // Forcing callers to call thru non-static function ensures ConnectivityManager
2529        // instantiated.
2530        return getProcessDefaultNetwork();
2531    }
2532
2533    /**
2534     * Returns the {@link Network} currently bound to this process via
2535     * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
2536     *
2537     * @return {@code Network} to which this process is bound, or {@code null}.
2538     * @deprecated Using this function can lead to other functions throwing
2539     *             {@link IllegalStateException}.  Use {@link #getBoundNetworkForProcess} instead.
2540     *             {@code getBoundNetworkForProcess} is a direct replacement.
2541     */
2542    public static Network getProcessDefaultNetwork() {
2543        int netId = NetworkUtils.getBoundNetworkForProcess();
2544        if (netId == NETID_UNSET) return null;
2545        return new Network(netId);
2546    }
2547
2548    /**
2549     * Binds host resolutions performed by this process to {@code network}.
2550     * {@link #bindProcessToNetwork} takes precedence over this setting.
2551     *
2552     * @param network The {@link Network} to bind host resolutions from the current process to, or
2553     *                {@code null} to clear the current binding.
2554     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
2555     * @hide
2556     * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}.
2557     */
2558    public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
2559        return NetworkUtils.bindProcessToNetworkForHostResolution(
2560                network == null ? NETID_UNSET : network.netId);
2561    }
2562}
2563