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