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