ConnectivityManager.java revision bb2e0e98160f099261876794518d4db62e309aec
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 action 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     * When the app handling this action believes the user has signed in to
112     * the network and the captive portal has been dismissed, the app should call
113     * {@link #reportCaptivePortalDismissed} so the system can reevaluate the network.
114     * If reevaluation finds the network no longer subject to a captive portal,
115     * the network may become the default active data network.
116     * <p/>
117     * When the app handling this action believes the user explicitly wants
118     * to ignore the captive portal and the network, the app should call
119     * {@link #ignoreNetworkWithCaptivePortal}.
120     * <p/>
121     * Note that this action includes a {@code String} extra named
122     * {@link #EXTRA_CAPTIVE_PORTAL_TOKEN} that must
123     * be passed in to {@link #reportCaptivePortalDismissed} and
124     * {@link #ignoreNetworkWithCaptivePortal}.
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    /**
192     * The lookup key for a string that is sent out with
193     * {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN}. This string must be
194     * passed in to {@link #reportCaptivePortalDismissed} and
195     * {@link #ignoreNetworkWithCaptivePortal}. Retrieve it with
196     * {@link android.content.Intent#getStringExtra(String)}.
197     */
198    public static final String EXTRA_CAPTIVE_PORTAL_TOKEN = "captivePortalToken";
199
200    /**
201     * Broadcast action to indicate the change of data activity status
202     * (idle or active) on a network in a recent period.
203     * The network becomes active when data transmission is started, or
204     * idle if there is no data transmission for a period of time.
205     * {@hide}
206     */
207    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
208    public static final String ACTION_DATA_ACTIVITY_CHANGE = "android.net.conn.DATA_ACTIVITY_CHANGE";
209    /**
210     * The lookup key for an enum that indicates the network device type on which this data activity
211     * change happens.
212     * {@hide}
213     */
214    public static final String EXTRA_DEVICE_TYPE = "deviceType";
215    /**
216     * The lookup key for a boolean that indicates the device is active or not. {@code true} means
217     * it is actively sending or receiving data and {@code false} means it is idle.
218     * {@hide}
219     */
220    public static final String EXTRA_IS_ACTIVE = "isActive";
221    /**
222     * The lookup key for a long that contains the timestamp (nanos) of the radio state change.
223     * {@hide}
224     */
225    public static final String EXTRA_REALTIME_NS = "tsNanos";
226
227    /**
228     * Broadcast Action: The setting for background data usage has changed
229     * values. Use {@link #getBackgroundDataSetting()} to get the current value.
230     * <p>
231     * If an application uses the network in the background, it should listen
232     * for this broadcast and stop using the background data if the value is
233     * {@code false}.
234     * <p>
235     *
236     * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability
237     *             of background data depends on several combined factors, and
238     *             this broadcast is no longer sent. Instead, when background
239     *             data is unavailable, {@link #getActiveNetworkInfo()} will now
240     *             appear disconnected. During first boot after a platform
241     *             upgrade, this broadcast will be sent once if
242     *             {@link #getBackgroundDataSetting()} was {@code false} before
243     *             the upgrade.
244     */
245    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
246    @Deprecated
247    public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED =
248            "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
249
250    /**
251     * Broadcast Action: The network connection may not be good
252     * uses {@code ConnectivityManager.EXTRA_INET_CONDITION} and
253     * {@code ConnectivityManager.EXTRA_NETWORK_INFO} to specify
254     * the network and it's condition.
255     * @hide
256     */
257    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
258    public static final String INET_CONDITION_ACTION =
259            "android.net.conn.INET_CONDITION_ACTION";
260
261    /**
262     * Broadcast Action: A tetherable connection has come or gone.
263     * Uses {@code ConnectivityManager.EXTRA_AVAILABLE_TETHER},
264     * {@code ConnectivityManager.EXTRA_ACTIVE_TETHER} and
265     * {@code ConnectivityManager.EXTRA_ERRORED_TETHER} to indicate
266     * the current state of tethering.  Each include a list of
267     * interface names in that state (may be empty).
268     * @hide
269     */
270    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
271    public static final String ACTION_TETHER_STATE_CHANGED =
272            "android.net.conn.TETHER_STATE_CHANGED";
273
274    /**
275     * @hide
276     * gives a String[] listing all the interfaces configured for
277     * tethering and currently available for tethering.
278     */
279    public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
280
281    /**
282     * @hide
283     * gives a String[] listing all the interfaces currently tethered
284     * (ie, has dhcp support and packets potentially forwarded/NATed)
285     */
286    public static final String EXTRA_ACTIVE_TETHER = "activeArray";
287
288    /**
289     * @hide
290     * gives a String[] listing all the interfaces we tried to tether and
291     * failed.  Use {@link #getLastTetherError} to find the error code
292     * for any interfaces listed here.
293     */
294    public static final String EXTRA_ERRORED_TETHER = "erroredArray";
295
296    /**
297     * Broadcast Action: The captive portal tracker has finished its test.
298     * Sent only while running Setup Wizard, in lieu of showing a user
299     * notification.
300     * @hide
301     */
302    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
303    public static final String ACTION_CAPTIVE_PORTAL_TEST_COMPLETED =
304            "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED";
305    /**
306     * The lookup key for a boolean that indicates whether a captive portal was detected.
307     * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
308     * @hide
309     */
310    public static final String EXTRA_IS_CAPTIVE_PORTAL = "captivePortal";
311
312    /**
313     * Action used to display a dialog that asks the user whether to connect to a network that is
314     * not validated. This intent is used to start the dialog in settings via startActivity.
315     *
316     * @hide
317     */
318    public static final String ACTION_PROMPT_UNVALIDATED = "android.net.conn.PROMPT_UNVALIDATED";
319
320    /**
321     * The absence of a connection type.
322     * @hide
323     */
324    public static final int TYPE_NONE        = -1;
325
326    /**
327     * The Mobile data connection.  When active, all data traffic
328     * will use this network type's interface by default
329     * (it has a default route)
330     */
331    public static final int TYPE_MOBILE      = 0;
332    /**
333     * The WIFI data connection.  When active, all data traffic
334     * will use this network type's interface by default
335     * (it has a default route).
336     */
337    public static final int TYPE_WIFI        = 1;
338    /**
339     * An MMS-specific Mobile data connection.  This network type may use the
340     * same network interface as {@link #TYPE_MOBILE} or it may use a different
341     * one.  This is used by applications needing to talk to the carrier's
342     * Multimedia Messaging Service servers.
343     *
344     * @deprecated Applications should instead use
345     *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that
346     *         provides the {@link NetworkCapabilities#NET_CAPABILITY_MMS} capability.
347     */
348    public static final int TYPE_MOBILE_MMS  = 2;
349    /**
350     * A SUPL-specific Mobile data connection.  This network type may use the
351     * same network interface as {@link #TYPE_MOBILE} or it may use a different
352     * one.  This is used by applications needing to talk to the carrier's
353     * Secure User Plane Location servers for help locating the device.
354     *
355     * @deprecated Applications should instead use
356     *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that
357     *         provides the {@link NetworkCapabilities#NET_CAPABILITY_SUPL} capability.
358     */
359    public static final int TYPE_MOBILE_SUPL = 3;
360    /**
361     * A DUN-specific Mobile data connection.  This network type may use the
362     * same network interface as {@link #TYPE_MOBILE} or it may use a different
363     * one.  This is sometimes by the system when setting up an upstream connection
364     * for tethering so that the carrier is aware of DUN traffic.
365     */
366    public static final int TYPE_MOBILE_DUN  = 4;
367    /**
368     * A High Priority Mobile data connection.  This network type uses the
369     * same network interface as {@link #TYPE_MOBILE} but the routing setup
370     * is different.
371     *
372     * @deprecated Applications should instead use
373     *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that
374     *         uses the {@link NetworkCapabilities#TRANSPORT_CELLULAR} transport.
375     */
376    public static final int TYPE_MOBILE_HIPRI = 5;
377    /**
378     * The WiMAX data connection.  When active, all data traffic
379     * will use this network type's interface by default
380     * (it has a default route).
381     */
382    public static final int TYPE_WIMAX       = 6;
383
384    /**
385     * The Bluetooth data connection.  When active, all data traffic
386     * will use this network type's interface by default
387     * (it has a default route).
388     */
389    public static final int TYPE_BLUETOOTH   = 7;
390
391    /**
392     * Dummy data connection.  This should not be used on shipping devices.
393     */
394    public static final int TYPE_DUMMY       = 8;
395
396    /**
397     * The Ethernet data connection.  When active, all data traffic
398     * will use this network type's interface by default
399     * (it has a default route).
400     */
401    public static final int TYPE_ETHERNET    = 9;
402
403    /**
404     * Over the air Administration.
405     * {@hide}
406     */
407    public static final int TYPE_MOBILE_FOTA = 10;
408
409    /**
410     * IP Multimedia Subsystem.
411     * {@hide}
412     */
413    public static final int TYPE_MOBILE_IMS  = 11;
414
415    /**
416     * Carrier Branded Services.
417     * {@hide}
418     */
419    public static final int TYPE_MOBILE_CBS  = 12;
420
421    /**
422     * A Wi-Fi p2p connection. Only requesting processes will have access to
423     * the peers connected.
424     * {@hide}
425     */
426    public static final int TYPE_WIFI_P2P    = 13;
427
428    /**
429     * The network to use for initially attaching to the network
430     * {@hide}
431     */
432    public static final int TYPE_MOBILE_IA = 14;
433
434    /**
435     * Emergency PDN connection for emergency calls
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    /**
960     * Removes the NET_CAPABILITY_NOT_RESTRICTED capability from the given
961     * NetworkCapabilities object if all the capabilities it provides are
962     * typically provided by restricted networks.
963     *
964     * TODO: consider:
965     * - Moving to NetworkCapabilities
966     * - Renaming it to guessRestrictedCapability and make it set the
967     *   restricted capability bit in addition to clearing it.
968     * @hide
969     */
970    public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
971        for (int capability : nc.getCapabilities()) {
972            switch (capability) {
973                case NetworkCapabilities.NET_CAPABILITY_CBS:
974                case NetworkCapabilities.NET_CAPABILITY_DUN:
975                case NetworkCapabilities.NET_CAPABILITY_EIMS:
976                case NetworkCapabilities.NET_CAPABILITY_FOTA:
977                case NetworkCapabilities.NET_CAPABILITY_IA:
978                case NetworkCapabilities.NET_CAPABILITY_IMS:
979                case NetworkCapabilities.NET_CAPABILITY_RCS:
980                case NetworkCapabilities.NET_CAPABILITY_XCAP:
981                case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED: //there by default
982                    continue;
983                default:
984                    // At least one capability usually provided by unrestricted
985                    // networks. Conclude that this network is unrestricted.
986                    return;
987            }
988        }
989        // All the capabilities are typically provided by restricted networks.
990        // Conclude that this network is restricted.
991        nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
992    }
993
994    private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
995        if (networkType == TYPE_MOBILE) {
996            int cap = -1;
997            if ("enableMMS".equals(feature)) {
998                cap = NetworkCapabilities.NET_CAPABILITY_MMS;
999            } else if ("enableSUPL".equals(feature)) {
1000                cap = NetworkCapabilities.NET_CAPABILITY_SUPL;
1001            } else if ("enableDUN".equals(feature) || "enableDUNAlways".equals(feature)) {
1002                cap = NetworkCapabilities.NET_CAPABILITY_DUN;
1003            } else if ("enableHIPRI".equals(feature)) {
1004                cap = NetworkCapabilities.NET_CAPABILITY_INTERNET;
1005            } else if ("enableFOTA".equals(feature)) {
1006                cap = NetworkCapabilities.NET_CAPABILITY_FOTA;
1007            } else if ("enableIMS".equals(feature)) {
1008                cap = NetworkCapabilities.NET_CAPABILITY_IMS;
1009            } else if ("enableCBS".equals(feature)) {
1010                cap = NetworkCapabilities.NET_CAPABILITY_CBS;
1011            } else {
1012                return null;
1013            }
1014            NetworkCapabilities netCap = new NetworkCapabilities();
1015            netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
1016            maybeMarkCapabilitiesRestricted(netCap);
1017            return netCap;
1018        } else if (networkType == TYPE_WIFI) {
1019            if ("p2p".equals(feature)) {
1020                NetworkCapabilities netCap = new NetworkCapabilities();
1021                netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
1022                netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
1023                maybeMarkCapabilitiesRestricted(netCap);
1024                return netCap;
1025            }
1026        }
1027        return null;
1028    }
1029
1030    /**
1031     * Guess what the network request was trying to say so that the resulting
1032     * network is accessible via the legacy (deprecated) API such as
1033     * requestRouteToHost.
1034     * This means we should try to be fairly preceise about transport and
1035     * capability but ignore things such as networkSpecifier.
1036     * If the request has more than one transport or capability it doesn't
1037     * match the old legacy requests (they selected only single transport/capability)
1038     * so this function cannot map the request to a single legacy type and
1039     * the resulting network will not be available to the legacy APIs.
1040     *
1041     * TODO - This should be removed when the legacy APIs are removed.
1042     */
1043    private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
1044        if (netCap == null) {
1045            return TYPE_NONE;
1046        }
1047
1048        if (!netCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
1049            return TYPE_NONE;
1050        }
1051
1052        String type = null;
1053        int result = TYPE_NONE;
1054
1055        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
1056            type = "enableCBS";
1057            result = TYPE_MOBILE_CBS;
1058        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
1059            type = "enableIMS";
1060            result = TYPE_MOBILE_IMS;
1061        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
1062            type = "enableFOTA";
1063            result = TYPE_MOBILE_FOTA;
1064        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
1065            type = "enableDUN";
1066            result = TYPE_MOBILE_DUN;
1067        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
1068            type = "enableSUPL";
1069            result = TYPE_MOBILE_SUPL;
1070        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
1071            type = "enableMMS";
1072            result = TYPE_MOBILE_MMS;
1073        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
1074            type = "enableHIPRI";
1075            result = TYPE_MOBILE_HIPRI;
1076        }
1077        if (type != null) {
1078            NetworkCapabilities testCap = networkCapabilitiesForFeature(TYPE_MOBILE, type);
1079            if (testCap.equalsNetCapabilities(netCap) && testCap.equalsTransportTypes(netCap)) {
1080                return result;
1081            }
1082        }
1083        return TYPE_NONE;
1084    }
1085
1086    private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
1087        if (netCap == null) return TYPE_NONE;
1088        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
1089            return TYPE_MOBILE_CBS;
1090        }
1091        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
1092            return TYPE_MOBILE_IMS;
1093        }
1094        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
1095            return TYPE_MOBILE_FOTA;
1096        }
1097        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
1098            return TYPE_MOBILE_DUN;
1099        }
1100        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
1101            return TYPE_MOBILE_SUPL;
1102        }
1103        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
1104            return TYPE_MOBILE_MMS;
1105        }
1106        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
1107            return TYPE_MOBILE_HIPRI;
1108        }
1109        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) {
1110            return TYPE_WIFI_P2P;
1111        }
1112        return TYPE_NONE;
1113    }
1114
1115    private static class LegacyRequest {
1116        NetworkCapabilities networkCapabilities;
1117        NetworkRequest networkRequest;
1118        int expireSequenceNumber;
1119        Network currentNetwork;
1120        int delay = -1;
1121
1122        private void clearDnsBinding() {
1123            if (currentNetwork != null) {
1124                currentNetwork = null;
1125                setProcessDefaultNetworkForHostResolution(null);
1126            }
1127        }
1128
1129        NetworkCallback networkCallback = new NetworkCallback() {
1130            @Override
1131            public void onAvailable(Network network) {
1132                currentNetwork = network;
1133                Log.d(TAG, "startUsingNetworkFeature got Network:" + network);
1134                setProcessDefaultNetworkForHostResolution(network);
1135            }
1136            @Override
1137            public void onLost(Network network) {
1138                if (network.equals(currentNetwork)) clearDnsBinding();
1139                Log.d(TAG, "startUsingNetworkFeature lost Network:" + network);
1140            }
1141        };
1142    }
1143
1144    private static HashMap<NetworkCapabilities, LegacyRequest> sLegacyRequests =
1145            new HashMap<NetworkCapabilities, LegacyRequest>();
1146
1147    private NetworkRequest findRequestForFeature(NetworkCapabilities netCap) {
1148        synchronized (sLegacyRequests) {
1149            LegacyRequest l = sLegacyRequests.get(netCap);
1150            if (l != null) return l.networkRequest;
1151        }
1152        return null;
1153    }
1154
1155    private void renewRequestLocked(LegacyRequest l) {
1156        l.expireSequenceNumber++;
1157        Log.d(TAG, "renewing request to seqNum " + l.expireSequenceNumber);
1158        sendExpireMsgForFeature(l.networkCapabilities, l.expireSequenceNumber, l.delay);
1159    }
1160
1161    private void expireRequest(NetworkCapabilities netCap, int sequenceNum) {
1162        int ourSeqNum = -1;
1163        synchronized (sLegacyRequests) {
1164            LegacyRequest l = sLegacyRequests.get(netCap);
1165            if (l == null) return;
1166            ourSeqNum = l.expireSequenceNumber;
1167            if (l.expireSequenceNumber == sequenceNum) removeRequestForFeature(netCap);
1168        }
1169        Log.d(TAG, "expireRequest with " + ourSeqNum + ", " + sequenceNum);
1170    }
1171
1172    private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) {
1173        int delay = -1;
1174        int type = legacyTypeForNetworkCapabilities(netCap);
1175        try {
1176            delay = mService.getRestoreDefaultNetworkDelay(type);
1177        } catch (RemoteException e) {}
1178        LegacyRequest l = new LegacyRequest();
1179        l.networkCapabilities = netCap;
1180        l.delay = delay;
1181        l.expireSequenceNumber = 0;
1182        l.networkRequest = sendRequestForNetwork(netCap, l.networkCallback, 0,
1183                REQUEST, type);
1184        if (l.networkRequest == null) return null;
1185        sLegacyRequests.put(netCap, l);
1186        sendExpireMsgForFeature(netCap, l.expireSequenceNumber, delay);
1187        return l.networkRequest;
1188    }
1189
1190    private void sendExpireMsgForFeature(NetworkCapabilities netCap, int seqNum, int delay) {
1191        if (delay >= 0) {
1192            Log.d(TAG, "sending expire msg with seqNum " + seqNum + " and delay " + delay);
1193            Message msg = sCallbackHandler.obtainMessage(EXPIRE_LEGACY_REQUEST, seqNum, 0, netCap);
1194            sCallbackHandler.sendMessageDelayed(msg, delay);
1195        }
1196    }
1197
1198    private boolean removeRequestForFeature(NetworkCapabilities netCap) {
1199        final LegacyRequest l;
1200        synchronized (sLegacyRequests) {
1201            l = sLegacyRequests.remove(netCap);
1202        }
1203        if (l == null) return false;
1204        unregisterNetworkCallback(l.networkCallback);
1205        l.clearDnsBinding();
1206        return true;
1207    }
1208
1209    /**
1210     * Ensure that a network route exists to deliver traffic to the specified
1211     * host via the specified network interface. An attempt to add a route that
1212     * already exists is ignored, but treated as successful.
1213     * <p>This method requires the caller to hold the permission
1214     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
1215     * @param networkType the type of the network over which traffic to the specified
1216     * host is to be routed
1217     * @param hostAddress the IP address of the host to which the route is desired
1218     * @return {@code true} on success, {@code false} on failure
1219     *
1220     * @deprecated Deprecated in favor of the
1221     *             {@link #requestNetwork(NetworkRequest, NetworkCallback)},
1222     *             {@link #bindProcessToNetwork} and {@link Network#getSocketFactory} API.
1223     * @removed
1224     */
1225    public boolean requestRouteToHost(int networkType, int hostAddress) {
1226        return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress));
1227    }
1228
1229    /**
1230     * Ensure that a network route exists to deliver traffic to the specified
1231     * host via the specified network interface. An attempt to add a route that
1232     * already exists is ignored, but treated as successful.
1233     * <p>This method requires the caller to hold the permission
1234     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
1235     * @param networkType the type of the network over which traffic to the specified
1236     * host is to be routed
1237     * @param hostAddress the IP address of the host to which the route is desired
1238     * @return {@code true} on success, {@code false} on failure
1239     * @hide
1240     * @deprecated Deprecated in favor of the {@link #requestNetwork} and
1241     *             {@link #bindProcessToNetwork} API.
1242     * @removed
1243     */
1244    public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
1245        try {
1246            return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress());
1247        } catch (RemoteException e) {
1248            return false;
1249        }
1250    }
1251
1252    /**
1253     * Returns the value of the setting for background data usage. If false,
1254     * applications should not use the network if the application is not in the
1255     * foreground. Developers should respect this setting, and check the value
1256     * of this before performing any background data operations.
1257     * <p>
1258     * All applications that have background services that use the network
1259     * should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}.
1260     * <p>
1261     * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability of
1262     * background data depends on several combined factors, and this method will
1263     * always return {@code true}. Instead, when background data is unavailable,
1264     * {@link #getActiveNetworkInfo()} will now appear disconnected.
1265     *
1266     * @return Whether background data usage is allowed.
1267     */
1268    @Deprecated
1269    public boolean getBackgroundDataSetting() {
1270        // assume that background data is allowed; final authority is
1271        // NetworkInfo which may be blocked.
1272        return true;
1273    }
1274
1275    /**
1276     * Sets the value of the setting for background data usage.
1277     *
1278     * @param allowBackgroundData Whether an application should use data while
1279     *            it is in the background.
1280     *
1281     * @attr ref android.Manifest.permission#CHANGE_BACKGROUND_DATA_SETTING
1282     * @see #getBackgroundDataSetting()
1283     * @hide
1284     */
1285    @Deprecated
1286    public void setBackgroundDataSetting(boolean allowBackgroundData) {
1287        // ignored
1288    }
1289
1290    /**
1291     * Return quota status for the current active network, or {@code null} if no
1292     * network is active. Quota status can change rapidly, so these values
1293     * shouldn't be cached.
1294     *
1295     * <p>This method requires the caller to hold the permission
1296     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1297     *
1298     * @hide
1299     */
1300    public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
1301        try {
1302            return mService.getActiveNetworkQuotaInfo();
1303        } catch (RemoteException e) {
1304            return null;
1305        }
1306    }
1307
1308    /**
1309     * @hide
1310     * @deprecated Talk to TelephonyManager directly
1311     */
1312    public boolean getMobileDataEnabled() {
1313        IBinder b = ServiceManager.getService(Context.TELEPHONY_SERVICE);
1314        if (b != null) {
1315            try {
1316                ITelephony it = ITelephony.Stub.asInterface(b);
1317                int subId = SubscriptionManager.getDefaultDataSubId();
1318                Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
1319                boolean retVal = it.getDataEnabled(subId);
1320                Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
1321                        + " retVal=" + retVal);
1322                return retVal;
1323            } catch (RemoteException e) { }
1324        }
1325        Log.d("ConnectivityManager", "getMobileDataEnabled()- remote exception retVal=false");
1326        return false;
1327    }
1328
1329    /**
1330     * Callback for use with {@link ConnectivityManager#addDefaultNetworkActiveListener}
1331     * to find out when the system default network has gone in to a high power state.
1332     */
1333    public interface OnNetworkActiveListener {
1334        /**
1335         * Called on the main thread of the process to report that the current data network
1336         * has become active, and it is now a good time to perform any pending network
1337         * operations.  Note that this listener only tells you when the network becomes
1338         * active; if at any other time you want to know whether it is active (and thus okay
1339         * to initiate network traffic), you can retrieve its instantaneous state with
1340         * {@link ConnectivityManager#isDefaultNetworkActive}.
1341         */
1342        public void onNetworkActive();
1343    }
1344
1345    private INetworkManagementService getNetworkManagementService() {
1346        synchronized (this) {
1347            if (mNMService != null) {
1348                return mNMService;
1349            }
1350            IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
1351            mNMService = INetworkManagementService.Stub.asInterface(b);
1352            return mNMService;
1353        }
1354    }
1355
1356    private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
1357            mNetworkActivityListeners
1358                    = new ArrayMap<OnNetworkActiveListener, INetworkActivityListener>();
1359
1360    /**
1361     * Start listening to reports when the system's default data network is active, meaning it is
1362     * a good time to perform network traffic.  Use {@link #isDefaultNetworkActive()}
1363     * to determine the current state of the system's default network after registering the
1364     * listener.
1365     * <p>
1366     * If the process default network has been set with
1367     * {@link ConnectivityManager#bindProcessToNetwork} this function will not
1368     * reflect the process's default, but the system default.
1369     *
1370     * @param l The listener to be told when the network is active.
1371     */
1372    public void addDefaultNetworkActiveListener(final OnNetworkActiveListener l) {
1373        INetworkActivityListener rl = new INetworkActivityListener.Stub() {
1374            @Override
1375            public void onNetworkActive() throws RemoteException {
1376                l.onNetworkActive();
1377            }
1378        };
1379
1380        try {
1381            getNetworkManagementService().registerNetworkActivityListener(rl);
1382            mNetworkActivityListeners.put(l, rl);
1383        } catch (RemoteException e) {
1384        }
1385    }
1386
1387    /**
1388     * Remove network active listener previously registered with
1389     * {@link #addDefaultNetworkActiveListener}.
1390     *
1391     * @param l Previously registered listener.
1392     */
1393    public void removeDefaultNetworkActiveListener(OnNetworkActiveListener l) {
1394        INetworkActivityListener rl = mNetworkActivityListeners.get(l);
1395        if (rl == null) {
1396            throw new IllegalArgumentException("Listener not registered: " + l);
1397        }
1398        try {
1399            getNetworkManagementService().unregisterNetworkActivityListener(rl);
1400        } catch (RemoteException e) {
1401        }
1402    }
1403
1404    /**
1405     * Return whether the data network is currently active.  An active network means that
1406     * it is currently in a high power state for performing data transmission.  On some
1407     * types of networks, it may be expensive to move and stay in such a state, so it is
1408     * more power efficient to batch network traffic together when the radio is already in
1409     * this state.  This method tells you whether right now is currently a good time to
1410     * initiate network traffic, as the network is already active.
1411     */
1412    public boolean isDefaultNetworkActive() {
1413        try {
1414            return getNetworkManagementService().isNetworkActive();
1415        } catch (RemoteException e) {
1416        }
1417        return false;
1418    }
1419
1420    /**
1421     * {@hide}
1422     */
1423    public ConnectivityManager(IConnectivityManager service) {
1424        mService = checkNotNull(service, "missing IConnectivityManager");
1425        sInstance = this;
1426    }
1427
1428    /** {@hide} */
1429    public static ConnectivityManager from(Context context) {
1430        return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
1431    }
1432
1433    /** {@hide */
1434    public static final void enforceTetherChangePermission(Context context) {
1435        if (context.getResources().getStringArray(
1436                com.android.internal.R.array.config_mobile_hotspot_provision_app).length == 2) {
1437            // Have a provisioning app - must only let system apps (which check this app)
1438            // turn on tethering
1439            context.enforceCallingOrSelfPermission(
1440                    android.Manifest.permission.CONNECTIVITY_INTERNAL, "ConnectivityService");
1441        } else {
1442            context.enforceCallingOrSelfPermission(
1443                    android.Manifest.permission.CHANGE_NETWORK_STATE, "ConnectivityService");
1444        }
1445    }
1446
1447    /**
1448     * @deprecated - use getSystemService. This is a kludge to support static access in certain
1449     *               situations where a Context pointer is unavailable.
1450     * @hide
1451     */
1452    static ConnectivityManager getInstanceOrNull() {
1453        return sInstance;
1454    }
1455
1456    /**
1457     * @deprecated - use getSystemService. This is a kludge to support static access in certain
1458     *               situations where a Context pointer is unavailable.
1459     * @hide
1460     */
1461    private static ConnectivityManager getInstance() {
1462        if (getInstanceOrNull() == null) {
1463            throw new IllegalStateException("No ConnectivityManager yet constructed");
1464        }
1465        return getInstanceOrNull();
1466    }
1467
1468    /**
1469     * Get the set of tetherable, available interfaces.  This list is limited by
1470     * device configuration and current interface existence.
1471     * <p>This method requires the caller to hold the permission
1472     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1473     *
1474     * @return an array of 0 or more Strings of tetherable interface names.
1475     *
1476     * {@hide}
1477     */
1478    public String[] getTetherableIfaces() {
1479        try {
1480            return mService.getTetherableIfaces();
1481        } catch (RemoteException e) {
1482            return new String[0];
1483        }
1484    }
1485
1486    /**
1487     * Get the set of tethered interfaces.
1488     * <p>This method requires the caller to hold the permission
1489     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1490     *
1491     * @return an array of 0 or more String of currently tethered interface names.
1492     *
1493     * {@hide}
1494     */
1495    public String[] getTetheredIfaces() {
1496        try {
1497            return mService.getTetheredIfaces();
1498        } catch (RemoteException e) {
1499            return new String[0];
1500        }
1501    }
1502
1503    /**
1504     * Get the set of interface names which attempted to tether but
1505     * failed.  Re-attempting to tether may cause them to reset to the Tethered
1506     * state.  Alternatively, causing the interface to be destroyed and recreated
1507     * may cause them to reset to the available state.
1508     * {@link ConnectivityManager#getLastTetherError} can be used to get more
1509     * information on the cause of the errors.
1510     * <p>This method requires the caller to hold the permission
1511     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1512     *
1513     * @return an array of 0 or more String indicating the interface names
1514     *        which failed to tether.
1515     *
1516     * {@hide}
1517     */
1518    public String[] getTetheringErroredIfaces() {
1519        try {
1520            return mService.getTetheringErroredIfaces();
1521        } catch (RemoteException e) {
1522            return new String[0];
1523        }
1524    }
1525
1526    /**
1527     * Get the set of tethered dhcp ranges.
1528     *
1529     * @return an array of 0 or more {@code String} of tethered dhcp ranges.
1530     * {@hide}
1531     */
1532    public String[] getTetheredDhcpRanges() {
1533        try {
1534            return mService.getTetheredDhcpRanges();
1535        } catch (RemoteException e) {
1536            return new String[0];
1537        }
1538    }
1539
1540    /**
1541     * Attempt to tether the named interface.  This will setup a dhcp server
1542     * on the interface, forward and NAT IP packets and forward DNS requests
1543     * to the best active upstream network interface.  Note that if no upstream
1544     * IP network interface is available, dhcp will still run and traffic will be
1545     * allowed between the tethered devices and this device, though upstream net
1546     * access will of course fail until an upstream network interface becomes
1547     * active.
1548     * <p>This method requires the caller to hold the permission
1549     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
1550     *
1551     * @param iface the interface name to tether.
1552     * @return error a {@code TETHER_ERROR} value indicating success or failure type
1553     *
1554     * {@hide}
1555     */
1556    public int tether(String iface) {
1557        try {
1558            return mService.tether(iface);
1559        } catch (RemoteException e) {
1560            return TETHER_ERROR_SERVICE_UNAVAIL;
1561        }
1562    }
1563
1564    /**
1565     * Stop tethering the named interface.
1566     * <p>This method requires the caller to hold the permission
1567     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
1568     *
1569     * @param iface the interface name to untether.
1570     * @return error a {@code TETHER_ERROR} value indicating success or failure type
1571     *
1572     * {@hide}
1573     */
1574    public int untether(String iface) {
1575        try {
1576            return mService.untether(iface);
1577        } catch (RemoteException e) {
1578            return TETHER_ERROR_SERVICE_UNAVAIL;
1579        }
1580    }
1581
1582    /**
1583     * Check if the device allows for tethering.  It may be disabled via
1584     * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
1585     * due to device configuration.
1586     * <p>This method requires the caller to hold the permission
1587     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1588     *
1589     * @return a boolean - {@code true} indicating Tethering is supported.
1590     *
1591     * {@hide}
1592     */
1593    public boolean isTetheringSupported() {
1594        try {
1595            return mService.isTetheringSupported();
1596        } catch (RemoteException e) {
1597            return false;
1598        }
1599    }
1600
1601    /**
1602     * Get the list of regular expressions that define any tetherable
1603     * USB network interfaces.  If USB tethering is not supported by the
1604     * device, this list should be empty.
1605     * <p>This method requires the caller to hold the permission
1606     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1607     *
1608     * @return an array of 0 or more regular expression Strings defining
1609     *        what interfaces are considered tetherable usb interfaces.
1610     *
1611     * {@hide}
1612     */
1613    public String[] getTetherableUsbRegexs() {
1614        try {
1615            return mService.getTetherableUsbRegexs();
1616        } catch (RemoteException e) {
1617            return new String[0];
1618        }
1619    }
1620
1621    /**
1622     * Get the list of regular expressions that define any tetherable
1623     * Wifi network interfaces.  If Wifi tethering is not supported by the
1624     * device, this list should be empty.
1625     * <p>This method requires the caller to hold the permission
1626     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1627     *
1628     * @return an array of 0 or more regular expression Strings defining
1629     *        what interfaces are considered tetherable wifi interfaces.
1630     *
1631     * {@hide}
1632     */
1633    public String[] getTetherableWifiRegexs() {
1634        try {
1635            return mService.getTetherableWifiRegexs();
1636        } catch (RemoteException e) {
1637            return new String[0];
1638        }
1639    }
1640
1641    /**
1642     * Get the list of regular expressions that define any tetherable
1643     * Bluetooth network interfaces.  If Bluetooth tethering is not supported by the
1644     * device, this list should be empty.
1645     * <p>This method requires the caller to hold the permission
1646     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1647     *
1648     * @return an array of 0 or more regular expression Strings defining
1649     *        what interfaces are considered tetherable bluetooth interfaces.
1650     *
1651     * {@hide}
1652     */
1653    public String[] getTetherableBluetoothRegexs() {
1654        try {
1655            return mService.getTetherableBluetoothRegexs();
1656        } catch (RemoteException e) {
1657            return new String[0];
1658        }
1659    }
1660
1661    /**
1662     * Attempt to both alter the mode of USB and Tethering of USB.  A
1663     * utility method to deal with some of the complexity of USB - will
1664     * attempt to switch to Rndis and subsequently tether the resulting
1665     * interface on {@code true} or turn off tethering and switch off
1666     * Rndis on {@code false}.
1667     * <p>This method requires the caller to hold the permission
1668     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
1669     *
1670     * @param enable a boolean - {@code true} to enable tethering
1671     * @return error a {@code TETHER_ERROR} value indicating success or failure type
1672     *
1673     * {@hide}
1674     */
1675    public int setUsbTethering(boolean enable) {
1676        try {
1677            return mService.setUsbTethering(enable);
1678        } catch (RemoteException e) {
1679            return TETHER_ERROR_SERVICE_UNAVAIL;
1680        }
1681    }
1682
1683    /** {@hide} */
1684    public static final int TETHER_ERROR_NO_ERROR           = 0;
1685    /** {@hide} */
1686    public static final int TETHER_ERROR_UNKNOWN_IFACE      = 1;
1687    /** {@hide} */
1688    public static final int TETHER_ERROR_SERVICE_UNAVAIL    = 2;
1689    /** {@hide} */
1690    public static final int TETHER_ERROR_UNSUPPORTED        = 3;
1691    /** {@hide} */
1692    public static final int TETHER_ERROR_UNAVAIL_IFACE      = 4;
1693    /** {@hide} */
1694    public static final int TETHER_ERROR_MASTER_ERROR       = 5;
1695    /** {@hide} */
1696    public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
1697    /** {@hide} */
1698    public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
1699    /** {@hide} */
1700    public static final int TETHER_ERROR_ENABLE_NAT_ERROR     = 8;
1701    /** {@hide} */
1702    public static final int TETHER_ERROR_DISABLE_NAT_ERROR    = 9;
1703    /** {@hide} */
1704    public static final int TETHER_ERROR_IFACE_CFG_ERROR      = 10;
1705
1706    /**
1707     * Get a more detailed error code after a Tethering or Untethering
1708     * request asynchronously failed.
1709     * <p>This method requires the caller to hold the permission
1710     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1711     *
1712     * @param iface The name of the interface of interest
1713     * @return error The error code of the last error tethering or untethering the named
1714     *               interface
1715     *
1716     * {@hide}
1717     */
1718    public int getLastTetherError(String iface) {
1719        try {
1720            return mService.getLastTetherError(iface);
1721        } catch (RemoteException e) {
1722            return TETHER_ERROR_SERVICE_UNAVAIL;
1723        }
1724    }
1725
1726    /**
1727     * Report network connectivity status.  This is currently used only
1728     * to alter status bar UI.
1729     * <p>This method requires the caller to hold the permission
1730     * {@link android.Manifest.permission#STATUS_BAR}.
1731     *
1732     * @param networkType The type of network you want to report on
1733     * @param percentage The quality of the connection 0 is bad, 100 is good
1734     * {@hide}
1735     */
1736    public void reportInetCondition(int networkType, int percentage) {
1737        try {
1738            mService.reportInetCondition(networkType, percentage);
1739        } catch (RemoteException e) {
1740        }
1741    }
1742
1743    /**
1744     * Report a problem network to the framework.  This provides a hint to the system
1745     * that there might be connectivity problems on this network and may cause
1746     * the framework to re-evaluate network connectivity and/or switch to another
1747     * network.
1748     *
1749     * @param network The {@link Network} the application was attempting to use
1750     *                or {@code null} to indicate the current default network.
1751     * @deprecated Use {@link #reportNetworkConnectivity} which allows reporting both
1752     *             working and non-working connectivity.
1753     */
1754    public void reportBadNetwork(Network network) {
1755        try {
1756            // One of these will be ignored because it matches system's current state.
1757            // The other will trigger the necessary reevaluation.
1758            mService.reportNetworkConnectivity(network, true);
1759            mService.reportNetworkConnectivity(network, false);
1760        } catch (RemoteException e) {
1761        }
1762    }
1763
1764    /**
1765     * Report to the framework whether a network has working connectivity.
1766     * This provides a hint to the system that a particular network is providing
1767     * working connectivity or not.  In response the framework may re-evaluate
1768     * the network's connectivity and might take further action thereafter.
1769     *
1770     * @param network The {@link Network} the application was attempting to use
1771     *                or {@code null} to indicate the current default network.
1772     * @param hasConnectivity {@code true} if the application was able to successfully access the
1773     *                        Internet using {@code network} or {@code false} if not.
1774     */
1775    public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
1776        try {
1777            mService.reportNetworkConnectivity(network, hasConnectivity);
1778        } catch (RemoteException e) {
1779        }
1780    }
1781
1782    /** {@hide} */
1783    public static final int CAPTIVE_PORTAL_APP_RETURN_DISMISSED    = 0;
1784    /** {@hide} */
1785    public static final int CAPTIVE_PORTAL_APP_RETURN_UNWANTED     = 1;
1786    /** {@hide} */
1787    public static final int CAPTIVE_PORTAL_APP_RETURN_WANTED_AS_IS = 2;
1788
1789    /**
1790     * Called by an app handling the {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN}
1791     * action to indicate to the system that the captive portal has been
1792     * dismissed.  In response the framework will re-evaluate the network's
1793     * connectivity and might take further action thereafter.
1794     *
1795     * @param network The {@link Network} object passed via
1796     *                {@link #EXTRA_NETWORK} with the
1797     *                {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN} action.
1798     * @param actionToken The {@code String} passed via
1799     *                    {@link #EXTRA_CAPTIVE_PORTAL_TOKEN} with the
1800     *                    {@code ACTION_CAPTIVE_PORTAL_SIGN_IN} action.
1801     */
1802    public void reportCaptivePortalDismissed(Network network, String actionToken) {
1803        try {
1804            mService.captivePortalAppResponse(network, CAPTIVE_PORTAL_APP_RETURN_DISMISSED,
1805                    actionToken);
1806        } catch (RemoteException e) {
1807        }
1808    }
1809
1810    /**
1811     * Called by an app handling the {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN}
1812     * action to indicate that the user does not want to pursue signing in to
1813     * captive portal and the system should continue to prefer other networks
1814     * without captive portals for use as the default active data network.  The
1815     * system will not retest the network for a captive portal so as to avoid
1816     * disturbing the user with further sign in to network notifications.
1817     *
1818     * @param network The {@link Network} object passed via
1819     *                {@link #EXTRA_NETWORK} with the
1820     *                {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN} action.
1821     * @param actionToken The {@code String} passed via
1822     *                    {@link #EXTRA_CAPTIVE_PORTAL_TOKEN} with the
1823     *                    {@code ACTION_CAPTIVE_PORTAL_SIGN_IN} action.
1824     */
1825    public void ignoreNetworkWithCaptivePortal(Network network, String actionToken) {
1826        try {
1827            mService.captivePortalAppResponse(network, CAPTIVE_PORTAL_APP_RETURN_UNWANTED,
1828                    actionToken);
1829        } catch (RemoteException e) {
1830        }
1831    }
1832
1833    /**
1834     * Called by an app handling the {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN}
1835     * action to indicate the user wants to use this network as is, even though
1836     * the captive portal is still in place.  The system will treat the network
1837     * as if it did not have a captive portal when selecting the network to use
1838     * as the default active data network. This may result in this network
1839     * becoming the default active data network, which could disrupt network
1840     * connectivity for apps because the captive portal is still in place.
1841     *
1842     * @param network The {@link Network} object passed via
1843     *                {@link #EXTRA_NETWORK} with the
1844     *                {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN} action.
1845     * @param actionToken The {@code String} passed via
1846     *                    {@link #EXTRA_CAPTIVE_PORTAL_TOKEN} with the
1847     *                    {@code ACTION_CAPTIVE_PORTAL_SIGN_IN} action.
1848     * @hide
1849     */
1850    public void useNetworkWithCaptivePortal(Network network, String actionToken) {
1851        try {
1852            mService.captivePortalAppResponse(network, CAPTIVE_PORTAL_APP_RETURN_WANTED_AS_IS,
1853                    actionToken);
1854        } catch (RemoteException e) {
1855        }
1856    }
1857
1858    /**
1859     * Set a network-independent global http proxy.  This is not normally what you want
1860     * for typical HTTP proxies - they are general network dependent.  However if you're
1861     * doing something unusual like general internal filtering this may be useful.  On
1862     * a private network where the proxy is not accessible, you may break HTTP using this.
1863     * <p>This method requires the caller to hold the permission
1864     * android.Manifest.permission#CONNECTIVITY_INTERNAL.
1865     *
1866     * @param p A {@link ProxyInfo} object defining the new global
1867     *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
1868     * @hide
1869     */
1870    public void setGlobalProxy(ProxyInfo p) {
1871        try {
1872            mService.setGlobalProxy(p);
1873        } catch (RemoteException e) {
1874        }
1875    }
1876
1877    /**
1878     * Retrieve any network-independent global HTTP proxy.
1879     *
1880     * @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
1881     *        if no global HTTP proxy is set.
1882     * @hide
1883     */
1884    public ProxyInfo getGlobalProxy() {
1885        try {
1886            return mService.getGlobalProxy();
1887        } catch (RemoteException e) {
1888            return null;
1889        }
1890    }
1891
1892    /**
1893     * Retrieve the global HTTP proxy, or if no global HTTP proxy is set, a
1894     * network-specific HTTP proxy.  If {@code network} is null, the
1895     * network-specific proxy returned is the proxy of the default active
1896     * network.
1897     *
1898     * @return {@link ProxyInfo} for the current global HTTP proxy, or if no
1899     *         global HTTP proxy is set, {@code ProxyInfo} for {@code network},
1900     *         or when {@code network} is {@code null},
1901     *         the {@code ProxyInfo} for the default active network.  Returns
1902     *         {@code null} when no proxy applies or the caller doesn't have
1903     *         permission to use {@code network}.
1904     * @hide
1905     */
1906    public ProxyInfo getProxyForNetwork(Network network) {
1907        try {
1908            return mService.getProxyForNetwork(network);
1909        } catch (RemoteException e) {
1910            return null;
1911        }
1912    }
1913
1914    /**
1915     * Get the current default HTTP proxy settings.  If a global proxy is set it will be returned,
1916     * otherwise if this process is bound to a {@link Network} using
1917     * {@link #bindProcessToNetwork} then that {@code Network}'s proxy is returned, otherwise
1918     * the default network's proxy is returned.
1919     *
1920     * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no
1921     *        HTTP proxy is active.
1922     */
1923    public ProxyInfo getDefaultProxy() {
1924        return getProxyForNetwork(getBoundNetworkForProcess());
1925    }
1926
1927    /**
1928     * Returns true if the hardware supports the given network type
1929     * else it returns false.  This doesn't indicate we have coverage
1930     * or are authorized onto a network, just whether or not the
1931     * hardware supports it.  For example a GSM phone without a SIM
1932     * should still return {@code true} for mobile data, but a wifi only
1933     * tablet would return {@code false}.
1934     * <p>This method requires the caller to hold the permission
1935     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1936     *
1937     * @param networkType The network type we'd like to check
1938     * @return {@code true} if supported, else {@code false}
1939     *
1940     * @hide
1941     */
1942    public boolean isNetworkSupported(int networkType) {
1943        try {
1944            return mService.isNetworkSupported(networkType);
1945        } catch (RemoteException e) {}
1946        return false;
1947    }
1948
1949    /**
1950     * Returns if the currently active data network is metered. A network is
1951     * classified as metered when the user is sensitive to heavy data usage on
1952     * that connection due to monetary costs, data limitations or
1953     * battery/performance issues. You should check this before doing large
1954     * data transfers, and warn the user or delay the operation until another
1955     * network is available.
1956     * <p>This method requires the caller to hold the permission
1957     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1958     *
1959     * @return {@code true} if large transfers should be avoided, otherwise
1960     *        {@code false}.
1961     */
1962    public boolean isActiveNetworkMetered() {
1963        try {
1964            return mService.isActiveNetworkMetered();
1965        } catch (RemoteException e) {
1966            return false;
1967        }
1968    }
1969
1970    /**
1971     * If the LockdownVpn mechanism is enabled, updates the vpn
1972     * with a reload of its profile.
1973     *
1974     * @return a boolean with {@code} indicating success
1975     *
1976     * <p>This method can only be called by the system UID
1977     * {@hide}
1978     */
1979    public boolean updateLockdownVpn() {
1980        try {
1981            return mService.updateLockdownVpn();
1982        } catch (RemoteException e) {
1983            return false;
1984        }
1985    }
1986
1987    /**
1988     * Check mobile provisioning.
1989     *
1990     * @param suggestedTimeOutMs, timeout in milliseconds
1991     *
1992     * @return time out that will be used, maybe less that suggestedTimeOutMs
1993     * -1 if an error.
1994     *
1995     * {@hide}
1996     */
1997    public int checkMobileProvisioning(int suggestedTimeOutMs) {
1998        int timeOutMs = -1;
1999        try {
2000            timeOutMs = mService.checkMobileProvisioning(suggestedTimeOutMs);
2001        } catch (RemoteException e) {
2002        }
2003        return timeOutMs;
2004    }
2005
2006    /**
2007     * Get the mobile provisioning url.
2008     * {@hide}
2009     */
2010    public String getMobileProvisioningUrl() {
2011        try {
2012            return mService.getMobileProvisioningUrl();
2013        } catch (RemoteException e) {
2014        }
2015        return null;
2016    }
2017
2018    /**
2019     * Set sign in error notification to visible or in visible
2020     *
2021     * @param visible
2022     * @param networkType
2023     *
2024     * {@hide}
2025     * @deprecated Doesn't properly deal with multiple connected networks of the same type.
2026     */
2027    public void setProvisioningNotificationVisible(boolean visible, int networkType,
2028            String action) {
2029        try {
2030            mService.setProvisioningNotificationVisible(visible, networkType, action);
2031        } catch (RemoteException e) {
2032        }
2033    }
2034
2035    /**
2036     * Set the value for enabling/disabling airplane mode
2037     * <p>This method requires the caller to hold the permission
2038     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
2039     *
2040     * @param enable whether to enable airplane mode or not
2041     *
2042     * @hide
2043     */
2044    public void setAirplaneMode(boolean enable) {
2045        try {
2046            mService.setAirplaneMode(enable);
2047        } catch (RemoteException e) {
2048        }
2049    }
2050
2051    /** {@hide} */
2052    public void registerNetworkFactory(Messenger messenger, String name) {
2053        try {
2054            mService.registerNetworkFactory(messenger, name);
2055        } catch (RemoteException e) { }
2056    }
2057
2058    /** {@hide} */
2059    public void unregisterNetworkFactory(Messenger messenger) {
2060        try {
2061            mService.unregisterNetworkFactory(messenger);
2062        } catch (RemoteException e) { }
2063    }
2064
2065    /**
2066     * @hide
2067     * Register a NetworkAgent with ConnectivityService.
2068     * @return NetID corresponding to NetworkAgent.
2069     */
2070    public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
2071            NetworkCapabilities nc, int score, NetworkMisc misc) {
2072        try {
2073            return mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc);
2074        } catch (RemoteException e) {
2075            return NETID_UNSET;
2076        }
2077    }
2078
2079    /**
2080     * Base class for NetworkRequest callbacks.  Used for notifications about network
2081     * changes.  Should be extended by applications wanting notifications.
2082     */
2083    public static class NetworkCallback {
2084        /** @hide */
2085        public static final int PRECHECK     = 1;
2086        /** @hide */
2087        public static final int AVAILABLE    = 2;
2088        /** @hide */
2089        public static final int LOSING       = 3;
2090        /** @hide */
2091        public static final int LOST         = 4;
2092        /** @hide */
2093        public static final int UNAVAIL      = 5;
2094        /** @hide */
2095        public static final int CAP_CHANGED  = 6;
2096        /** @hide */
2097        public static final int PROP_CHANGED = 7;
2098        /** @hide */
2099        public static final int CANCELED     = 8;
2100
2101        /**
2102         * Called when the framework connects to a new network to evaluate whether it satisfies this
2103         * request. If evaluation succeeds, this callback may be followed by an {@link #onAvailable}
2104         * callback. There is no guarantee that this new network will satisfy any requests, or that
2105         * the network will stay connected for longer than the time necessary to evaluate it.
2106         * <p>
2107         * Most applications <b>should not</b> act on this callback, and should instead use
2108         * {@link #onAvailable}. This callback is intended for use by applications that can assist
2109         * the framework in properly evaluating the network &mdash; for example, an application that
2110         * can automatically log in to a captive portal without user intervention.
2111         *
2112         * @param network The {@link Network} of the network that is being evaluated.
2113         *
2114         * @hide
2115         */
2116        public void onPreCheck(Network network) {}
2117
2118        /**
2119         * Called when the framework connects and has declared a new network ready for use.
2120         * This callback may be called more than once if the {@link Network} that is
2121         * satisfying the request changes.
2122         *
2123         * @param network The {@link Network} of the satisfying network.
2124         */
2125        public void onAvailable(Network network) {}
2126
2127        /**
2128         * Called when the network is about to be disconnected.  Often paired with an
2129         * {@link NetworkCallback#onAvailable} call with the new replacement network
2130         * for graceful handover.  This may not be called if we have a hard loss
2131         * (loss without warning).  This may be followed by either a
2132         * {@link NetworkCallback#onLost} call or a
2133         * {@link NetworkCallback#onAvailable} call for this network depending
2134         * on whether we lose or regain it.
2135         *
2136         * @param network The {@link Network} that is about to be disconnected.
2137         * @param maxMsToLive The time in ms the framework will attempt to keep the
2138         *                     network connected.  Note that the network may suffer a
2139         *                     hard loss at any time.
2140         */
2141        public void onLosing(Network network, int maxMsToLive) {}
2142
2143        /**
2144         * Called when the framework has a hard loss of the network or when the
2145         * graceful failure ends.
2146         *
2147         * @param network The {@link Network} lost.
2148         */
2149        public void onLost(Network network) {}
2150
2151        /**
2152         * Called if no network is found in the given timeout time.  If no timeout is given,
2153         * this will not be called.
2154         * @hide
2155         */
2156        public void onUnavailable() {}
2157
2158        /**
2159         * Called when the network the framework connected to for this request
2160         * changes capabilities but still satisfies the stated need.
2161         *
2162         * @param network The {@link Network} whose capabilities have changed.
2163         * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this network.
2164         */
2165        public void onCapabilitiesChanged(Network network,
2166                NetworkCapabilities networkCapabilities) {}
2167
2168        /**
2169         * Called when the network the framework connected to for this request
2170         * changes {@link LinkProperties}.
2171         *
2172         * @param network The {@link Network} whose link properties have changed.
2173         * @param linkProperties The new {@link LinkProperties} for this network.
2174         */
2175        public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {}
2176
2177        private NetworkRequest networkRequest;
2178    }
2179
2180    private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER;
2181    /** @hide obj = pair(NetworkRequest, Network) */
2182    public static final int CALLBACK_PRECHECK           = BASE + 1;
2183    /** @hide obj = pair(NetworkRequest, Network) */
2184    public static final int CALLBACK_AVAILABLE          = BASE + 2;
2185    /** @hide obj = pair(NetworkRequest, Network), arg1 = ttl */
2186    public static final int CALLBACK_LOSING             = BASE + 3;
2187    /** @hide obj = pair(NetworkRequest, Network) */
2188    public static final int CALLBACK_LOST               = BASE + 4;
2189    /** @hide obj = NetworkRequest */
2190    public static final int CALLBACK_UNAVAIL            = BASE + 5;
2191    /** @hide obj = pair(NetworkRequest, Network) */
2192    public static final int CALLBACK_CAP_CHANGED        = BASE + 6;
2193    /** @hide obj = pair(NetworkRequest, Network) */
2194    public static final int CALLBACK_IP_CHANGED         = BASE + 7;
2195    /** @hide obj = NetworkRequest */
2196    public static final int CALLBACK_RELEASED           = BASE + 8;
2197    /** @hide */
2198    public static final int CALLBACK_EXIT               = BASE + 9;
2199    /** @hide obj = NetworkCapabilities, arg1 = seq number */
2200    private static final int EXPIRE_LEGACY_REQUEST      = BASE + 10;
2201
2202    private class CallbackHandler extends Handler {
2203        private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap;
2204        private final AtomicInteger mRefCount;
2205        private static final String TAG = "ConnectivityManager.CallbackHandler";
2206        private final ConnectivityManager mCm;
2207
2208        CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallback>callbackMap,
2209                AtomicInteger refCount, ConnectivityManager cm) {
2210            super(looper);
2211            mCallbackMap = callbackMap;
2212            mRefCount = refCount;
2213            mCm = cm;
2214        }
2215
2216        @Override
2217        public void handleMessage(Message message) {
2218            Log.d(TAG, "CM callback handler got msg " + message.what);
2219            NetworkRequest request = (NetworkRequest) getObject(message, NetworkRequest.class);
2220            Network network = (Network) getObject(message, Network.class);
2221            switch (message.what) {
2222                case CALLBACK_PRECHECK: {
2223                    NetworkCallback callback = getCallback(request, "PRECHECK");
2224                    if (callback != null) {
2225                        callback.onPreCheck(network);
2226                    }
2227                    break;
2228                }
2229                case CALLBACK_AVAILABLE: {
2230                    NetworkCallback callback = getCallback(request, "AVAILABLE");
2231                    if (callback != null) {
2232                        callback.onAvailable(network);
2233                    }
2234                    break;
2235                }
2236                case CALLBACK_LOSING: {
2237                    NetworkCallback callback = getCallback(request, "LOSING");
2238                    if (callback != null) {
2239                        callback.onLosing(network, message.arg1);
2240                    }
2241                    break;
2242                }
2243                case CALLBACK_LOST: {
2244                    NetworkCallback callback = getCallback(request, "LOST");
2245                    if (callback != null) {
2246                        callback.onLost(network);
2247                    }
2248                    break;
2249                }
2250                case CALLBACK_UNAVAIL: {
2251                    NetworkCallback callback = getCallback(request, "UNAVAIL");
2252                    if (callback != null) {
2253                        callback.onUnavailable();
2254                    }
2255                    break;
2256                }
2257                case CALLBACK_CAP_CHANGED: {
2258                    NetworkCallback callback = getCallback(request, "CAP_CHANGED");
2259                    if (callback != null) {
2260                        NetworkCapabilities cap = (NetworkCapabilities)getObject(message,
2261                                NetworkCapabilities.class);
2262
2263                        callback.onCapabilitiesChanged(network, cap);
2264                    }
2265                    break;
2266                }
2267                case CALLBACK_IP_CHANGED: {
2268                    NetworkCallback callback = getCallback(request, "IP_CHANGED");
2269                    if (callback != null) {
2270                        LinkProperties lp = (LinkProperties)getObject(message,
2271                                LinkProperties.class);
2272
2273                        callback.onLinkPropertiesChanged(network, lp);
2274                    }
2275                    break;
2276                }
2277                case CALLBACK_RELEASED: {
2278                    NetworkCallback callback = null;
2279                    synchronized(mCallbackMap) {
2280                        callback = mCallbackMap.remove(request);
2281                    }
2282                    if (callback != null) {
2283                        synchronized(mRefCount) {
2284                            if (mRefCount.decrementAndGet() == 0) {
2285                                getLooper().quit();
2286                            }
2287                        }
2288                    } else {
2289                        Log.e(TAG, "callback not found for RELEASED message");
2290                    }
2291                    break;
2292                }
2293                case CALLBACK_EXIT: {
2294                    Log.d(TAG, "Listener quitting");
2295                    getLooper().quit();
2296                    break;
2297                }
2298                case EXPIRE_LEGACY_REQUEST: {
2299                    expireRequest((NetworkCapabilities)message.obj, message.arg1);
2300                    break;
2301                }
2302            }
2303        }
2304
2305        private Object getObject(Message msg, Class c) {
2306            return msg.getData().getParcelable(c.getSimpleName());
2307        }
2308
2309        private NetworkCallback getCallback(NetworkRequest req, String name) {
2310            NetworkCallback callback;
2311            synchronized(mCallbackMap) {
2312                callback = mCallbackMap.get(req);
2313            }
2314            if (callback == null) {
2315                Log.e(TAG, "callback not found for " + name + " message");
2316            }
2317            return callback;
2318        }
2319    }
2320
2321    private void incCallbackHandlerRefCount() {
2322        synchronized(sCallbackRefCount) {
2323            if (sCallbackRefCount.incrementAndGet() == 1) {
2324                // TODO - switch this over to a ManagerThread or expire it when done
2325                HandlerThread callbackThread = new HandlerThread("ConnectivityManager");
2326                callbackThread.start();
2327                sCallbackHandler = new CallbackHandler(callbackThread.getLooper(),
2328                        sNetworkCallback, sCallbackRefCount, this);
2329            }
2330        }
2331    }
2332
2333    private void decCallbackHandlerRefCount() {
2334        synchronized(sCallbackRefCount) {
2335            if (sCallbackRefCount.decrementAndGet() == 0) {
2336                sCallbackHandler.obtainMessage(CALLBACK_EXIT).sendToTarget();
2337                sCallbackHandler = null;
2338            }
2339        }
2340    }
2341
2342    static final HashMap<NetworkRequest, NetworkCallback> sNetworkCallback =
2343            new HashMap<NetworkRequest, NetworkCallback>();
2344    static final AtomicInteger sCallbackRefCount = new AtomicInteger(0);
2345    static CallbackHandler sCallbackHandler = null;
2346
2347    private final static int LISTEN  = 1;
2348    private final static int REQUEST = 2;
2349
2350    private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
2351            NetworkCallback networkCallback, int timeoutSec, int action,
2352            int legacyType) {
2353        if (networkCallback == null) {
2354            throw new IllegalArgumentException("null NetworkCallback");
2355        }
2356        if (need == null) throw new IllegalArgumentException("null NetworkCapabilities");
2357        try {
2358            incCallbackHandlerRefCount();
2359            synchronized(sNetworkCallback) {
2360                if (action == LISTEN) {
2361                    networkCallback.networkRequest = mService.listenForNetwork(need,
2362                            new Messenger(sCallbackHandler), new Binder());
2363                } else {
2364                    networkCallback.networkRequest = mService.requestNetwork(need,
2365                            new Messenger(sCallbackHandler), timeoutSec, new Binder(), legacyType);
2366                }
2367                if (networkCallback.networkRequest != null) {
2368                    sNetworkCallback.put(networkCallback.networkRequest, networkCallback);
2369                }
2370            }
2371        } catch (RemoteException e) {}
2372        if (networkCallback.networkRequest == null) decCallbackHandlerRefCount();
2373        return networkCallback.networkRequest;
2374    }
2375
2376    /**
2377     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
2378     *
2379     * This {@link NetworkRequest} will live until released via
2380     * {@link #unregisterNetworkCallback} or the calling application exits.
2381     * Status of the request can be followed by listening to the various
2382     * callbacks described in {@link NetworkCallback}.  The {@link Network}
2383     * can be used to direct traffic to the network.
2384     * <p>It is presently unsupported to request a network with mutable
2385     * {@link NetworkCapabilities} such as
2386     * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
2387     * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
2388     * as these {@code NetworkCapabilities} represent states that a particular
2389     * network may never attain, and whether a network will attain these states
2390     * is unknown prior to bringing up the network so the framework does not
2391     * know how to go about satisfing a request with these capabilities.
2392     * <p>This method requires the caller to hold the permission
2393     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
2394     *
2395     * @param request {@link NetworkRequest} describing this request.
2396     * @param networkCallback The {@link NetworkCallback} to be utilized for this
2397     *                        request.  Note the callback must not be shared - they
2398     *                        uniquely specify this request.
2399     * @throws IllegalArgumentException if {@code request} specifies any mutable
2400     *         {@code NetworkCapabilities}.
2401     */
2402    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) {
2403        sendRequestForNetwork(request.networkCapabilities, networkCallback, 0,
2404                REQUEST, inferLegacyTypeForNetworkCapabilities(request.networkCapabilities));
2405    }
2406
2407    /**
2408     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
2409     * by a timeout.
2410     *
2411     * This function behaves identically to the non-timedout version, but if a suitable
2412     * network is not found within the given time (in milliseconds) the
2413     * {@link NetworkCallback#unavailable} callback is called.  The request must
2414     * still be released normally by calling {@link releaseNetworkRequest}.
2415     * <p>This method requires the caller to hold the permission
2416     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
2417     * @param request {@link NetworkRequest} describing this request.
2418     * @param networkCallback The callbacks to be utilized for this request.  Note
2419     *                        the callbacks must not be shared - they uniquely specify
2420     *                        this request.
2421     * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
2422     *                  before {@link NetworkCallback#unavailable} is called.
2423     * @hide
2424     */
2425    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
2426            int timeoutMs) {
2427        sendRequestForNetwork(request.networkCapabilities, networkCallback, timeoutMs,
2428                REQUEST, inferLegacyTypeForNetworkCapabilities(request.networkCapabilities));
2429    }
2430
2431    /**
2432     * The maximum number of milliseconds the framework will look for a suitable network
2433     * during a timeout-equiped call to {@link requestNetwork}.
2434     * {@hide}
2435     */
2436    public final static int MAX_NETWORK_REQUEST_TIMEOUT_MS = 100 * 60 * 1000;
2437
2438    /**
2439     * The lookup key for a {@link Network} object included with the intent after
2440     * successfully finding a network for the applications request.  Retrieve it with
2441     * {@link android.content.Intent#getParcelableExtra(String)}.
2442     * <p>
2443     * Note that if you intend to invoke {@link Network#openConnection(java.net.URL)}
2444     * then you must get a ConnectivityManager instance before doing so.
2445     */
2446    public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
2447
2448    /**
2449     * The lookup key for a {@link NetworkRequest} object included with the intent after
2450     * successfully finding a network for the applications request.  Retrieve it with
2451     * {@link android.content.Intent#getParcelableExtra(String)}.
2452     */
2453    public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
2454
2455
2456    /**
2457     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
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.  It is important to create a new,
2472     * {@link NetworkCallback} based request before completing the processing of the
2473     * Intent to reserve the network or it will be released shortly after the Intent
2474     * is processed.
2475     * <p>
2476     * If there is already a request for this Intent registered (with the equality of
2477     * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
2478     * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
2479     * <p>
2480     * The request may be released normally by calling
2481     * {@link #releaseNetworkRequest(android.app.PendingIntent)}.
2482     * <p>It is presently unsupported to request a network with either
2483     * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
2484     * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
2485     * as these {@code NetworkCapabilities} represent states that a particular
2486     * network may never attain, and whether a network will attain these states
2487     * is unknown prior to bringing up the network so the framework does not
2488     * know how to go about satisfing a request with these capabilities.
2489     * <p>This method requires the caller to hold the permission
2490     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
2491     * @param request {@link NetworkRequest} describing this request.
2492     * @param operation Action to perform when the network is available (corresponds
2493     *                  to the {@link NetworkCallback#onAvailable} call.  Typically
2494     *                  comes from {@link PendingIntent#getBroadcast}. Cannot be null.
2495     * @throws IllegalArgumentException if {@code request} contains either
2496     *         {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
2497     *         {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}.
2498     */
2499    public void requestNetwork(NetworkRequest request, PendingIntent operation) {
2500        checkPendingIntent(operation);
2501        try {
2502            mService.pendingRequestForNetwork(request.networkCapabilities, operation);
2503        } catch (RemoteException e) {}
2504    }
2505
2506    /**
2507     * Removes a request made via {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)}
2508     * <p>
2509     * This method has the same behavior as {@link #unregisterNetworkCallback} with respect to
2510     * releasing network resources and disconnecting.
2511     *
2512     * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the
2513     *                  PendingIntent passed to
2514     *                  {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)} with the
2515     *                  corresponding NetworkRequest you'd like to remove. Cannot be null.
2516     */
2517    public void releaseNetworkRequest(PendingIntent operation) {
2518        checkPendingIntent(operation);
2519        try {
2520            mService.releasePendingNetworkRequest(operation);
2521        } catch (RemoteException e) {}
2522    }
2523
2524    private void checkPendingIntent(PendingIntent intent) {
2525        if (intent == null) {
2526            throw new IllegalArgumentException("PendingIntent cannot be null.");
2527        }
2528    }
2529
2530    /**
2531     * Registers to receive notifications about all networks which satisfy the given
2532     * {@link NetworkRequest}.  The callbacks will continue to be called until
2533     * either the application exits or {@link #unregisterNetworkCallback} is called
2534     * <p>This method requires the caller to hold the permission
2535     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
2536     *
2537     * @param request {@link NetworkRequest} describing this request.
2538     * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
2539     *                        networks change state.
2540     */
2541    public void registerNetworkCallback(NetworkRequest request, NetworkCallback networkCallback) {
2542        sendRequestForNetwork(request.networkCapabilities, networkCallback, 0, LISTEN, TYPE_NONE);
2543    }
2544
2545    /**
2546     * Registers a PendingIntent to be sent when a network is available which satisfies the given
2547     * {@link NetworkRequest}.
2548     *
2549     * This function behaves identically to the version that takes a NetworkCallback, but instead
2550     * of {@link NetworkCallback} a {@link PendingIntent} is used.  This means
2551     * the request may outlive the calling application and get called back when a suitable
2552     * network is found.
2553     * <p>
2554     * The operation is an Intent broadcast that goes to a broadcast receiver that
2555     * you registered with {@link Context#registerReceiver} or through the
2556     * &lt;receiver&gt; tag in an AndroidManifest.xml file
2557     * <p>
2558     * The operation Intent is delivered with two extras, a {@link Network} typed
2559     * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest}
2560     * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing
2561     * the original requests parameters.
2562     * <p>
2563     * If there is already a request for this Intent registered (with the equality of
2564     * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
2565     * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
2566     * <p>
2567     * The request may be released normally by calling
2568     * {@link #releaseNetworkRequest(android.app.PendingIntent)}.
2569     * <p>This method requires the caller to hold the permission
2570     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
2571     * @param request {@link NetworkRequest} describing this request.
2572     * @param operation Action to perform when the network is available (corresponds
2573     *                  to the {@link NetworkCallback#onAvailable} call.  Typically
2574     *                  comes from {@link PendingIntent#getBroadcast}. Cannot be null.
2575     */
2576    public void registerNetworkCallback(NetworkRequest request, PendingIntent operation) {
2577        checkPendingIntent(operation);
2578        try {
2579            mService.pendingListenForNetwork(request.networkCapabilities, operation);
2580        } catch (RemoteException e) {}
2581    }
2582
2583    /**
2584     * Requests bandwidth update for a given {@link Network} and returns whether the update request
2585     * is accepted by ConnectivityService. Once accepted, ConnectivityService will poll underlying
2586     * network connection for updated bandwidth information. The caller will be notified via
2587     * {@link ConnectivityManager.NetworkCallback} if there is an update. Notice that this
2588     * method assumes that the caller has previously called {@link #registerNetworkCallback} to
2589     * listen for network changes.
2590     *
2591     * @param network {@link Network} specifying which network you're interested.
2592     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
2593     */
2594    public boolean requestBandwidthUpdate(Network network) {
2595        try {
2596            return mService.requestBandwidthUpdate(network);
2597        } catch (RemoteException e) {
2598            return false;
2599        }
2600    }
2601
2602    /**
2603     * Unregisters callbacks about and possibly releases networks originating from
2604     * {@link #requestNetwork(NetworkRequest, NetworkCallback)} and {@link #registerNetworkCallback}
2605     * calls.  If the given {@code NetworkCallback} had previously been used with
2606     * {@code #requestNetwork}, any networks that had been connected to only to satisfy that request
2607     * will be disconnected.
2608     *
2609     * @param networkCallback The {@link NetworkCallback} used when making the request.
2610     */
2611    public void unregisterNetworkCallback(NetworkCallback networkCallback) {
2612        if (networkCallback == null || networkCallback.networkRequest == null ||
2613                networkCallback.networkRequest.requestId == REQUEST_ID_UNSET) {
2614            throw new IllegalArgumentException("Invalid NetworkCallback");
2615        }
2616        try {
2617            mService.releaseNetworkRequest(networkCallback.networkRequest);
2618        } catch (RemoteException e) {}
2619    }
2620
2621    /**
2622     * Informs the system whether it should switch to {@code network} regardless of whether it is
2623     * validated or not. If {@code accept} is true, and the network was explicitly selected by the
2624     * user (e.g., by selecting a Wi-Fi network in the Settings app), then the network will become
2625     * the system default network regardless of any other network that's currently connected. If
2626     * {@code always} is true, then the choice is remembered, so that the next time the user
2627     * connects to this network, the system will switch to it.
2628     *
2629     * <p>This method requires the caller to hold the permission
2630     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}
2631     *
2632     * @param network The network to accept.
2633     * @param accept Whether to accept the network even if unvalidated.
2634     * @param always Whether to remember this choice in the future.
2635     *
2636     * @hide
2637     */
2638    public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
2639        try {
2640            mService.setAcceptUnvalidated(network, accept, always);
2641        } catch (RemoteException e) {}
2642    }
2643
2644    /**
2645     * Resets all connectivity manager settings back to factory defaults.
2646     * @hide
2647     */
2648    public void factoryReset() {
2649        try {
2650            mService.factoryReset();
2651        } catch (RemoteException e) {
2652        }
2653    }
2654
2655    /**
2656     * Binds the current process to {@code network}.  All Sockets created in the future
2657     * (and not explicitly bound via a bound SocketFactory from
2658     * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
2659     * {@code network}.  All host name resolutions will be limited to {@code network} as well.
2660     * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
2661     * work and all host name resolutions will fail.  This is by design so an application doesn't
2662     * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
2663     * To clear binding pass {@code null} for {@code network}.  Using individually bound
2664     * Sockets created by Network.getSocketFactory().createSocket() and
2665     * performing network-specific host name resolutions via
2666     * {@link Network#getAllByName Network.getAllByName} is preferred to calling
2667     * {@code bindProcessToNetwork}.
2668     *
2669     * @param network The {@link Network} to bind the current process to, or {@code null} to clear
2670     *                the current binding.
2671     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
2672     */
2673    public boolean bindProcessToNetwork(Network network) {
2674        // Forcing callers to call thru non-static function ensures ConnectivityManager
2675        // instantiated.
2676        return setProcessDefaultNetwork(network);
2677    }
2678
2679    /**
2680     * Binds the current process to {@code network}.  All Sockets created in the future
2681     * (and not explicitly bound via a bound SocketFactory from
2682     * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
2683     * {@code network}.  All host name resolutions will be limited to {@code network} as well.
2684     * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
2685     * work and all host name resolutions will fail.  This is by design so an application doesn't
2686     * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
2687     * To clear binding pass {@code null} for {@code network}.  Using individually bound
2688     * Sockets created by Network.getSocketFactory().createSocket() and
2689     * performing network-specific host name resolutions via
2690     * {@link Network#getAllByName Network.getAllByName} is preferred to calling
2691     * {@code setProcessDefaultNetwork}.
2692     *
2693     * @param network The {@link Network} to bind the current process to, or {@code null} to clear
2694     *                the current binding.
2695     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
2696     * @deprecated This function can throw {@link IllegalStateException}.  Use
2697     *             {@link #bindProcessToNetwork} instead.  {@code bindProcessToNetwork}
2698     *             is a direct replacement.
2699     */
2700    public static boolean setProcessDefaultNetwork(Network network) {
2701        int netId = (network == null) ? NETID_UNSET : network.netId;
2702        if (netId == NetworkUtils.getBoundNetworkForProcess()) {
2703            return true;
2704        }
2705        if (NetworkUtils.bindProcessToNetwork(netId)) {
2706            // Set HTTP proxy system properties to match network.
2707            // TODO: Deprecate this static method and replace it with a non-static version.
2708            try {
2709                Proxy.setHttpProxySystemProperty(getInstance().getDefaultProxy());
2710            } catch (SecurityException e) {
2711                // The process doesn't have ACCESS_NETWORK_STATE, so we can't fetch the proxy.
2712                Log.e(TAG, "Can't set proxy properties", e);
2713            }
2714            // Must flush DNS cache as new network may have different DNS resolutions.
2715            InetAddress.clearDnsCache();
2716            // Must flush socket pool as idle sockets will be bound to previous network and may
2717            // cause subsequent fetches to be performed on old network.
2718            NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
2719            return true;
2720        } else {
2721            return false;
2722        }
2723    }
2724
2725    /**
2726     * Returns the {@link Network} currently bound to this process via
2727     * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
2728     *
2729     * @return {@code Network} to which this process is bound, or {@code null}.
2730     */
2731    public Network getBoundNetworkForProcess() {
2732        // Forcing callers to call thru non-static function ensures ConnectivityManager
2733        // instantiated.
2734        return getProcessDefaultNetwork();
2735    }
2736
2737    /**
2738     * Returns the {@link Network} currently bound to this process via
2739     * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
2740     *
2741     * @return {@code Network} to which this process is bound, or {@code null}.
2742     * @deprecated Using this function can lead to other functions throwing
2743     *             {@link IllegalStateException}.  Use {@link #getBoundNetworkForProcess} instead.
2744     *             {@code getBoundNetworkForProcess} is a direct replacement.
2745     */
2746    public static Network getProcessDefaultNetwork() {
2747        int netId = NetworkUtils.getBoundNetworkForProcess();
2748        if (netId == NETID_UNSET) return null;
2749        return new Network(netId);
2750    }
2751
2752    /**
2753     * Binds host resolutions performed by this process to {@code network}.
2754     * {@link #bindProcessToNetwork} takes precedence over this setting.
2755     *
2756     * @param network The {@link Network} to bind host resolutions from the current process to, or
2757     *                {@code null} to clear the current binding.
2758     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
2759     * @hide
2760     * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}.
2761     */
2762    public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
2763        return NetworkUtils.bindProcessToNetworkForHostResolution(
2764                network == null ? NETID_UNSET : network.netId);
2765    }
2766}
2767