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