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