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