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