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