OSDN Git Service

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