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