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