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