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