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