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