ConnectivityManager.java revision 26aa91ab27c4064cc7e77267a1a4ef7544d35f5c
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 android.annotation.IntDef;
19import android.annotation.Nullable;
20import android.annotation.RequiresPermission;
21import android.annotation.SdkConstant;
22import android.annotation.SdkConstant.SdkConstantType;
23import android.annotation.SystemApi;
24import android.annotation.SystemService;
25import android.app.PendingIntent;
26import android.content.Context;
27import android.content.Intent;
28import android.content.pm.PackageManager;
29import android.os.Binder;
30import android.os.Build.VERSION_CODES;
31import android.os.Bundle;
32import android.os.Handler;
33import android.os.HandlerThread;
34import android.os.IBinder;
35import android.os.INetworkActivityListener;
36import android.os.INetworkManagementService;
37import android.os.Looper;
38import android.os.Message;
39import android.os.Messenger;
40import android.os.Process;
41import android.os.RemoteException;
42import android.os.ResultReceiver;
43import android.os.ServiceManager;
44import android.os.ServiceSpecificException;
45import android.provider.Settings;
46import android.telephony.SubscriptionManager;
47import android.util.ArrayMap;
48import android.util.Log;
49import android.util.SparseIntArray;
50
51import com.android.internal.telephony.ITelephony;
52import com.android.internal.telephony.PhoneConstants;
53import com.android.internal.util.Preconditions;
54import com.android.internal.util.Protocol;
55
56import libcore.net.event.NetworkEventDispatcher;
57
58import java.lang.annotation.Retention;
59import java.lang.annotation.RetentionPolicy;
60import java.net.InetAddress;
61import java.util.ArrayList;
62import java.util.HashMap;
63import java.util.List;
64import java.util.Map;
65
66/**
67 * Class that answers queries about the state of network connectivity. It also
68 * notifies applications when network connectivity changes.
69 * <p>
70 * The primary responsibilities of this class are to:
71 * <ol>
72 * <li>Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)</li>
73 * <li>Send broadcast intents when network connectivity changes</li>
74 * <li>Attempt to "fail over" to another network when connectivity to a network
75 * is lost</li>
76 * <li>Provide an API that allows applications to query the coarse-grained or fine-grained
77 * state of the available networks</li>
78 * <li>Provide an API that allows applications to request and select networks for their data
79 * traffic</li>
80 * </ol>
81 */
82@SystemService(Context.CONNECTIVITY_SERVICE)
83public class ConnectivityManager {
84    private static final String TAG = "ConnectivityManager";
85
86    /**
87     * A change in network connectivity has occurred. A default connection has either
88     * been established or lost. The NetworkInfo for the affected network is
89     * sent as an extra; it should be consulted to see what kind of
90     * connectivity event occurred.
91     * <p/>
92     * Apps targeting Android 7.0 (API level 24) and higher do not receive this
93     * broadcast if they declare the broadcast receiver in their manifest. Apps
94     * will still receive broadcasts if they register their
95     * {@link android.content.BroadcastReceiver} with
96     * {@link android.content.Context#registerReceiver Context.registerReceiver()}
97     * and that context is still valid.
98     * <p/>
99     * If this is a connection that was the result of failing over from a
100     * disconnected network, then the FAILOVER_CONNECTION boolean extra is
101     * set to true.
102     * <p/>
103     * For a loss of connectivity, if the connectivity manager is attempting
104     * to connect (or has already connected) to another network, the
105     * NetworkInfo for the new network is also passed as an extra. This lets
106     * any receivers of the broadcast know that they should not necessarily
107     * tell the user that no data traffic will be possible. Instead, the
108     * receiver should expect another broadcast soon, indicating either that
109     * the failover attempt succeeded (and so there is still overall data
110     * connectivity), or that the failover attempt failed, meaning that all
111     * connectivity has been lost.
112     * <p/>
113     * For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY
114     * is set to {@code true} if there are no connected networks at all.
115     *
116     * @deprecated apps should use the more versatile {@link #requestNetwork},
117     *             {@link #registerNetworkCallback} or {@link #registerDefaultNetworkCallback}
118     *             functions instead for faster and more detailed updates about the network
119     *             changes they care about.
120     */
121    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
122    @Deprecated
123    public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
124
125    /**
126     * A temporary hack until SUPL system can get off the legacy APIS.
127     * They do too many network requests and the long list of apps listening
128     * and waking due to the CONNECTIVITY_ACTION bcast makes it expensive.
129     * Use this bcast intent instead for SUPL requests.
130     * @hide
131     */
132    public static final String CONNECTIVITY_ACTION_SUPL =
133            "android.net.conn.CONNECTIVITY_CHANGE_SUPL";
134
135    /**
136     * The device has connected to a network that has presented a captive
137     * portal, which is blocking Internet connectivity. The user was presented
138     * with a notification that network sign in is required,
139     * and the user invoked the notification's action indicating they
140     * desire to sign in to the network. Apps handling this activity should
141     * facilitate signing in to the network. This action includes a
142     * {@link Network} typed extra called {@link #EXTRA_NETWORK} that represents
143     * the network presenting the captive portal; all communication with the
144     * captive portal must be done using this {@code Network} object.
145     * <p/>
146     * This activity includes a {@link CaptivePortal} extra named
147     * {@link #EXTRA_CAPTIVE_PORTAL} that can be used to indicate different
148     * outcomes of the captive portal sign in to the system:
149     * <ul>
150     * <li> When the app handling this action believes the user has signed in to
151     * the network and the captive portal has been dismissed, the app should
152     * call {@link CaptivePortal#reportCaptivePortalDismissed} so the system can
153     * reevaluate the network. If reevaluation finds the network no longer
154     * subject to a captive portal, the network may become the default active
155     * data network. </li>
156     * <li> When the app handling this action believes the user explicitly wants
157     * to ignore the captive portal and the network, the app should call
158     * {@link CaptivePortal#ignoreNetwork}. </li>
159     * </ul>
160     */
161    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
162    public static final String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL";
163
164    /**
165     * The lookup key for a {@link NetworkInfo} object. Retrieve with
166     * {@link android.content.Intent#getParcelableExtra(String)}.
167     *
168     * @deprecated Since {@link NetworkInfo} can vary based on UID, applications
169     *             should always obtain network information through
170     *             {@link #getActiveNetworkInfo()}.
171     * @see #EXTRA_NETWORK_TYPE
172     */
173    @Deprecated
174    public static final String EXTRA_NETWORK_INFO = "networkInfo";
175
176    /**
177     * Network type which triggered a {@link #CONNECTIVITY_ACTION} broadcast.
178     *
179     * @see android.content.Intent#getIntExtra(String, int)
180     */
181    public static final String EXTRA_NETWORK_TYPE = "networkType";
182
183    /**
184     * The lookup key for a boolean that indicates whether a connect event
185     * is for a network to which the connectivity manager was failing over
186     * following a disconnect on another network.
187     * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
188     */
189    public static final String EXTRA_IS_FAILOVER = "isFailover";
190    /**
191     * The lookup key for a {@link NetworkInfo} object. This is supplied when
192     * there is another network that it may be possible to connect to. Retrieve with
193     * {@link android.content.Intent#getParcelableExtra(String)}.
194     */
195    public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
196    /**
197     * The lookup key for a boolean that indicates whether there is a
198     * complete lack of connectivity, i.e., no network is available.
199     * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
200     */
201    public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
202    /**
203     * The lookup key for a string that indicates why an attempt to connect
204     * to a network failed. The string has no particular structure. It is
205     * intended to be used in notifications presented to users. Retrieve
206     * it with {@link android.content.Intent#getStringExtra(String)}.
207     */
208    public static final String EXTRA_REASON = "reason";
209    /**
210     * The lookup key for a string that provides optionally supplied
211     * extra information about the network state. The information
212     * may be passed up from the lower networking layers, and its
213     * meaning may be specific to a particular network type. Retrieve
214     * it with {@link android.content.Intent#getStringExtra(String)}.
215     */
216    public static final String EXTRA_EXTRA_INFO = "extraInfo";
217    /**
218     * The lookup key for an int that provides information about
219     * our connection to the internet at large.  0 indicates no connection,
220     * 100 indicates a great connection.  Retrieve it with
221     * {@link android.content.Intent#getIntExtra(String, int)}.
222     * {@hide}
223     */
224    public static final String EXTRA_INET_CONDITION = "inetCondition";
225    /**
226     * The lookup key for a {@link CaptivePortal} object included with the
227     * {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN} intent.  The {@code CaptivePortal}
228     * object can be used to either indicate to the system that the captive
229     * portal has been dismissed or that the user does not want to pursue
230     * signing in to captive portal.  Retrieve it with
231     * {@link android.content.Intent#getParcelableExtra(String)}.
232     */
233    public static final String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL";
234
235    /**
236     * Key for passing a URL to the captive portal login activity.
237     */
238    public static final String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL";
239
240    /**
241     * Key for passing a user agent string to the captive portal login activity.
242     * {@hide}
243     */
244    public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT =
245            "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
246
247    /**
248     * Broadcast action to indicate the change of data activity status
249     * (idle or active) on a network in a recent period.
250     * The network becomes active when data transmission is started, or
251     * idle if there is no data transmission for a period of time.
252     * {@hide}
253     */
254    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
255    public static final String ACTION_DATA_ACTIVITY_CHANGE = "android.net.conn.DATA_ACTIVITY_CHANGE";
256    /**
257     * The lookup key for an enum that indicates the network device type on which this data activity
258     * change happens.
259     * {@hide}
260     */
261    public static final String EXTRA_DEVICE_TYPE = "deviceType";
262    /**
263     * The lookup key for a boolean that indicates the device is active or not. {@code true} means
264     * it is actively sending or receiving data and {@code false} means it is idle.
265     * {@hide}
266     */
267    public static final String EXTRA_IS_ACTIVE = "isActive";
268    /**
269     * The lookup key for a long that contains the timestamp (nanos) of the radio state change.
270     * {@hide}
271     */
272    public static final String EXTRA_REALTIME_NS = "tsNanos";
273
274    /**
275     * Broadcast Action: The setting for background data usage has changed
276     * values. Use {@link #getBackgroundDataSetting()} to get the current value.
277     * <p>
278     * If an application uses the network in the background, it should listen
279     * for this broadcast and stop using the background data if the value is
280     * {@code false}.
281     * <p>
282     *
283     * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability
284     *             of background data depends on several combined factors, and
285     *             this broadcast is no longer sent. Instead, when background
286     *             data is unavailable, {@link #getActiveNetworkInfo()} will now
287     *             appear disconnected. During first boot after a platform
288     *             upgrade, this broadcast will be sent once if
289     *             {@link #getBackgroundDataSetting()} was {@code false} before
290     *             the upgrade.
291     */
292    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
293    @Deprecated
294    public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED =
295            "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
296
297    /**
298     * Broadcast Action: The network connection may not be good
299     * uses {@code ConnectivityManager.EXTRA_INET_CONDITION} and
300     * {@code ConnectivityManager.EXTRA_NETWORK_INFO} to specify
301     * the network and it's condition.
302     * @hide
303     */
304    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
305    public static final String INET_CONDITION_ACTION =
306            "android.net.conn.INET_CONDITION_ACTION";
307
308    /**
309     * Broadcast Action: A tetherable connection has come or gone.
310     * Uses {@code ConnectivityManager.EXTRA_AVAILABLE_TETHER},
311     * {@code ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY},
312     * {@code ConnectivityManager.EXTRA_ACTIVE_TETHER}, and
313     * {@code ConnectivityManager.EXTRA_ERRORED_TETHER} to indicate
314     * the current state of tethering.  Each include a list of
315     * interface names in that state (may be empty).
316     * @hide
317     */
318    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
319    public static final String ACTION_TETHER_STATE_CHANGED =
320            "android.net.conn.TETHER_STATE_CHANGED";
321
322    /**
323     * @hide
324     * gives a String[] listing all the interfaces configured for
325     * tethering and currently available for tethering.
326     */
327    public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
328
329    /**
330     * @hide
331     * gives a String[] listing all the interfaces currently in local-only
332     * mode (ie, has DHCPv4+IPv6-ULA support and no packet forwarding)
333     */
334    public static final String EXTRA_ACTIVE_LOCAL_ONLY = "localOnlyArray";
335
336    /**
337     * @hide
338     * gives a String[] listing all the interfaces currently tethered
339     * (ie, has DHCPv4 support and packets potentially forwarded/NATed)
340     */
341    public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
342
343    /**
344     * @hide
345     * gives a String[] listing all the interfaces we tried to tether and
346     * failed.  Use {@link #getLastTetherError} to find the error code
347     * for any interfaces listed here.
348     */
349    public static final String EXTRA_ERRORED_TETHER = "erroredArray";
350
351    /**
352     * Broadcast Action: The captive portal tracker has finished its test.
353     * Sent only while running Setup Wizard, in lieu of showing a user
354     * notification.
355     * @hide
356     */
357    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
358    public static final String ACTION_CAPTIVE_PORTAL_TEST_COMPLETED =
359            "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED";
360    /**
361     * The lookup key for a boolean that indicates whether a captive portal was detected.
362     * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
363     * @hide
364     */
365    public static final String EXTRA_IS_CAPTIVE_PORTAL = "captivePortal";
366
367    /**
368     * Action used to display a dialog that asks the user whether to connect to a network that is
369     * not validated. This intent is used to start the dialog in settings via startActivity.
370     *
371     * @hide
372     */
373    public static final String ACTION_PROMPT_UNVALIDATED = "android.net.conn.PROMPT_UNVALIDATED";
374
375    /**
376     * Action used to display a dialog that asks the user whether to avoid a network that is no
377     * longer validated. This intent is used to start the dialog in settings via startActivity.
378     *
379     * @hide
380     */
381    public static final String ACTION_PROMPT_LOST_VALIDATION =
382            "android.net.conn.PROMPT_LOST_VALIDATION";
383
384    /**
385     * Invalid tethering type.
386     * @see #startTethering(int, OnStartTetheringCallback, boolean)
387     * @hide
388     */
389    public static final int TETHERING_INVALID   = -1;
390
391    /**
392     * Wifi tethering type.
393     * @see #startTethering(int, OnStartTetheringCallback, boolean)
394     * @hide
395     */
396    @SystemApi
397    public static final int TETHERING_WIFI      = 0;
398
399    /**
400     * USB tethering type.
401     * @see #startTethering(int, OnStartTetheringCallback, boolean)
402     * @hide
403     */
404    @SystemApi
405    public static final int TETHERING_USB       = 1;
406
407    /**
408     * Bluetooth tethering type.
409     * @see #startTethering(int, OnStartTetheringCallback, boolean)
410     * @hide
411     */
412    @SystemApi
413    public static final int TETHERING_BLUETOOTH = 2;
414
415    /**
416     * Extra used for communicating with the TetherService. Includes the type of tethering to
417     * enable if any.
418     * @hide
419     */
420    public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
421
422    /**
423     * Extra used for communicating with the TetherService. Includes the type of tethering for
424     * which to cancel provisioning.
425     * @hide
426     */
427    public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType";
428
429    /**
430     * Extra used for communicating with the TetherService. True to schedule a recheck of tether
431     * provisioning.
432     * @hide
433     */
434    public static final String EXTRA_SET_ALARM = "extraSetAlarm";
435
436    /**
437     * Tells the TetherService to run a provision check now.
438     * @hide
439     */
440    public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
441
442    /**
443     * Extra used for communicating with the TetherService. Contains the {@link ResultReceiver}
444     * which will receive provisioning results. Can be left empty.
445     * @hide
446     */
447    public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";
448
449    /**
450     * The absence of a connection type.
451     * @hide
452     */
453    public static final int TYPE_NONE        = -1;
454
455    /**
456     * A Mobile data connection. Devices may support more than one.
457     *
458     * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or
459     *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an
460     *         appropriate network. {@see NetworkCapabilities} for supported transports.
461     */
462    @Deprecated
463    public static final int TYPE_MOBILE      = 0;
464
465    /**
466     * A WIFI data connection. Devices may support more than one.
467     *
468     * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or
469     *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an
470     *         appropriate network. {@see NetworkCapabilities} for supported transports.
471     */
472    @Deprecated
473    public static final int TYPE_WIFI        = 1;
474
475    /**
476     * An MMS-specific Mobile data connection.  This network type may use the
477     * same network interface as {@link #TYPE_MOBILE} or it may use a different
478     * one.  This is used by applications needing to talk to the carrier's
479     * Multimedia Messaging Service servers.
480     *
481     * @deprecated Applications should instead use {@link NetworkCapabilities#hasCapability} or
482     *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that
483     *         provides the {@link NetworkCapabilities#NET_CAPABILITY_MMS} capability.
484     */
485    @Deprecated
486    public static final int TYPE_MOBILE_MMS  = 2;
487
488    /**
489     * A SUPL-specific Mobile data connection.  This network type may use the
490     * same network interface as {@link #TYPE_MOBILE} or it may use a different
491     * one.  This is used by applications needing to talk to the carrier's
492     * Secure User Plane Location servers for help locating the device.
493     *
494     * @deprecated Applications should instead use {@link NetworkCapabilities#hasCapability} or
495     *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that
496     *         provides the {@link NetworkCapabilities#NET_CAPABILITY_SUPL} capability.
497     */
498    @Deprecated
499    public static final int TYPE_MOBILE_SUPL = 3;
500
501    /**
502     * A DUN-specific Mobile data connection.  This network type may use the
503     * same network interface as {@link #TYPE_MOBILE} or it may use a different
504     * one.  This is sometimes by the system when setting up an upstream connection
505     * for tethering so that the carrier is aware of DUN traffic.
506     *
507     * @deprecated Applications should instead use {@link NetworkCapabilities#hasCapability} or
508     *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request a network that
509     *         provides the {@link NetworkCapabilities#NET_CAPABILITY_DUN} capability.
510     */
511    @Deprecated
512    public static final int TYPE_MOBILE_DUN  = 4;
513
514    /**
515     * A High Priority Mobile data connection.  This network type uses the
516     * same network interface as {@link #TYPE_MOBILE} but the routing setup
517     * is different.
518     *
519     * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or
520     *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an
521     *         appropriate network. {@see NetworkCapabilities} for supported transports.
522     */
523    @Deprecated
524    public static final int TYPE_MOBILE_HIPRI = 5;
525
526    /**
527     * A WiMAX data connection.
528     *
529     * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or
530     *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an
531     *         appropriate network. {@see NetworkCapabilities} for supported transports.
532     */
533    @Deprecated
534    public static final int TYPE_WIMAX       = 6;
535
536    /**
537     * A Bluetooth data connection.
538     *
539     * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or
540     *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an
541     *         appropriate network. {@see NetworkCapabilities} for supported transports.
542     */
543    @Deprecated
544    public static final int TYPE_BLUETOOTH   = 7;
545
546    /**
547     * Dummy data connection.  This should not be used on shipping devices.
548     * @deprecated This is not used any more.
549     */
550    @Deprecated
551    public static final int TYPE_DUMMY       = 8;
552
553    /**
554     * An Ethernet data connection.
555     *
556     * @deprecated Applications should instead use {@link NetworkCapabilities#hasTransport} or
557     *         {@link #requestNetwork(NetworkRequest, NetworkCallback)} to request an
558     *         appropriate network. {@see NetworkCapabilities} for supported transports.
559     */
560    @Deprecated
561    public static final int TYPE_ETHERNET    = 9;
562
563    /**
564     * Over the air Administration.
565     * @deprecated Use {@link NetworkCapabilities} instead.
566     * {@hide}
567     */
568    @Deprecated
569    public static final int TYPE_MOBILE_FOTA = 10;
570
571    /**
572     * IP Multimedia Subsystem.
573     * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_IMS} instead.
574     * {@hide}
575     */
576    @Deprecated
577    public static final int TYPE_MOBILE_IMS  = 11;
578
579    /**
580     * Carrier Branded Services.
581     * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_CBS} instead.
582     * {@hide}
583     */
584    @Deprecated
585    public static final int TYPE_MOBILE_CBS  = 12;
586
587    /**
588     * A Wi-Fi p2p connection. Only requesting processes will have access to
589     * the peers connected.
590     * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_WIFI_P2P} instead.
591     * {@hide}
592     */
593    @Deprecated
594    public static final int TYPE_WIFI_P2P    = 13;
595
596    /**
597     * The network to use for initially attaching to the network
598     * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_IA} instead.
599     * {@hide}
600     */
601    @Deprecated
602    public static final int TYPE_MOBILE_IA = 14;
603
604    /**
605     * Emergency PDN connection for emergency services.  This
606     * may include IMS and MMS in emergency situations.
607     * @deprecated Use {@link NetworkCapabilities#NET_CAPABILITY_EIMS} instead.
608     * {@hide}
609     */
610    @Deprecated
611    public static final int TYPE_MOBILE_EMERGENCY = 15;
612
613    /**
614     * The network that uses proxy to achieve connectivity.
615     * @deprecated Use {@link NetworkCapabilities} instead.
616     * {@hide}
617     */
618    @Deprecated
619    public static final int TYPE_PROXY = 16;
620
621    /**
622     * A virtual network using one or more native bearers.
623     * It may or may not be providing security services.
624     * @deprecated Applications should use {@link NetworkCapabilities#TRANSPORT_VPN} instead.
625     */
626    @Deprecated
627    public static final int TYPE_VPN = 17;
628
629    /** {@hide} */
630    public static final int MAX_RADIO_TYPE   = TYPE_VPN;
631
632    /** {@hide} */
633    public static final int MAX_NETWORK_TYPE = TYPE_VPN;
634
635    private static final int MIN_NETWORK_TYPE = TYPE_MOBILE;
636
637    /**
638     * If you want to set the default network preference,you can directly
639     * change the networkAttributes array in framework's config.xml.
640     *
641     * @deprecated Since we support so many more networks now, the single
642     *             network default network preference can't really express
643     *             the hierarchy.  Instead, the default is defined by the
644     *             networkAttributes in config.xml.  You can determine
645     *             the current value by calling {@link #getNetworkPreference()}
646     *             from an App.
647     */
648    @Deprecated
649    public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
650
651    /**
652     * @hide
653     */
654    public static final int REQUEST_ID_UNSET = 0;
655
656    /**
657     * Static unique request used as a tombstone for NetworkCallbacks that have been unregistered.
658     * This allows to distinguish when unregistering NetworkCallbacks those that were never
659     * registered and those that were already unregistered.
660     * @hide
661     */
662    private static final NetworkRequest ALREADY_UNREGISTERED =
663            new NetworkRequest.Builder().clearCapabilities().build();
664
665    /**
666     * A NetID indicating no Network is selected.
667     * Keep in sync with bionic/libc/dns/include/resolv_netid.h
668     * @hide
669     */
670    public static final int NETID_UNSET = 0;
671
672    /**
673     * Private DNS Mode values.
674     *
675     * The "private_dns_mode" global setting stores a String value which is
676     * expected to be one of the following.
677     */
678
679    /**
680     * @hide
681     */
682    public static final String PRIVATE_DNS_MODE_OFF = "off";
683    /**
684     * @hide
685     */
686    public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic";
687    /**
688     * @hide
689     */
690    public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname";
691    /**
692     * The default Private DNS mode.
693     *
694     * This may change from release to release or may become dependent upon
695     * the capabilities of the underlying platform.
696     *
697     * @hide
698     */
699    public static final String PRIVATE_DNS_DEFAULT_MODE = PRIVATE_DNS_MODE_OPPORTUNISTIC;
700
701    private final IConnectivityManager mService;
702    /**
703     * A kludge to facilitate static access where a Context pointer isn't available, like in the
704     * case of the static set/getProcessDefaultNetwork methods and from the Network class.
705     * TODO: Remove this after deprecating the static methods in favor of non-static methods or
706     * methods that take a Context argument.
707     */
708    private static ConnectivityManager sInstance;
709
710    private final Context mContext;
711
712    private INetworkManagementService mNMService;
713    private INetworkPolicyManager mNPManager;
714
715    /**
716     * Tests if a given integer represents a valid network type.
717     * @param networkType the type to be tested
718     * @return a boolean.  {@code true} if the type is valid, else {@code false}
719     * @deprecated All APIs accepting a network type are deprecated. There should be no need to
720     *             validate a network type.
721     */
722    @Deprecated
723    public static boolean isNetworkTypeValid(int networkType) {
724        return MIN_NETWORK_TYPE <= networkType && networkType <= MAX_NETWORK_TYPE;
725    }
726
727    /**
728     * Returns a non-localized string representing a given network type.
729     * ONLY used for debugging output.
730     * @param type the type needing naming
731     * @return a String for the given type, or a string version of the type ("87")
732     * if no name is known.
733     * @deprecated Types are deprecated. Use {@link NetworkCapabilities} instead.
734     * {@hide}
735     */
736    @Deprecated
737    public static String getNetworkTypeName(int type) {
738        switch (type) {
739          case TYPE_NONE:
740                return "NONE";
741            case TYPE_MOBILE:
742                return "MOBILE";
743            case TYPE_WIFI:
744                return "WIFI";
745            case TYPE_MOBILE_MMS:
746                return "MOBILE_MMS";
747            case TYPE_MOBILE_SUPL:
748                return "MOBILE_SUPL";
749            case TYPE_MOBILE_DUN:
750                return "MOBILE_DUN";
751            case TYPE_MOBILE_HIPRI:
752                return "MOBILE_HIPRI";
753            case TYPE_WIMAX:
754                return "WIMAX";
755            case TYPE_BLUETOOTH:
756                return "BLUETOOTH";
757            case TYPE_DUMMY:
758                return "DUMMY";
759            case TYPE_ETHERNET:
760                return "ETHERNET";
761            case TYPE_MOBILE_FOTA:
762                return "MOBILE_FOTA";
763            case TYPE_MOBILE_IMS:
764                return "MOBILE_IMS";
765            case TYPE_MOBILE_CBS:
766                return "MOBILE_CBS";
767            case TYPE_WIFI_P2P:
768                return "WIFI_P2P";
769            case TYPE_MOBILE_IA:
770                return "MOBILE_IA";
771            case TYPE_MOBILE_EMERGENCY:
772                return "MOBILE_EMERGENCY";
773            case TYPE_PROXY:
774                return "PROXY";
775            case TYPE_VPN:
776                return "VPN";
777            default:
778                return Integer.toString(type);
779        }
780    }
781
782    /**
783     * Checks if a given type uses the cellular data connection.
784     * This should be replaced in the future by a network property.
785     * @param networkType the type to check
786     * @return a boolean - {@code true} if uses cellular network, else {@code false}
787     * @deprecated Types are deprecated. Use {@link NetworkCapabilities} instead.
788     * {@hide}
789     */
790    @Deprecated
791    public static boolean isNetworkTypeMobile(int networkType) {
792        switch (networkType) {
793            case TYPE_MOBILE:
794            case TYPE_MOBILE_MMS:
795            case TYPE_MOBILE_SUPL:
796            case TYPE_MOBILE_DUN:
797            case TYPE_MOBILE_HIPRI:
798            case TYPE_MOBILE_FOTA:
799            case TYPE_MOBILE_IMS:
800            case TYPE_MOBILE_CBS:
801            case TYPE_MOBILE_IA:
802            case TYPE_MOBILE_EMERGENCY:
803                return true;
804            default:
805                return false;
806        }
807    }
808
809    /**
810     * Checks if the given network type is backed by a Wi-Fi radio.
811     *
812     * @deprecated Types are deprecated. Use {@link NetworkCapabilities} instead.
813     * @hide
814     */
815    @Deprecated
816    public static boolean isNetworkTypeWifi(int networkType) {
817        switch (networkType) {
818            case TYPE_WIFI:
819            case TYPE_WIFI_P2P:
820                return true;
821            default:
822                return false;
823        }
824    }
825
826    /**
827     * Specifies the preferred network type.  When the device has more
828     * than one type available the preferred network type will be used.
829     *
830     * @param preference the network type to prefer over all others.  It is
831     *         unspecified what happens to the old preferred network in the
832     *         overall ordering.
833     * @deprecated Functionality has been removed as it no longer makes sense,
834     *             with many more than two networks - we'd need an array to express
835     *             preference.  Instead we use dynamic network properties of
836     *             the networks to describe their precedence.
837     */
838    @Deprecated
839    public void setNetworkPreference(int preference) {
840    }
841
842    /**
843     * Retrieves the current preferred network type.
844     *
845     * @return an integer representing the preferred network type
846     *
847     * @deprecated Functionality has been removed as it no longer makes sense,
848     *             with many more than two networks - we'd need an array to express
849     *             preference.  Instead we use dynamic network properties of
850     *             the networks to describe their precedence.
851     */
852    @Deprecated
853    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
854    public int getNetworkPreference() {
855        return TYPE_NONE;
856    }
857
858    /**
859     * Returns details about the currently active default data network. When
860     * connected, this network is the default route for outgoing connections.
861     * You should always check {@link NetworkInfo#isConnected()} before initiating
862     * network traffic. This may return {@code null} when there is no default
863     * network.
864     *
865     * @return a {@link NetworkInfo} object for the current default network
866     *        or {@code null} if no default network is currently active
867     */
868    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
869    public NetworkInfo getActiveNetworkInfo() {
870        try {
871            return mService.getActiveNetworkInfo();
872        } catch (RemoteException e) {
873            throw e.rethrowFromSystemServer();
874        }
875    }
876
877    /**
878     * Returns a {@link Network} object corresponding to the currently active
879     * default data network.  In the event that the current active default data
880     * network disconnects, the returned {@code Network} object will no longer
881     * be usable.  This will return {@code null} when there is no default
882     * network.
883     *
884     * @return a {@link Network} object for the current default network or
885     *        {@code null} if no default network is currently active
886     */
887    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
888    public Network getActiveNetwork() {
889        try {
890            return mService.getActiveNetwork();
891        } catch (RemoteException e) {
892            throw e.rethrowFromSystemServer();
893        }
894    }
895
896    /**
897     * Returns a {@link Network} object corresponding to the currently active
898     * default data network for a specific UID.  In the event that the default data
899     * network disconnects, the returned {@code Network} object will no longer
900     * be usable.  This will return {@code null} when there is no default
901     * network for the UID.
902     *
903     * @return a {@link Network} object for the current default network for the
904     *         given UID or {@code null} if no default network is currently active
905     *
906     * @hide
907     */
908    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
909    public Network getActiveNetworkForUid(int uid) {
910        return getActiveNetworkForUid(uid, false);
911    }
912
913    /** {@hide} */
914    public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
915        try {
916            return mService.getActiveNetworkForUid(uid, ignoreBlocked);
917        } catch (RemoteException e) {
918            throw e.rethrowFromSystemServer();
919        }
920    }
921
922    /**
923     * Checks if a VPN app supports always-on mode.
924     *
925     * In order to support the always-on feature, an app has to
926     * <ul>
927     *     <li>target {@link VERSION_CODES#N API 24} or above, and
928     *     <li>not opt out through the {@link VpnService#SERVICE_META_DATA_SUPPORTS_ALWAYS_ON}
929     *         meta-data field.
930     * </ul>
931     *
932     * @param userId The identifier of the user for whom the VPN app is installed.
933     * @param vpnPackage The canonical package name of the VPN app.
934     * @return {@code true} if and only if the VPN app exists and supports always-on mode.
935     * @hide
936     */
937    public boolean isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage) {
938        try {
939            return mService.isAlwaysOnVpnPackageSupported(userId, vpnPackage);
940        } catch (RemoteException e) {
941            throw e.rethrowFromSystemServer();
942        }
943    }
944
945    /**
946     * Configures an always-on VPN connection through a specific application.
947     * This connection is automatically granted and persisted after a reboot.
948     *
949     * <p>The designated package should declare a {@link VpnService} in its
950     *    manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE},
951     *    otherwise the call will fail.
952     *
953     * @param userId The identifier of the user to set an always-on VPN for.
954     * @param vpnPackage The package name for an installed VPN app on the device, or {@code null}
955     *                   to remove an existing always-on VPN configuration.
956     * @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or
957     *        {@code false} otherwise.
958     * @return {@code true} if the package is set as always-on VPN controller;
959     *         {@code false} otherwise.
960     * @hide
961     */
962    public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
963            boolean lockdownEnabled) {
964        try {
965            return mService.setAlwaysOnVpnPackage(userId, vpnPackage, lockdownEnabled);
966        } catch (RemoteException e) {
967            throw e.rethrowFromSystemServer();
968        }
969    }
970
971    /**
972     * Returns the package name of the currently set always-on VPN application.
973     * If there is no always-on VPN set, or the VPN is provided by the system instead
974     * of by an app, {@code null} will be returned.
975     *
976     * @return Package name of VPN controller responsible for always-on VPN,
977     *         or {@code null} if none is set.
978     * @hide
979     */
980    public String getAlwaysOnVpnPackageForUser(int userId) {
981        try {
982            return mService.getAlwaysOnVpnPackage(userId);
983        } catch (RemoteException e) {
984            throw e.rethrowFromSystemServer();
985        }
986    }
987
988    /**
989     * Returns details about the currently active default data network
990     * for a given uid.  This is for internal use only to avoid spying
991     * other apps.
992     *
993     * @return a {@link NetworkInfo} object for the current default network
994     *        for the given uid or {@code null} if no default network is
995     *        available for the specified uid.
996     *
997     * {@hide}
998     */
999    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
1000    public NetworkInfo getActiveNetworkInfoForUid(int uid) {
1001        return getActiveNetworkInfoForUid(uid, false);
1002    }
1003
1004    /** {@hide} */
1005    public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
1006        try {
1007            return mService.getActiveNetworkInfoForUid(uid, ignoreBlocked);
1008        } catch (RemoteException e) {
1009            throw e.rethrowFromSystemServer();
1010        }
1011    }
1012
1013    /**
1014     * Returns connection status information about a particular
1015     * network type.
1016     *
1017     * @param networkType integer specifying which networkType in
1018     *        which you're interested.
1019     * @return a {@link NetworkInfo} object for the requested
1020     *        network type or {@code null} if the type is not
1021     *        supported by the device.
1022     *
1023     * @deprecated This method does not support multiple connected networks
1024     *             of the same type. Use {@link #getAllNetworks} and
1025     *             {@link #getNetworkInfo(android.net.Network)} instead.
1026     */
1027    @Deprecated
1028    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
1029    public NetworkInfo getNetworkInfo(int networkType) {
1030        try {
1031            return mService.getNetworkInfo(networkType);
1032        } catch (RemoteException e) {
1033            throw e.rethrowFromSystemServer();
1034        }
1035    }
1036
1037    /**
1038     * Returns connection status information about a particular
1039     * Network.
1040     *
1041     * @param network {@link Network} specifying which network
1042     *        in which you're interested.
1043     * @return a {@link NetworkInfo} object for the requested
1044     *        network or {@code null} if the {@code Network}
1045     *        is not valid.
1046     */
1047    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
1048    public NetworkInfo getNetworkInfo(Network network) {
1049        return getNetworkInfoForUid(network, Process.myUid(), false);
1050    }
1051
1052    /** {@hide} */
1053    public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
1054        try {
1055            return mService.getNetworkInfoForUid(network, uid, ignoreBlocked);
1056        } catch (RemoteException e) {
1057            throw e.rethrowFromSystemServer();
1058        }
1059    }
1060
1061    /**
1062     * Returns connection status information about all network
1063     * types supported by the device.
1064     *
1065     * @return an array of {@link NetworkInfo} objects.  Check each
1066     * {@link NetworkInfo#getType} for which type each applies.
1067     *
1068     * @deprecated This method does not support multiple connected networks
1069     *             of the same type. Use {@link #getAllNetworks} and
1070     *             {@link #getNetworkInfo(android.net.Network)} instead.
1071     */
1072    @Deprecated
1073    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
1074    public NetworkInfo[] getAllNetworkInfo() {
1075        try {
1076            return mService.getAllNetworkInfo();
1077        } catch (RemoteException e) {
1078            throw e.rethrowFromSystemServer();
1079        }
1080    }
1081
1082    /**
1083     * Returns the {@link Network} object currently serving a given type, or
1084     * null if the given type is not connected.
1085     *
1086     * @hide
1087     * @deprecated This method does not support multiple connected networks
1088     *             of the same type. Use {@link #getAllNetworks} and
1089     *             {@link #getNetworkInfo(android.net.Network)} instead.
1090     */
1091    @Deprecated
1092    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
1093    public Network getNetworkForType(int networkType) {
1094        try {
1095            return mService.getNetworkForType(networkType);
1096        } catch (RemoteException e) {
1097            throw e.rethrowFromSystemServer();
1098        }
1099    }
1100
1101    /**
1102     * Returns an array of all {@link Network} currently tracked by the
1103     * framework.
1104     *
1105     * @return an array of {@link Network} objects.
1106     */
1107    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
1108    public Network[] getAllNetworks() {
1109        try {
1110            return mService.getAllNetworks();
1111        } catch (RemoteException e) {
1112            throw e.rethrowFromSystemServer();
1113        }
1114    }
1115
1116    /**
1117     * Returns an array of {@link android.net.NetworkCapabilities} objects, representing
1118     * the Networks that applications run by the given user will use by default.
1119     * @hide
1120     */
1121    public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
1122        try {
1123            return mService.getDefaultNetworkCapabilitiesForUser(userId);
1124        } catch (RemoteException e) {
1125            throw e.rethrowFromSystemServer();
1126        }
1127    }
1128
1129    /**
1130     * Returns the IP information for the current default network.
1131     *
1132     * @return a {@link LinkProperties} object describing the IP info
1133     *        for the current default network, or {@code null} if there
1134     *        is no current default network.
1135     *
1136     * {@hide}
1137     */
1138    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
1139    public LinkProperties getActiveLinkProperties() {
1140        try {
1141            return mService.getActiveLinkProperties();
1142        } catch (RemoteException e) {
1143            throw e.rethrowFromSystemServer();
1144        }
1145    }
1146
1147    /**
1148     * Returns the IP information for a given network type.
1149     *
1150     * @param networkType the network type of interest.
1151     * @return a {@link LinkProperties} object describing the IP info
1152     *        for the given networkType, or {@code null} if there is
1153     *        no current default network.
1154     *
1155     * {@hide}
1156     * @deprecated This method does not support multiple connected networks
1157     *             of the same type. Use {@link #getAllNetworks},
1158     *             {@link #getNetworkInfo(android.net.Network)}, and
1159     *             {@link #getLinkProperties(android.net.Network)} instead.
1160     */
1161    @Deprecated
1162    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
1163    public LinkProperties getLinkProperties(int networkType) {
1164        try {
1165            return mService.getLinkPropertiesForType(networkType);
1166        } catch (RemoteException e) {
1167            throw e.rethrowFromSystemServer();
1168        }
1169    }
1170
1171    /**
1172     * Get the {@link LinkProperties} for the given {@link Network}.  This
1173     * will return {@code null} if the network is unknown.
1174     *
1175     * @param network The {@link Network} object identifying the network in question.
1176     * @return The {@link LinkProperties} for the network, or {@code null}.
1177     */
1178    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
1179    public LinkProperties getLinkProperties(Network network) {
1180        try {
1181            return mService.getLinkProperties(network);
1182        } catch (RemoteException e) {
1183            throw e.rethrowFromSystemServer();
1184        }
1185    }
1186
1187    /**
1188     * Get the {@link android.net.NetworkCapabilities} for the given {@link Network}.  This
1189     * will return {@code null} if the network is unknown.
1190     *
1191     * @param network The {@link Network} object identifying the network in question.
1192     * @return The {@link android.net.NetworkCapabilities} for the network, or {@code null}.
1193     */
1194    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
1195    public NetworkCapabilities getNetworkCapabilities(Network network) {
1196        try {
1197            return mService.getNetworkCapabilities(network);
1198        } catch (RemoteException e) {
1199            throw e.rethrowFromSystemServer();
1200        }
1201    }
1202
1203    /**
1204     * Gets the URL that should be used for resolving whether a captive portal is present.
1205     * 1. This URL should respond with a 204 response to a GET request to indicate no captive
1206     *    portal is present.
1207     * 2. This URL must be HTTP as redirect responses are used to find captive portal
1208     *    sign-in pages. Captive portals cannot respond to HTTPS requests with redirects.
1209     *
1210     * @hide
1211     */
1212    @SystemApi
1213    @RequiresPermission(android.Manifest.permission.LOCAL_MAC_ADDRESS)
1214    public String getCaptivePortalServerUrl() {
1215        try {
1216            return mService.getCaptivePortalServerUrl();
1217        } catch (RemoteException e) {
1218            throw e.rethrowFromSystemServer();
1219        }
1220    }
1221
1222    /**
1223     * Tells the underlying networking system that the caller wants to
1224     * begin using the named feature. The interpretation of {@code feature}
1225     * is completely up to each networking implementation.
1226     *
1227     * <p>This method requires the caller to hold either the
1228     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
1229     * or the ability to modify system settings as determined by
1230     * {@link android.provider.Settings.System#canWrite}.</p>
1231     *
1232     * @param networkType specifies which network the request pertains to
1233     * @param feature the name of the feature to be used
1234     * @return an integer value representing the outcome of the request.
1235     * The interpretation of this value is specific to each networking
1236     * implementation+feature combination, except that the value {@code -1}
1237     * always indicates failure.
1238     *
1239     * @deprecated Deprecated in favor of the cleaner
1240     *             {@link #requestNetwork(NetworkRequest, NetworkCallback)} API.
1241     *             In {@link VERSION_CODES#M}, and above, this method is unsupported and will
1242     *             throw {@code UnsupportedOperationException} if called.
1243     * @removed
1244     */
1245    @Deprecated
1246    public int startUsingNetworkFeature(int networkType, String feature) {
1247        checkLegacyRoutingApiAccess();
1248        NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
1249        if (netCap == null) {
1250            Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " +
1251                    feature);
1252            return PhoneConstants.APN_REQUEST_FAILED;
1253        }
1254
1255        NetworkRequest request = null;
1256        synchronized (sLegacyRequests) {
1257            LegacyRequest l = sLegacyRequests.get(netCap);
1258            if (l != null) {
1259                Log.d(TAG, "renewing startUsingNetworkFeature request " + l.networkRequest);
1260                renewRequestLocked(l);
1261                if (l.currentNetwork != null) {
1262                    return PhoneConstants.APN_ALREADY_ACTIVE;
1263                } else {
1264                    return PhoneConstants.APN_REQUEST_STARTED;
1265                }
1266            }
1267
1268            request = requestNetworkForFeatureLocked(netCap);
1269        }
1270        if (request != null) {
1271            Log.d(TAG, "starting startUsingNetworkFeature for request " + request);
1272            return PhoneConstants.APN_REQUEST_STARTED;
1273        } else {
1274            Log.d(TAG, " request Failed");
1275            return PhoneConstants.APN_REQUEST_FAILED;
1276        }
1277    }
1278
1279    /**
1280     * Tells the underlying networking system that the caller is finished
1281     * using the named feature. The interpretation of {@code feature}
1282     * is completely up to each networking implementation.
1283     *
1284     * <p>This method requires the caller to hold either the
1285     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
1286     * or the ability to modify system settings as determined by
1287     * {@link android.provider.Settings.System#canWrite}.</p>
1288     *
1289     * @param networkType specifies which network the request pertains to
1290     * @param feature the name of the feature that is no longer needed
1291     * @return an integer value representing the outcome of the request.
1292     * The interpretation of this value is specific to each networking
1293     * implementation+feature combination, except that the value {@code -1}
1294     * always indicates failure.
1295     *
1296     * @deprecated Deprecated in favor of the cleaner
1297     *             {@link #unregisterNetworkCallback(NetworkCallback)} API.
1298     *             In {@link VERSION_CODES#M}, and above, this method is unsupported and will
1299     *             throw {@code UnsupportedOperationException} if called.
1300     * @removed
1301     */
1302    @Deprecated
1303    public int stopUsingNetworkFeature(int networkType, String feature) {
1304        checkLegacyRoutingApiAccess();
1305        NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
1306        if (netCap == null) {
1307            Log.d(TAG, "Can't satisfy stopUsingNetworkFeature for " + networkType + ", " +
1308                    feature);
1309            return -1;
1310        }
1311
1312        if (removeRequestForFeature(netCap)) {
1313            Log.d(TAG, "stopUsingNetworkFeature for " + networkType + ", " + feature);
1314        }
1315        return 1;
1316    }
1317
1318    private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
1319        if (networkType == TYPE_MOBILE) {
1320            switch (feature) {
1321                case "enableCBS":
1322                    return networkCapabilitiesForType(TYPE_MOBILE_CBS);
1323                case "enableDUN":
1324                case "enableDUNAlways":
1325                    return networkCapabilitiesForType(TYPE_MOBILE_DUN);
1326                case "enableFOTA":
1327                    return networkCapabilitiesForType(TYPE_MOBILE_FOTA);
1328                case "enableHIPRI":
1329                    return networkCapabilitiesForType(TYPE_MOBILE_HIPRI);
1330                case "enableIMS":
1331                    return networkCapabilitiesForType(TYPE_MOBILE_IMS);
1332                case "enableMMS":
1333                    return networkCapabilitiesForType(TYPE_MOBILE_MMS);
1334                case "enableSUPL":
1335                    return networkCapabilitiesForType(TYPE_MOBILE_SUPL);
1336                default:
1337                    return null;
1338            }
1339        } else if (networkType == TYPE_WIFI && "p2p".equals(feature)) {
1340            return networkCapabilitiesForType(TYPE_WIFI_P2P);
1341        }
1342        return null;
1343    }
1344
1345    /**
1346     * Guess what the network request was trying to say so that the resulting
1347     * network is accessible via the legacy (deprecated) API such as
1348     * requestRouteToHost.
1349     *
1350     * This means we should try to be fairly precise about transport and
1351     * capability but ignore things such as networkSpecifier.
1352     * If the request has more than one transport or capability it doesn't
1353     * match the old legacy requests (they selected only single transport/capability)
1354     * so this function cannot map the request to a single legacy type and
1355     * the resulting network will not be available to the legacy APIs.
1356     *
1357     * This code is only called from the requestNetwork API (L and above).
1358     *
1359     * Setting a legacy type causes CONNECTIVITY_ACTION broadcasts, which are expensive
1360     * because they wake up lots of apps - see http://b/23350688 . So we currently only
1361     * do this for SUPL requests, which are the only ones that we know need it. If
1362     * omitting these broadcasts causes unacceptable app breakage, then for backwards
1363     * compatibility we can send them:
1364     *
1365     * if (targetSdkVersion < Build.VERSION_CODES.M) &&        // legacy API unsupported >= M
1366     *     targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP))  // requestNetwork not present < L
1367     *
1368     * TODO - This should be removed when the legacy APIs are removed.
1369     */
1370    private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
1371        if (netCap == null) {
1372            return TYPE_NONE;
1373        }
1374
1375        if (!netCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
1376            return TYPE_NONE;
1377        }
1378
1379        // Do this only for SUPL, until GnssLocationProvider is fixed. http://b/25876485 .
1380        if (!netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
1381            // NOTE: if this causes app breakage, we should not just comment out this early return;
1382            // instead, we should make this early return conditional on the requesting app's target
1383            // SDK version, as described in the comment above.
1384            return TYPE_NONE;
1385        }
1386
1387        String type = null;
1388        int result = TYPE_NONE;
1389
1390        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
1391            type = "enableCBS";
1392            result = TYPE_MOBILE_CBS;
1393        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
1394            type = "enableIMS";
1395            result = TYPE_MOBILE_IMS;
1396        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
1397            type = "enableFOTA";
1398            result = TYPE_MOBILE_FOTA;
1399        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
1400            type = "enableDUN";
1401            result = TYPE_MOBILE_DUN;
1402        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
1403            type = "enableSUPL";
1404            result = TYPE_MOBILE_SUPL;
1405        // back out this hack for mms as they no longer need this and it's causing
1406        // device slowdowns - b/23350688 (note, supl still needs this)
1407        //} else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
1408        //    type = "enableMMS";
1409        //    result = TYPE_MOBILE_MMS;
1410        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
1411            type = "enableHIPRI";
1412            result = TYPE_MOBILE_HIPRI;
1413        }
1414        if (type != null) {
1415            NetworkCapabilities testCap = networkCapabilitiesForFeature(TYPE_MOBILE, type);
1416            if (testCap.equalsNetCapabilities(netCap) && testCap.equalsTransportTypes(netCap)) {
1417                return result;
1418            }
1419        }
1420        return TYPE_NONE;
1421    }
1422
1423    private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
1424        if (netCap == null) return TYPE_NONE;
1425        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
1426            return TYPE_MOBILE_CBS;
1427        }
1428        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
1429            return TYPE_MOBILE_IMS;
1430        }
1431        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
1432            return TYPE_MOBILE_FOTA;
1433        }
1434        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
1435            return TYPE_MOBILE_DUN;
1436        }
1437        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
1438            return TYPE_MOBILE_SUPL;
1439        }
1440        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
1441            return TYPE_MOBILE_MMS;
1442        }
1443        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
1444            return TYPE_MOBILE_HIPRI;
1445        }
1446        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) {
1447            return TYPE_WIFI_P2P;
1448        }
1449        return TYPE_NONE;
1450    }
1451
1452    private static class LegacyRequest {
1453        NetworkCapabilities networkCapabilities;
1454        NetworkRequest networkRequest;
1455        int expireSequenceNumber;
1456        Network currentNetwork;
1457        int delay = -1;
1458
1459        private void clearDnsBinding() {
1460            if (currentNetwork != null) {
1461                currentNetwork = null;
1462                setProcessDefaultNetworkForHostResolution(null);
1463            }
1464        }
1465
1466        NetworkCallback networkCallback = new NetworkCallback() {
1467            @Override
1468            public void onAvailable(Network network) {
1469                currentNetwork = network;
1470                Log.d(TAG, "startUsingNetworkFeature got Network:" + network);
1471                setProcessDefaultNetworkForHostResolution(network);
1472            }
1473            @Override
1474            public void onLost(Network network) {
1475                if (network.equals(currentNetwork)) clearDnsBinding();
1476                Log.d(TAG, "startUsingNetworkFeature lost Network:" + network);
1477            }
1478        };
1479    }
1480
1481    private static HashMap<NetworkCapabilities, LegacyRequest> sLegacyRequests =
1482            new HashMap<NetworkCapabilities, LegacyRequest>();
1483
1484    private NetworkRequest findRequestForFeature(NetworkCapabilities netCap) {
1485        synchronized (sLegacyRequests) {
1486            LegacyRequest l = sLegacyRequests.get(netCap);
1487            if (l != null) return l.networkRequest;
1488        }
1489        return null;
1490    }
1491
1492    private void renewRequestLocked(LegacyRequest l) {
1493        l.expireSequenceNumber++;
1494        Log.d(TAG, "renewing request to seqNum " + l.expireSequenceNumber);
1495        sendExpireMsgForFeature(l.networkCapabilities, l.expireSequenceNumber, l.delay);
1496    }
1497
1498    private void expireRequest(NetworkCapabilities netCap, int sequenceNum) {
1499        int ourSeqNum = -1;
1500        synchronized (sLegacyRequests) {
1501            LegacyRequest l = sLegacyRequests.get(netCap);
1502            if (l == null) return;
1503            ourSeqNum = l.expireSequenceNumber;
1504            if (l.expireSequenceNumber == sequenceNum) removeRequestForFeature(netCap);
1505        }
1506        Log.d(TAG, "expireRequest with " + ourSeqNum + ", " + sequenceNum);
1507    }
1508
1509    private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) {
1510        int delay = -1;
1511        int type = legacyTypeForNetworkCapabilities(netCap);
1512        try {
1513            delay = mService.getRestoreDefaultNetworkDelay(type);
1514        } catch (RemoteException e) {
1515            throw e.rethrowFromSystemServer();
1516        }
1517        LegacyRequest l = new LegacyRequest();
1518        l.networkCapabilities = netCap;
1519        l.delay = delay;
1520        l.expireSequenceNumber = 0;
1521        l.networkRequest = sendRequestForNetwork(
1522                netCap, l.networkCallback, 0, REQUEST, type, getDefaultHandler());
1523        if (l.networkRequest == null) return null;
1524        sLegacyRequests.put(netCap, l);
1525        sendExpireMsgForFeature(netCap, l.expireSequenceNumber, delay);
1526        return l.networkRequest;
1527    }
1528
1529    private void sendExpireMsgForFeature(NetworkCapabilities netCap, int seqNum, int delay) {
1530        if (delay >= 0) {
1531            Log.d(TAG, "sending expire msg with seqNum " + seqNum + " and delay " + delay);
1532            CallbackHandler handler = getDefaultHandler();
1533            Message msg = handler.obtainMessage(EXPIRE_LEGACY_REQUEST, seqNum, 0, netCap);
1534            handler.sendMessageDelayed(msg, delay);
1535        }
1536    }
1537
1538    private boolean removeRequestForFeature(NetworkCapabilities netCap) {
1539        final LegacyRequest l;
1540        synchronized (sLegacyRequests) {
1541            l = sLegacyRequests.remove(netCap);
1542        }
1543        if (l == null) return false;
1544        unregisterNetworkCallback(l.networkCallback);
1545        l.clearDnsBinding();
1546        return true;
1547    }
1548
1549    private static final SparseIntArray sLegacyTypeToTransport = new SparseIntArray();
1550    static {
1551        sLegacyTypeToTransport.put(TYPE_MOBILE,       NetworkCapabilities.TRANSPORT_CELLULAR);
1552        sLegacyTypeToTransport.put(TYPE_MOBILE_CBS,   NetworkCapabilities.TRANSPORT_CELLULAR);
1553        sLegacyTypeToTransport.put(TYPE_MOBILE_DUN,   NetworkCapabilities.TRANSPORT_CELLULAR);
1554        sLegacyTypeToTransport.put(TYPE_MOBILE_FOTA,  NetworkCapabilities.TRANSPORT_CELLULAR);
1555        sLegacyTypeToTransport.put(TYPE_MOBILE_HIPRI, NetworkCapabilities.TRANSPORT_CELLULAR);
1556        sLegacyTypeToTransport.put(TYPE_MOBILE_IMS,   NetworkCapabilities.TRANSPORT_CELLULAR);
1557        sLegacyTypeToTransport.put(TYPE_MOBILE_MMS,   NetworkCapabilities.TRANSPORT_CELLULAR);
1558        sLegacyTypeToTransport.put(TYPE_MOBILE_SUPL,  NetworkCapabilities.TRANSPORT_CELLULAR);
1559        sLegacyTypeToTransport.put(TYPE_WIFI,         NetworkCapabilities.TRANSPORT_WIFI);
1560        sLegacyTypeToTransport.put(TYPE_WIFI_P2P,     NetworkCapabilities.TRANSPORT_WIFI);
1561        sLegacyTypeToTransport.put(TYPE_BLUETOOTH,    NetworkCapabilities.TRANSPORT_BLUETOOTH);
1562        sLegacyTypeToTransport.put(TYPE_ETHERNET,     NetworkCapabilities.TRANSPORT_ETHERNET);
1563    }
1564
1565    private static final SparseIntArray sLegacyTypeToCapability = new SparseIntArray();
1566    static {
1567        sLegacyTypeToCapability.put(TYPE_MOBILE_CBS,  NetworkCapabilities.NET_CAPABILITY_CBS);
1568        sLegacyTypeToCapability.put(TYPE_MOBILE_DUN,  NetworkCapabilities.NET_CAPABILITY_DUN);
1569        sLegacyTypeToCapability.put(TYPE_MOBILE_FOTA, NetworkCapabilities.NET_CAPABILITY_FOTA);
1570        sLegacyTypeToCapability.put(TYPE_MOBILE_IMS,  NetworkCapabilities.NET_CAPABILITY_IMS);
1571        sLegacyTypeToCapability.put(TYPE_MOBILE_MMS,  NetworkCapabilities.NET_CAPABILITY_MMS);
1572        sLegacyTypeToCapability.put(TYPE_MOBILE_SUPL, NetworkCapabilities.NET_CAPABILITY_SUPL);
1573        sLegacyTypeToCapability.put(TYPE_WIFI_P2P,    NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
1574    }
1575
1576    /**
1577     * Given a legacy type (TYPE_WIFI, ...) returns a NetworkCapabilities
1578     * instance suitable for registering a request or callback.  Throws an
1579     * IllegalArgumentException if no mapping from the legacy type to
1580     * NetworkCapabilities is known.
1581     *
1582     * @deprecated Types are deprecated. Use {@link NetworkCallback} or {@link NetworkRequest}
1583     *     to find the network instead.
1584     * @hide
1585     */
1586    public static NetworkCapabilities networkCapabilitiesForType(int type) {
1587        final NetworkCapabilities nc = new NetworkCapabilities();
1588
1589        // Map from type to transports.
1590        final int NOT_FOUND = -1;
1591        final int transport = sLegacyTypeToTransport.get(type, NOT_FOUND);
1592        Preconditions.checkArgument(transport != NOT_FOUND, "unknown legacy type: " + type);
1593        nc.addTransportType(transport);
1594
1595        // Map from type to capabilities.
1596        nc.addCapability(sLegacyTypeToCapability.get(
1597                type, NetworkCapabilities.NET_CAPABILITY_INTERNET));
1598        nc.maybeMarkCapabilitiesRestricted();
1599        return nc;
1600    }
1601
1602    /** @hide */
1603    public static class PacketKeepaliveCallback {
1604        /** The requested keepalive was successfully started. */
1605        public void onStarted() {}
1606        /** The keepalive was successfully stopped. */
1607        public void onStopped() {}
1608        /** An error occurred. */
1609        public void onError(int error) {}
1610    }
1611
1612    /**
1613     * Allows applications to request that the system periodically send specific packets on their
1614     * behalf, using hardware offload to save battery power.
1615     *
1616     * To request that the system send keepalives, call one of the methods that return a
1617     * {@link ConnectivityManager.PacketKeepalive} object, such as {@link #startNattKeepalive},
1618     * passing in a non-null callback. If the callback is successfully started, the callback's
1619     * {@code onStarted} method will be called. If an error occurs, {@code onError} will be called,
1620     * specifying one of the {@code ERROR_*} constants in this class.
1621     *
1622     * To stop an existing keepalive, call {@link stop}. The system will call {@code onStopped} if
1623     * the operation was successfull or {@code onError} if an error occurred.
1624     *
1625     * @hide
1626     */
1627    public class PacketKeepalive {
1628
1629        private static final String TAG = "PacketKeepalive";
1630
1631        /** @hide */
1632        public static final int SUCCESS = 0;
1633
1634        /** @hide */
1635        public static final int NO_KEEPALIVE = -1;
1636
1637        /** @hide */
1638        public static final int BINDER_DIED = -10;
1639
1640        /** The specified {@code Network} is not connected. */
1641        public static final int ERROR_INVALID_NETWORK = -20;
1642        /** The specified IP addresses are invalid. For example, the specified source IP address is
1643          * not configured on the specified {@code Network}. */
1644        public static final int ERROR_INVALID_IP_ADDRESS = -21;
1645        /** The requested port is invalid. */
1646        public static final int ERROR_INVALID_PORT = -22;
1647        /** The packet length is invalid (e.g., too long). */
1648        public static final int ERROR_INVALID_LENGTH = -23;
1649        /** The packet transmission interval is invalid (e.g., too short). */
1650        public static final int ERROR_INVALID_INTERVAL = -24;
1651
1652        /** The hardware does not support this request. */
1653        public static final int ERROR_HARDWARE_UNSUPPORTED = -30;
1654        /** The hardware returned an error. */
1655        public static final int ERROR_HARDWARE_ERROR = -31;
1656
1657        /** The NAT-T destination port for IPsec */
1658        public static final int NATT_PORT = 4500;
1659
1660        /** The minimum interval in seconds between keepalive packet transmissions */
1661        public static final int MIN_INTERVAL = 10;
1662
1663        private final Network mNetwork;
1664        private final PacketKeepaliveCallback mCallback;
1665        private final Looper mLooper;
1666        private final Messenger mMessenger;
1667
1668        private volatile Integer mSlot;
1669
1670        void stopLooper() {
1671            mLooper.quit();
1672        }
1673
1674        public void stop() {
1675            try {
1676                mService.stopKeepalive(mNetwork, mSlot);
1677            } catch (RemoteException e) {
1678                Log.e(TAG, "Error stopping packet keepalive: ", e);
1679                stopLooper();
1680            }
1681        }
1682
1683        private PacketKeepalive(Network network, PacketKeepaliveCallback callback) {
1684            Preconditions.checkNotNull(network, "network cannot be null");
1685            Preconditions.checkNotNull(callback, "callback cannot be null");
1686            mNetwork = network;
1687            mCallback = callback;
1688            HandlerThread thread = new HandlerThread(TAG);
1689            thread.start();
1690            mLooper = thread.getLooper();
1691            mMessenger = new Messenger(new Handler(mLooper) {
1692                @Override
1693                public void handleMessage(Message message) {
1694                    switch (message.what) {
1695                        case NetworkAgent.EVENT_PACKET_KEEPALIVE:
1696                            int error = message.arg2;
1697                            try {
1698                                if (error == SUCCESS) {
1699                                    if (mSlot == null) {
1700                                        mSlot = message.arg1;
1701                                        mCallback.onStarted();
1702                                    } else {
1703                                        mSlot = null;
1704                                        stopLooper();
1705                                        mCallback.onStopped();
1706                                    }
1707                                } else {
1708                                    stopLooper();
1709                                    mCallback.onError(error);
1710                                }
1711                            } catch (Exception e) {
1712                                Log.e(TAG, "Exception in keepalive callback(" + error + ")", e);
1713                            }
1714                            break;
1715                        default:
1716                            Log.e(TAG, "Unhandled message " + Integer.toHexString(message.what));
1717                            break;
1718                    }
1719                }
1720            });
1721        }
1722    }
1723
1724    /**
1725     * Starts an IPsec NAT-T keepalive packet with the specified parameters.
1726     *
1727     * @hide
1728     */
1729    public PacketKeepalive startNattKeepalive(
1730            Network network, int intervalSeconds, PacketKeepaliveCallback callback,
1731            InetAddress srcAddr, int srcPort, InetAddress dstAddr) {
1732        final PacketKeepalive k = new PacketKeepalive(network, callback);
1733        try {
1734            mService.startNattKeepalive(network, intervalSeconds, k.mMessenger, new Binder(),
1735                    srcAddr.getHostAddress(), srcPort, dstAddr.getHostAddress());
1736        } catch (RemoteException e) {
1737            Log.e(TAG, "Error starting packet keepalive: ", e);
1738            k.stopLooper();
1739            return null;
1740        }
1741        return k;
1742    }
1743
1744    /**
1745     * Ensure that a network route exists to deliver traffic to the specified
1746     * host via the specified network interface. An attempt to add a route that
1747     * already exists is ignored, but treated as successful.
1748     *
1749     * <p>This method requires the caller to hold either the
1750     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
1751     * or the ability to modify system settings as determined by
1752     * {@link android.provider.Settings.System#canWrite}.</p>
1753     *
1754     * @param networkType the type of the network over which traffic to the specified
1755     * host is to be routed
1756     * @param hostAddress the IP address of the host to which the route is desired
1757     * @return {@code true} on success, {@code false} on failure
1758     *
1759     * @deprecated Deprecated in favor of the
1760     *             {@link #requestNetwork(NetworkRequest, NetworkCallback)},
1761     *             {@link #bindProcessToNetwork} and {@link Network#getSocketFactory} API.
1762     *             In {@link VERSION_CODES#M}, and above, this method is unsupported and will
1763     *             throw {@code UnsupportedOperationException} if called.
1764     * @removed
1765     */
1766    @Deprecated
1767    public boolean requestRouteToHost(int networkType, int hostAddress) {
1768        return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress));
1769    }
1770
1771    /**
1772     * Ensure that a network route exists to deliver traffic to the specified
1773     * host via the specified network interface. An attempt to add a route that
1774     * already exists is ignored, but treated as successful.
1775     *
1776     * <p>This method requires the caller to hold either the
1777     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
1778     * or the ability to modify system settings as determined by
1779     * {@link android.provider.Settings.System#canWrite}.</p>
1780     *
1781     * @param networkType the type of the network over which traffic to the specified
1782     * host is to be routed
1783     * @param hostAddress the IP address of the host to which the route is desired
1784     * @return {@code true} on success, {@code false} on failure
1785     * @hide
1786     * @deprecated Deprecated in favor of the {@link #requestNetwork} and
1787     *             {@link #bindProcessToNetwork} API.
1788     */
1789    @Deprecated
1790    public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
1791        checkLegacyRoutingApiAccess();
1792        try {
1793            return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress());
1794        } catch (RemoteException e) {
1795            throw e.rethrowFromSystemServer();
1796        }
1797    }
1798
1799    /**
1800     * Returns the value of the setting for background data usage. If false,
1801     * applications should not use the network if the application is not in the
1802     * foreground. Developers should respect this setting, and check the value
1803     * of this before performing any background data operations.
1804     * <p>
1805     * All applications that have background services that use the network
1806     * should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}.
1807     * <p>
1808     * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability of
1809     * background data depends on several combined factors, and this method will
1810     * always return {@code true}. Instead, when background data is unavailable,
1811     * {@link #getActiveNetworkInfo()} will now appear disconnected.
1812     *
1813     * @return Whether background data usage is allowed.
1814     */
1815    @Deprecated
1816    public boolean getBackgroundDataSetting() {
1817        // assume that background data is allowed; final authority is
1818        // NetworkInfo which may be blocked.
1819        return true;
1820    }
1821
1822    /**
1823     * Sets the value of the setting for background data usage.
1824     *
1825     * @param allowBackgroundData Whether an application should use data while
1826     *            it is in the background.
1827     *
1828     * @attr ref android.Manifest.permission#CHANGE_BACKGROUND_DATA_SETTING
1829     * @see #getBackgroundDataSetting()
1830     * @hide
1831     */
1832    @Deprecated
1833    public void setBackgroundDataSetting(boolean allowBackgroundData) {
1834        // ignored
1835    }
1836
1837    /** {@hide} */
1838    @Deprecated
1839    public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
1840        try {
1841            return mService.getActiveNetworkQuotaInfo();
1842        } catch (RemoteException e) {
1843            throw e.rethrowFromSystemServer();
1844        }
1845    }
1846
1847    /**
1848     * @hide
1849     * @deprecated Talk to TelephonyManager directly
1850     */
1851    @Deprecated
1852    public boolean getMobileDataEnabled() {
1853        IBinder b = ServiceManager.getService(Context.TELEPHONY_SERVICE);
1854        if (b != null) {
1855            try {
1856                ITelephony it = ITelephony.Stub.asInterface(b);
1857                int subId = SubscriptionManager.getDefaultDataSubscriptionId();
1858                Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId);
1859                boolean retVal = it.isUserDataEnabled(subId);
1860                Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId
1861                        + " retVal=" + retVal);
1862                return retVal;
1863            } catch (RemoteException e) {
1864                throw e.rethrowFromSystemServer();
1865            }
1866        }
1867        Log.d("ConnectivityManager", "getMobileDataEnabled()- remote exception retVal=false");
1868        return false;
1869    }
1870
1871    /**
1872     * Callback for use with {@link ConnectivityManager#addDefaultNetworkActiveListener}
1873     * to find out when the system default network has gone in to a high power state.
1874     */
1875    public interface OnNetworkActiveListener {
1876        /**
1877         * Called on the main thread of the process to report that the current data network
1878         * has become active, and it is now a good time to perform any pending network
1879         * operations.  Note that this listener only tells you when the network becomes
1880         * active; if at any other time you want to know whether it is active (and thus okay
1881         * to initiate network traffic), you can retrieve its instantaneous state with
1882         * {@link ConnectivityManager#isDefaultNetworkActive}.
1883         */
1884        public void onNetworkActive();
1885    }
1886
1887    private INetworkManagementService getNetworkManagementService() {
1888        synchronized (this) {
1889            if (mNMService != null) {
1890                return mNMService;
1891            }
1892            IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
1893            mNMService = INetworkManagementService.Stub.asInterface(b);
1894            return mNMService;
1895        }
1896    }
1897
1898    private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
1899            mNetworkActivityListeners
1900                    = new ArrayMap<OnNetworkActiveListener, INetworkActivityListener>();
1901
1902    /**
1903     * Start listening to reports when the system's default data network is active, meaning it is
1904     * a good time to perform network traffic.  Use {@link #isDefaultNetworkActive()}
1905     * to determine the current state of the system's default network after registering the
1906     * listener.
1907     * <p>
1908     * If the process default network has been set with
1909     * {@link ConnectivityManager#bindProcessToNetwork} this function will not
1910     * reflect the process's default, but the system default.
1911     *
1912     * @param l The listener to be told when the network is active.
1913     */
1914    public void addDefaultNetworkActiveListener(final OnNetworkActiveListener l) {
1915        INetworkActivityListener rl = new INetworkActivityListener.Stub() {
1916            @Override
1917            public void onNetworkActive() throws RemoteException {
1918                l.onNetworkActive();
1919            }
1920        };
1921
1922        try {
1923            getNetworkManagementService().registerNetworkActivityListener(rl);
1924            mNetworkActivityListeners.put(l, rl);
1925        } catch (RemoteException e) {
1926            throw e.rethrowFromSystemServer();
1927        }
1928    }
1929
1930    /**
1931     * Remove network active listener previously registered with
1932     * {@link #addDefaultNetworkActiveListener}.
1933     *
1934     * @param l Previously registered listener.
1935     */
1936    public void removeDefaultNetworkActiveListener(OnNetworkActiveListener l) {
1937        INetworkActivityListener rl = mNetworkActivityListeners.get(l);
1938        Preconditions.checkArgument(rl != null, "Listener was not registered.");
1939        try {
1940            getNetworkManagementService().unregisterNetworkActivityListener(rl);
1941        } catch (RemoteException e) {
1942            throw e.rethrowFromSystemServer();
1943        }
1944    }
1945
1946    /**
1947     * Return whether the data network is currently active.  An active network means that
1948     * it is currently in a high power state for performing data transmission.  On some
1949     * types of networks, it may be expensive to move and stay in such a state, so it is
1950     * more power efficient to batch network traffic together when the radio is already in
1951     * this state.  This method tells you whether right now is currently a good time to
1952     * initiate network traffic, as the network is already active.
1953     */
1954    public boolean isDefaultNetworkActive() {
1955        try {
1956            return getNetworkManagementService().isNetworkActive();
1957        } catch (RemoteException e) {
1958            throw e.rethrowFromSystemServer();
1959        }
1960    }
1961
1962    /**
1963     * {@hide}
1964     */
1965    public ConnectivityManager(Context context, IConnectivityManager service) {
1966        mContext = Preconditions.checkNotNull(context, "missing context");
1967        mService = Preconditions.checkNotNull(service, "missing IConnectivityManager");
1968        sInstance = this;
1969    }
1970
1971    /** {@hide} */
1972    public static ConnectivityManager from(Context context) {
1973        return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
1974    }
1975
1976    /* TODO: These permissions checks don't belong in client-side code. Move them to
1977     * services.jar, possibly in com.android.server.net. */
1978
1979    /** {@hide} */
1980    public static final void enforceChangePermission(Context context) {
1981        int uid = Binder.getCallingUid();
1982        Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings
1983                .getPackageNameForUid(context, uid), true /* throwException */);
1984    }
1985
1986    /** {@hide} */
1987    public static final void enforceTetherChangePermission(Context context, String callingPkg) {
1988        Preconditions.checkNotNull(context, "Context cannot be null");
1989        Preconditions.checkNotNull(callingPkg, "callingPkg cannot be null");
1990
1991        if (context.getResources().getStringArray(
1992                com.android.internal.R.array.config_mobile_hotspot_provision_app).length == 2) {
1993            // Have a provisioning app - must only let system apps (which check this app)
1994            // turn on tethering
1995            context.enforceCallingOrSelfPermission(
1996                    android.Manifest.permission.TETHER_PRIVILEGED, "ConnectivityService");
1997        } else {
1998            int uid = Binder.getCallingUid();
1999            // If callingPkg's uid is not same as Binder.getCallingUid(),
2000            // AppOpsService throws SecurityException.
2001            Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPkg,
2002                    true /* throwException */);
2003        }
2004    }
2005
2006    /**
2007     * @deprecated - use getSystemService. This is a kludge to support static access in certain
2008     *               situations where a Context pointer is unavailable.
2009     * @hide
2010     */
2011    @Deprecated
2012    static ConnectivityManager getInstanceOrNull() {
2013        return sInstance;
2014    }
2015
2016    /**
2017     * @deprecated - use getSystemService. This is a kludge to support static access in certain
2018     *               situations where a Context pointer is unavailable.
2019     * @hide
2020     */
2021    @Deprecated
2022    private static ConnectivityManager getInstance() {
2023        if (getInstanceOrNull() == null) {
2024            throw new IllegalStateException("No ConnectivityManager yet constructed");
2025        }
2026        return getInstanceOrNull();
2027    }
2028
2029    /**
2030     * Get the set of tetherable, available interfaces.  This list is limited by
2031     * device configuration and current interface existence.
2032     *
2033     * @return an array of 0 or more Strings of tetherable interface names.
2034     *
2035     * {@hide}
2036     */
2037    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2038    public String[] getTetherableIfaces() {
2039        try {
2040            return mService.getTetherableIfaces();
2041        } catch (RemoteException e) {
2042            throw e.rethrowFromSystemServer();
2043        }
2044    }
2045
2046    /**
2047     * Get the set of tethered interfaces.
2048     *
2049     * @return an array of 0 or more String of currently tethered interface names.
2050     *
2051     * {@hide}
2052     */
2053    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2054    public String[] getTetheredIfaces() {
2055        try {
2056            return mService.getTetheredIfaces();
2057        } catch (RemoteException e) {
2058            throw e.rethrowFromSystemServer();
2059        }
2060    }
2061
2062    /**
2063     * Get the set of interface names which attempted to tether but
2064     * failed.  Re-attempting to tether may cause them to reset to the Tethered
2065     * state.  Alternatively, causing the interface to be destroyed and recreated
2066     * may cause them to reset to the available state.
2067     * {@link ConnectivityManager#getLastTetherError} can be used to get more
2068     * information on the cause of the errors.
2069     *
2070     * @return an array of 0 or more String indicating the interface names
2071     *        which failed to tether.
2072     *
2073     * {@hide}
2074     */
2075    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2076    public String[] getTetheringErroredIfaces() {
2077        try {
2078            return mService.getTetheringErroredIfaces();
2079        } catch (RemoteException e) {
2080            throw e.rethrowFromSystemServer();
2081        }
2082    }
2083
2084    /**
2085     * Get the set of tethered dhcp ranges.
2086     *
2087     * @return an array of 0 or more {@code String} of tethered dhcp ranges.
2088     * {@hide}
2089     */
2090    public String[] getTetheredDhcpRanges() {
2091        try {
2092            return mService.getTetheredDhcpRanges();
2093        } catch (RemoteException e) {
2094            throw e.rethrowFromSystemServer();
2095        }
2096    }
2097
2098    /**
2099     * Attempt to tether the named interface.  This will setup a dhcp server
2100     * on the interface, forward and NAT IP packets and forward DNS requests
2101     * to the best active upstream network interface.  Note that if no upstream
2102     * IP network interface is available, dhcp will still run and traffic will be
2103     * allowed between the tethered devices and this device, though upstream net
2104     * access will of course fail until an upstream network interface becomes
2105     * active.
2106     *
2107     * <p>This method requires the caller to hold either the
2108     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
2109     * or the ability to modify system settings as determined by
2110     * {@link android.provider.Settings.System#canWrite}.</p>
2111     *
2112     * <p>WARNING: New clients should not use this function. The only usages should be in PanService
2113     * and WifiStateMachine which need direct access. All other clients should use
2114     * {@link #startTethering} and {@link #stopTethering} which encapsulate proper provisioning
2115     * logic.</p>
2116     *
2117     * @param iface the interface name to tether.
2118     * @return error a {@code TETHER_ERROR} value indicating success or failure type
2119     *
2120     * {@hide}
2121     */
2122    public int tether(String iface) {
2123        try {
2124            String pkgName = mContext.getOpPackageName();
2125            Log.i(TAG, "tether caller:" + pkgName);
2126            return mService.tether(iface, pkgName);
2127        } catch (RemoteException e) {
2128            throw e.rethrowFromSystemServer();
2129        }
2130    }
2131
2132    /**
2133     * Stop tethering the named interface.
2134     *
2135     * <p>This method requires the caller to hold either the
2136     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
2137     * or the ability to modify system settings as determined by
2138     * {@link android.provider.Settings.System#canWrite}.</p>
2139     *
2140     * <p>WARNING: New clients should not use this function. The only usages should be in PanService
2141     * and WifiStateMachine which need direct access. All other clients should use
2142     * {@link #startTethering} and {@link #stopTethering} which encapsulate proper provisioning
2143     * logic.</p>
2144     *
2145     * @param iface the interface name to untether.
2146     * @return error a {@code TETHER_ERROR} value indicating success or failure type
2147     *
2148     * {@hide}
2149     */
2150    public int untether(String iface) {
2151        try {
2152            String pkgName = mContext.getOpPackageName();
2153            Log.i(TAG, "untether caller:" + pkgName);
2154            return mService.untether(iface, pkgName);
2155        } catch (RemoteException e) {
2156            throw e.rethrowFromSystemServer();
2157        }
2158    }
2159
2160    /**
2161     * Check if the device allows for tethering.  It may be disabled via
2162     * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
2163     * due to device configuration.
2164     *
2165     * <p>If this app does not have permission to use this API, it will always
2166     * return false rather than throw an exception.</p>
2167     *
2168     * <p>If the device has a hotspot provisioning app, the caller is required to hold the
2169     * {@link android.Manifest.permission.TETHER_PRIVILEGED} permission.</p>
2170     *
2171     * <p>Otherwise, this method requires the caller to hold the ability to modify system
2172     * settings as determined by {@link android.provider.Settings.System#canWrite}.</p>
2173     *
2174     * @return a boolean - {@code true} indicating Tethering is supported.
2175     *
2176     * {@hide}
2177     */
2178    @SystemApi
2179    @RequiresPermission(anyOf = {android.Manifest.permission.TETHER_PRIVILEGED,
2180            android.Manifest.permission.WRITE_SETTINGS})
2181    public boolean isTetheringSupported() {
2182        String pkgName = mContext.getOpPackageName();
2183        try {
2184            return mService.isTetheringSupported(pkgName);
2185        } catch (SecurityException e) {
2186            // This API is not available to this caller, but for backward-compatibility
2187            // this will just return false instead of throwing.
2188            return false;
2189        } catch (RemoteException e) {
2190            throw e.rethrowFromSystemServer();
2191        }
2192    }
2193
2194    /**
2195     * Callback for use with {@link #startTethering} to find out whether tethering succeeded.
2196     * @hide
2197     */
2198    @SystemApi
2199    public static abstract class OnStartTetheringCallback {
2200        /**
2201         * Called when tethering has been successfully started.
2202         */
2203        public void onTetheringStarted() {};
2204
2205        /**
2206         * Called when starting tethering failed.
2207         */
2208        public void onTetheringFailed() {};
2209    }
2210
2211    /**
2212     * Convenient overload for
2213     * {@link #startTethering(int, boolean, OnStartTetheringCallback, Handler)} which passes a null
2214     * handler to run on the current thread's {@link Looper}.
2215     * @hide
2216     */
2217    @SystemApi
2218    @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
2219    public void startTethering(int type, boolean showProvisioningUi,
2220            final OnStartTetheringCallback callback) {
2221        startTethering(type, showProvisioningUi, callback, null);
2222    }
2223
2224    /**
2225     * Runs tether provisioning for the given type if needed and then starts tethering if
2226     * the check succeeds. If no carrier provisioning is required for tethering, tethering is
2227     * enabled immediately. If provisioning fails, tethering will not be enabled. It also
2228     * schedules tether provisioning re-checks if appropriate.
2229     *
2230     * @param type The type of tethering to start. Must be one of
2231     *         {@link ConnectivityManager.TETHERING_WIFI},
2232     *         {@link ConnectivityManager.TETHERING_USB}, or
2233     *         {@link ConnectivityManager.TETHERING_BLUETOOTH}.
2234     * @param showProvisioningUi a boolean indicating to show the provisioning app UI if there
2235     *         is one. This should be true the first time this function is called and also any time
2236     *         the user can see this UI. It gives users information from their carrier about the
2237     *         check failing and how they can sign up for tethering if possible.
2238     * @param callback an {@link OnStartTetheringCallback} which will be called to notify the caller
2239     *         of the result of trying to tether.
2240     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
2241     * @hide
2242     */
2243    @SystemApi
2244    @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
2245    public void startTethering(int type, boolean showProvisioningUi,
2246            final OnStartTetheringCallback callback, Handler handler) {
2247        Preconditions.checkNotNull(callback, "OnStartTetheringCallback cannot be null.");
2248
2249        ResultReceiver wrappedCallback = new ResultReceiver(handler) {
2250            @Override
2251            protected void onReceiveResult(int resultCode, Bundle resultData) {
2252                if (resultCode == TETHER_ERROR_NO_ERROR) {
2253                    callback.onTetheringStarted();
2254                } else {
2255                    callback.onTetheringFailed();
2256                }
2257            }
2258        };
2259
2260        try {
2261            String pkgName = mContext.getOpPackageName();
2262            Log.i(TAG, "startTethering caller:" + pkgName);
2263            mService.startTethering(type, wrappedCallback, showProvisioningUi, pkgName);
2264        } catch (RemoteException e) {
2265            Log.e(TAG, "Exception trying to start tethering.", e);
2266            wrappedCallback.send(TETHER_ERROR_SERVICE_UNAVAIL, null);
2267        }
2268    }
2269
2270    /**
2271     * Stops tethering for the given type. Also cancels any provisioning rechecks for that type if
2272     * applicable.
2273     *
2274     * @param type The type of tethering to stop. Must be one of
2275     *         {@link ConnectivityManager.TETHERING_WIFI},
2276     *         {@link ConnectivityManager.TETHERING_USB}, or
2277     *         {@link ConnectivityManager.TETHERING_BLUETOOTH}.
2278     * @hide
2279     */
2280    @SystemApi
2281    @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
2282    public void stopTethering(int type) {
2283        try {
2284            String pkgName = mContext.getOpPackageName();
2285            Log.i(TAG, "stopTethering caller:" + pkgName);
2286            mService.stopTethering(type, pkgName);
2287        } catch (RemoteException e) {
2288            throw e.rethrowFromSystemServer();
2289        }
2290    }
2291
2292    /**
2293     * Get the list of regular expressions that define any tetherable
2294     * USB network interfaces.  If USB tethering is not supported by the
2295     * device, this list should be empty.
2296     *
2297     * @return an array of 0 or more regular expression Strings defining
2298     *        what interfaces are considered tetherable usb interfaces.
2299     *
2300     * {@hide}
2301     */
2302    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2303    public String[] getTetherableUsbRegexs() {
2304        try {
2305            return mService.getTetherableUsbRegexs();
2306        } catch (RemoteException e) {
2307            throw e.rethrowFromSystemServer();
2308        }
2309    }
2310
2311    /**
2312     * Get the list of regular expressions that define any tetherable
2313     * Wifi network interfaces.  If Wifi tethering is not supported by the
2314     * device, this list should be empty.
2315     *
2316     * @return an array of 0 or more regular expression Strings defining
2317     *        what interfaces are considered tetherable wifi interfaces.
2318     *
2319     * {@hide}
2320     */
2321    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2322    public String[] getTetherableWifiRegexs() {
2323        try {
2324            return mService.getTetherableWifiRegexs();
2325        } catch (RemoteException e) {
2326            throw e.rethrowFromSystemServer();
2327        }
2328    }
2329
2330    /**
2331     * Get the list of regular expressions that define any tetherable
2332     * Bluetooth network interfaces.  If Bluetooth tethering is not supported by the
2333     * device, this list should be empty.
2334     *
2335     * @return an array of 0 or more regular expression Strings defining
2336     *        what interfaces are considered tetherable bluetooth interfaces.
2337     *
2338     * {@hide}
2339     */
2340    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2341    public String[] getTetherableBluetoothRegexs() {
2342        try {
2343            return mService.getTetherableBluetoothRegexs();
2344        } catch (RemoteException e) {
2345            throw e.rethrowFromSystemServer();
2346        }
2347    }
2348
2349    /**
2350     * Attempt to both alter the mode of USB and Tethering of USB.  A
2351     * utility method to deal with some of the complexity of USB - will
2352     * attempt to switch to Rndis and subsequently tether the resulting
2353     * interface on {@code true} or turn off tethering and switch off
2354     * Rndis on {@code false}.
2355     *
2356     * <p>This method requires the caller to hold either the
2357     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
2358     * or the ability to modify system settings as determined by
2359     * {@link android.provider.Settings.System#canWrite}.</p>
2360     *
2361     * @param enable a boolean - {@code true} to enable tethering
2362     * @return error a {@code TETHER_ERROR} value indicating success or failure type
2363     *
2364     * {@hide}
2365     */
2366    public int setUsbTethering(boolean enable) {
2367        try {
2368            String pkgName = mContext.getOpPackageName();
2369            Log.i(TAG, "setUsbTethering caller:" + pkgName);
2370            return mService.setUsbTethering(enable, pkgName);
2371        } catch (RemoteException e) {
2372            throw e.rethrowFromSystemServer();
2373        }
2374    }
2375
2376    /** {@hide} */
2377    public static final int TETHER_ERROR_NO_ERROR           = 0;
2378    /** {@hide} */
2379    public static final int TETHER_ERROR_UNKNOWN_IFACE      = 1;
2380    /** {@hide} */
2381    public static final int TETHER_ERROR_SERVICE_UNAVAIL    = 2;
2382    /** {@hide} */
2383    public static final int TETHER_ERROR_UNSUPPORTED        = 3;
2384    /** {@hide} */
2385    public static final int TETHER_ERROR_UNAVAIL_IFACE      = 4;
2386    /** {@hide} */
2387    public static final int TETHER_ERROR_MASTER_ERROR       = 5;
2388    /** {@hide} */
2389    public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
2390    /** {@hide} */
2391    public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
2392    /** {@hide} */
2393    public static final int TETHER_ERROR_ENABLE_NAT_ERROR     = 8;
2394    /** {@hide} */
2395    public static final int TETHER_ERROR_DISABLE_NAT_ERROR    = 9;
2396    /** {@hide} */
2397    public static final int TETHER_ERROR_IFACE_CFG_ERROR      = 10;
2398    /** {@hide} */
2399    public static final int TETHER_ERROR_PROVISION_FAILED     = 11;
2400
2401    /**
2402     * Get a more detailed error code after a Tethering or Untethering
2403     * request asynchronously failed.
2404     *
2405     * @param iface The name of the interface of interest
2406     * @return error The error code of the last error tethering or untethering the named
2407     *               interface
2408     *
2409     * {@hide}
2410     */
2411    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2412    public int getLastTetherError(String iface) {
2413        try {
2414            return mService.getLastTetherError(iface);
2415        } catch (RemoteException e) {
2416            throw e.rethrowFromSystemServer();
2417        }
2418    }
2419
2420    /**
2421     * Report network connectivity status.  This is currently used only
2422     * to alter status bar UI.
2423     * <p>This method requires the caller to hold the permission
2424     * {@link android.Manifest.permission#STATUS_BAR}.
2425     *
2426     * @param networkType The type of network you want to report on
2427     * @param percentage The quality of the connection 0 is bad, 100 is good
2428     * @deprecated Types are deprecated. Use {@link #reportNetworkConnectivity} instead.
2429     * {@hide}
2430     */
2431    public void reportInetCondition(int networkType, int percentage) {
2432        try {
2433            mService.reportInetCondition(networkType, percentage);
2434        } catch (RemoteException e) {
2435            throw e.rethrowFromSystemServer();
2436        }
2437    }
2438
2439    /**
2440     * Report a problem network to the framework.  This provides a hint to the system
2441     * that there might be connectivity problems on this network and may cause
2442     * the framework to re-evaluate network connectivity and/or switch to another
2443     * network.
2444     *
2445     * @param network The {@link Network} the application was attempting to use
2446     *                or {@code null} to indicate the current default network.
2447     * @deprecated Use {@link #reportNetworkConnectivity} which allows reporting both
2448     *             working and non-working connectivity.
2449     */
2450    @Deprecated
2451    public void reportBadNetwork(Network network) {
2452        try {
2453            // One of these will be ignored because it matches system's current state.
2454            // The other will trigger the necessary reevaluation.
2455            mService.reportNetworkConnectivity(network, true);
2456            mService.reportNetworkConnectivity(network, false);
2457        } catch (RemoteException e) {
2458            throw e.rethrowFromSystemServer();
2459        }
2460    }
2461
2462    /**
2463     * Report to the framework whether a network has working connectivity.
2464     * This provides a hint to the system that a particular network is providing
2465     * working connectivity or not.  In response the framework may re-evaluate
2466     * the network's connectivity and might take further action thereafter.
2467     *
2468     * @param network The {@link Network} the application was attempting to use
2469     *                or {@code null} to indicate the current default network.
2470     * @param hasConnectivity {@code true} if the application was able to successfully access the
2471     *                        Internet using {@code network} or {@code false} if not.
2472     */
2473    public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
2474        try {
2475            mService.reportNetworkConnectivity(network, hasConnectivity);
2476        } catch (RemoteException e) {
2477            throw e.rethrowFromSystemServer();
2478        }
2479    }
2480
2481    /**
2482     * Set a network-independent global http proxy.  This is not normally what you want
2483     * for typical HTTP proxies - they are general network dependent.  However if you're
2484     * doing something unusual like general internal filtering this may be useful.  On
2485     * a private network where the proxy is not accessible, you may break HTTP using this.
2486     *
2487     * @param p A {@link ProxyInfo} object defining the new global
2488     *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
2489     * @hide
2490     */
2491    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
2492    public void setGlobalProxy(ProxyInfo p) {
2493        try {
2494            mService.setGlobalProxy(p);
2495        } catch (RemoteException e) {
2496            throw e.rethrowFromSystemServer();
2497        }
2498    }
2499
2500    /**
2501     * Retrieve any network-independent global HTTP proxy.
2502     *
2503     * @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
2504     *        if no global HTTP proxy is set.
2505     * @hide
2506     */
2507    public ProxyInfo getGlobalProxy() {
2508        try {
2509            return mService.getGlobalProxy();
2510        } catch (RemoteException e) {
2511            throw e.rethrowFromSystemServer();
2512        }
2513    }
2514
2515    /**
2516     * Retrieve the global HTTP proxy, or if no global HTTP proxy is set, a
2517     * network-specific HTTP proxy.  If {@code network} is null, the
2518     * network-specific proxy returned is the proxy of the default active
2519     * network.
2520     *
2521     * @return {@link ProxyInfo} for the current global HTTP proxy, or if no
2522     *         global HTTP proxy is set, {@code ProxyInfo} for {@code network},
2523     *         or when {@code network} is {@code null},
2524     *         the {@code ProxyInfo} for the default active network.  Returns
2525     *         {@code null} when no proxy applies or the caller doesn't have
2526     *         permission to use {@code network}.
2527     * @hide
2528     */
2529    public ProxyInfo getProxyForNetwork(Network network) {
2530        try {
2531            return mService.getProxyForNetwork(network);
2532        } catch (RemoteException e) {
2533            throw e.rethrowFromSystemServer();
2534        }
2535    }
2536
2537    /**
2538     * Get the current default HTTP proxy settings.  If a global proxy is set it will be returned,
2539     * otherwise if this process is bound to a {@link Network} using
2540     * {@link #bindProcessToNetwork} then that {@code Network}'s proxy is returned, otherwise
2541     * the default network's proxy is returned.
2542     *
2543     * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no
2544     *        HTTP proxy is active.
2545     */
2546    public ProxyInfo getDefaultProxy() {
2547        return getProxyForNetwork(getBoundNetworkForProcess());
2548    }
2549
2550    /**
2551     * Returns true if the hardware supports the given network type
2552     * else it returns false.  This doesn't indicate we have coverage
2553     * or are authorized onto a network, just whether or not the
2554     * hardware supports it.  For example a GSM phone without a SIM
2555     * should still return {@code true} for mobile data, but a wifi only
2556     * tablet would return {@code false}.
2557     *
2558     * @param networkType The network type we'd like to check
2559     * @return {@code true} if supported, else {@code false}
2560     * @deprecated Types are deprecated. Use {@link NetworkCapabilities} instead.
2561     * @hide
2562     */
2563    @Deprecated
2564    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2565    public boolean isNetworkSupported(int networkType) {
2566        try {
2567            return mService.isNetworkSupported(networkType);
2568        } catch (RemoteException e) {
2569            throw e.rethrowFromSystemServer();
2570        }
2571    }
2572
2573    /**
2574     * Returns if the currently active data network is metered. A network is
2575     * classified as metered when the user is sensitive to heavy data usage on
2576     * that connection due to monetary costs, data limitations or
2577     * battery/performance issues. You should check this before doing large
2578     * data transfers, and warn the user or delay the operation until another
2579     * network is available.
2580     *
2581     * @return {@code true} if large transfers should be avoided, otherwise
2582     *        {@code false}.
2583     */
2584    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2585    public boolean isActiveNetworkMetered() {
2586        try {
2587            return mService.isActiveNetworkMetered();
2588        } catch (RemoteException e) {
2589            throw e.rethrowFromSystemServer();
2590        }
2591    }
2592
2593    /**
2594     * If the LockdownVpn mechanism is enabled, updates the vpn
2595     * with a reload of its profile.
2596     *
2597     * @return a boolean with {@code} indicating success
2598     *
2599     * <p>This method can only be called by the system UID
2600     * {@hide}
2601     */
2602    public boolean updateLockdownVpn() {
2603        try {
2604            return mService.updateLockdownVpn();
2605        } catch (RemoteException e) {
2606            throw e.rethrowFromSystemServer();
2607        }
2608    }
2609
2610    /**
2611     * Check mobile provisioning.
2612     *
2613     * @param suggestedTimeOutMs, timeout in milliseconds
2614     *
2615     * @return time out that will be used, maybe less that suggestedTimeOutMs
2616     * -1 if an error.
2617     *
2618     * {@hide}
2619     */
2620    public int checkMobileProvisioning(int suggestedTimeOutMs) {
2621        int timeOutMs = -1;
2622        try {
2623            timeOutMs = mService.checkMobileProvisioning(suggestedTimeOutMs);
2624        } catch (RemoteException e) {
2625            throw e.rethrowFromSystemServer();
2626        }
2627        return timeOutMs;
2628    }
2629
2630    /**
2631     * Get the mobile provisioning url.
2632     * {@hide}
2633     */
2634    public String getMobileProvisioningUrl() {
2635        try {
2636            return mService.getMobileProvisioningUrl();
2637        } catch (RemoteException e) {
2638            throw e.rethrowFromSystemServer();
2639        }
2640    }
2641
2642    /**
2643     * Set sign in error notification to visible or in visible
2644     *
2645     * @param visible
2646     * @param networkType
2647     *
2648     * {@hide}
2649     * @deprecated Doesn't properly deal with multiple connected networks of the same type.
2650     */
2651    @Deprecated
2652    public void setProvisioningNotificationVisible(boolean visible, int networkType,
2653            String action) {
2654        try {
2655            mService.setProvisioningNotificationVisible(visible, networkType, action);
2656        } catch (RemoteException e) {
2657            throw e.rethrowFromSystemServer();
2658        }
2659    }
2660
2661    /**
2662     * Set the value for enabling/disabling airplane mode
2663     *
2664     * @param enable whether to enable airplane mode or not
2665     *
2666     * @hide
2667     */
2668    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
2669    public void setAirplaneMode(boolean enable) {
2670        try {
2671            mService.setAirplaneMode(enable);
2672        } catch (RemoteException e) {
2673            throw e.rethrowFromSystemServer();
2674        }
2675    }
2676
2677    /** {@hide} */
2678    public void registerNetworkFactory(Messenger messenger, String name) {
2679        try {
2680            mService.registerNetworkFactory(messenger, name);
2681        } catch (RemoteException e) {
2682            throw e.rethrowFromSystemServer();
2683        }
2684    }
2685
2686    /** {@hide} */
2687    public void unregisterNetworkFactory(Messenger messenger) {
2688        try {
2689            mService.unregisterNetworkFactory(messenger);
2690        } catch (RemoteException e) {
2691            throw e.rethrowFromSystemServer();
2692        }
2693    }
2694
2695    /**
2696     * @hide
2697     * Register a NetworkAgent with ConnectivityService.
2698     * @return NetID corresponding to NetworkAgent.
2699     */
2700    public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
2701            NetworkCapabilities nc, int score, NetworkMisc misc) {
2702        try {
2703            return mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc);
2704        } catch (RemoteException e) {
2705            throw e.rethrowFromSystemServer();
2706        }
2707    }
2708
2709    /**
2710     * Base class for {@code NetworkRequest} callbacks. Used for notifications about network
2711     * changes. Should be extended by applications wanting notifications.
2712     *
2713     * A {@code NetworkCallback} is registered by calling
2714     * {@link #requestNetwork(NetworkRequest, NetworkCallback)},
2715     * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)},
2716     * or {@link #registerDefaultNetworkCallback(NetworkCallback)}. A {@code NetworkCallback} is
2717     * unregistered by calling {@link #unregisterNetworkCallback(NetworkCallback)}.
2718     * A {@code NetworkCallback} should be registered at most once at any time.
2719     * A {@code NetworkCallback} that has been unregistered can be registered again.
2720     */
2721    public static class NetworkCallback {
2722        /**
2723         * Called when the framework connects to a new network to evaluate whether it satisfies this
2724         * request. If evaluation succeeds, this callback may be followed by an {@link #onAvailable}
2725         * callback. There is no guarantee that this new network will satisfy any requests, or that
2726         * the network will stay connected for longer than the time necessary to evaluate it.
2727         * <p>
2728         * Most applications <b>should not</b> act on this callback, and should instead use
2729         * {@link #onAvailable}. This callback is intended for use by applications that can assist
2730         * the framework in properly evaluating the network &mdash; for example, an application that
2731         * can automatically log in to a captive portal without user intervention.
2732         *
2733         * @param network The {@link Network} of the network that is being evaluated.
2734         *
2735         * @hide
2736         */
2737        public void onPreCheck(Network network) {}
2738
2739        /**
2740         * Called when the framework connects and has declared a new network ready for use.
2741         * This callback may be called more than once if the {@link Network} that is
2742         * satisfying the request changes.
2743         *
2744         * @param network The {@link Network} of the satisfying network.
2745         * @param networkCapabilities The {@link NetworkCapabilities} of the satisfying network.
2746         * @param linkProperties The {@link LinkProperties} of the satisfying network.
2747         * @hide
2748         */
2749        public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
2750                LinkProperties linkProperties) {
2751            // Internally only this method is called when a new network is available, and
2752            // it calls the callback in the same way and order that older versions used
2753            // to call so as not to change the behavior.
2754            onAvailable(network);
2755            if (!networkCapabilities.hasCapability(
2756                    NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)) {
2757                onNetworkSuspended(network);
2758            }
2759            onCapabilitiesChanged(network, networkCapabilities);
2760            onLinkPropertiesChanged(network, linkProperties);
2761        }
2762
2763        /**
2764         * Called when the framework connects and has declared a new network ready for use.
2765         * This callback may be called more than once if the {@link Network} that is
2766         * satisfying the request changes. This will always immediately be followed by a
2767         * call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} then by a
2768         * call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}.
2769         *
2770         * @param network The {@link Network} of the satisfying network.
2771         */
2772        public void onAvailable(Network network) {}
2773
2774        /**
2775         * Called when the network is about to be disconnected.  Often paired with an
2776         * {@link NetworkCallback#onAvailable} call with the new replacement network
2777         * for graceful handover.  This may not be called if we have a hard loss
2778         * (loss without warning).  This may be followed by either a
2779         * {@link NetworkCallback#onLost} call or a
2780         * {@link NetworkCallback#onAvailable} call for this network depending
2781         * on whether we lose or regain it.
2782         *
2783         * @param network The {@link Network} that is about to be disconnected.
2784         * @param maxMsToLive The time in ms the framework will attempt to keep the
2785         *                     network connected.  Note that the network may suffer a
2786         *                     hard loss at any time.
2787         */
2788        public void onLosing(Network network, int maxMsToLive) {}
2789
2790        /**
2791         * Called when the framework has a hard loss of the network or when the
2792         * graceful failure ends.
2793         *
2794         * @param network The {@link Network} lost.
2795         */
2796        public void onLost(Network network) {}
2797
2798        /**
2799         * Called if no network is found in the timeout time specified in
2800         * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)} call. This callback is not
2801         * called for the version of {@link #requestNetwork(NetworkRequest, NetworkCallback)}
2802         * without timeout. When this callback is invoked the associated
2803         * {@link NetworkRequest} will have already been removed and released, as if
2804         * {@link #unregisterNetworkCallback(NetworkCallback)} had been called.
2805         */
2806        public void onUnavailable() {}
2807
2808        /**
2809         * Called when the network the framework connected to for this request
2810         * changes capabilities but still satisfies the stated need.
2811         *
2812         * @param network The {@link Network} whose capabilities have changed.
2813         * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this
2814         *                            network.
2815         */
2816        public void onCapabilitiesChanged(Network network,
2817                NetworkCapabilities networkCapabilities) {}
2818
2819        /**
2820         * Called when the network the framework connected to for this request
2821         * changes {@link LinkProperties}.
2822         *
2823         * @param network The {@link Network} whose link properties have changed.
2824         * @param linkProperties The new {@link LinkProperties} for this network.
2825         */
2826        public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {}
2827
2828        /**
2829         * Called when the network the framework connected to for this request
2830         * goes into {@link NetworkInfo.State#SUSPENDED}.
2831         * This generally means that while the TCP connections are still live,
2832         * temporarily network data fails to transfer.  Specifically this is used
2833         * on cellular networks to mask temporary outages when driving through
2834         * a tunnel, etc.
2835         * @hide
2836         */
2837        public void onNetworkSuspended(Network network) {}
2838
2839        /**
2840         * Called when the network the framework connected to for this request
2841         * returns from a {@link NetworkInfo.State#SUSPENDED} state. This should always be
2842         * preceded by a matching {@link NetworkCallback#onNetworkSuspended} call.
2843         * @hide
2844         */
2845        public void onNetworkResumed(Network network) {}
2846
2847        private NetworkRequest networkRequest;
2848    }
2849
2850    /**
2851     * Constant error codes used by ConnectivityService to communicate about failures and errors
2852     * across a Binder boundary.
2853     * @hide
2854     */
2855    public interface Errors {
2856        static int TOO_MANY_REQUESTS = 1;
2857    }
2858
2859    /** @hide */
2860    public static class TooManyRequestsException extends RuntimeException {}
2861
2862    private static RuntimeException convertServiceException(ServiceSpecificException e) {
2863        switch (e.errorCode) {
2864            case Errors.TOO_MANY_REQUESTS:
2865                return new TooManyRequestsException();
2866            default:
2867                Log.w(TAG, "Unknown service error code " + e.errorCode);
2868                return new RuntimeException(e);
2869        }
2870    }
2871
2872    private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER;
2873    /** @hide */
2874    public static final int CALLBACK_PRECHECK            = BASE + 1;
2875    /** @hide */
2876    public static final int CALLBACK_AVAILABLE           = BASE + 2;
2877    /** @hide arg1 = TTL */
2878    public static final int CALLBACK_LOSING              = BASE + 3;
2879    /** @hide */
2880    public static final int CALLBACK_LOST                = BASE + 4;
2881    /** @hide */
2882    public static final int CALLBACK_UNAVAIL             = BASE + 5;
2883    /** @hide */
2884    public static final int CALLBACK_CAP_CHANGED         = BASE + 6;
2885    /** @hide */
2886    public static final int CALLBACK_IP_CHANGED          = BASE + 7;
2887    /** @hide obj = NetworkCapabilities, arg1 = seq number */
2888    private static final int EXPIRE_LEGACY_REQUEST       = BASE + 8;
2889    /** @hide */
2890    public static final int CALLBACK_SUSPENDED           = BASE + 9;
2891    /** @hide */
2892    public static final int CALLBACK_RESUMED             = BASE + 10;
2893
2894    /** @hide */
2895    public static String getCallbackName(int whichCallback) {
2896        switch (whichCallback) {
2897            case CALLBACK_PRECHECK:     return "CALLBACK_PRECHECK";
2898            case CALLBACK_AVAILABLE:    return "CALLBACK_AVAILABLE";
2899            case CALLBACK_LOSING:       return "CALLBACK_LOSING";
2900            case CALLBACK_LOST:         return "CALLBACK_LOST";
2901            case CALLBACK_UNAVAIL:      return "CALLBACK_UNAVAIL";
2902            case CALLBACK_CAP_CHANGED:  return "CALLBACK_CAP_CHANGED";
2903            case CALLBACK_IP_CHANGED:   return "CALLBACK_IP_CHANGED";
2904            case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST";
2905            case CALLBACK_SUSPENDED:    return "CALLBACK_SUSPENDED";
2906            case CALLBACK_RESUMED:      return "CALLBACK_RESUMED";
2907            default:
2908                return Integer.toString(whichCallback);
2909        }
2910    }
2911
2912    private class CallbackHandler extends Handler {
2913        private static final String TAG = "ConnectivityManager.CallbackHandler";
2914        private static final boolean DBG = false;
2915
2916        CallbackHandler(Looper looper) {
2917            super(looper);
2918        }
2919
2920        CallbackHandler(Handler handler) {
2921            this(Preconditions.checkNotNull(handler, "Handler cannot be null.").getLooper());
2922        }
2923
2924        @Override
2925        public void handleMessage(Message message) {
2926            if (message.what == EXPIRE_LEGACY_REQUEST) {
2927                expireRequest((NetworkCapabilities) message.obj, message.arg1);
2928                return;
2929            }
2930
2931            final NetworkRequest request = getObject(message, NetworkRequest.class);
2932            final Network network = getObject(message, Network.class);
2933            final NetworkCallback callback;
2934            synchronized (sCallbacks) {
2935                callback = sCallbacks.get(request);
2936            }
2937            if (DBG) {
2938                Log.d(TAG, getCallbackName(message.what) + " for network " + network);
2939            }
2940            if (callback == null) {
2941                Log.w(TAG, "callback not found for " + getCallbackName(message.what) + " message");
2942                return;
2943            }
2944
2945            switch (message.what) {
2946                case CALLBACK_PRECHECK: {
2947                    callback.onPreCheck(network);
2948                    break;
2949                }
2950                case CALLBACK_AVAILABLE: {
2951                    NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
2952                    LinkProperties lp = getObject(message, LinkProperties.class);
2953                    callback.onAvailable(network, cap, lp);
2954                    break;
2955                }
2956                case CALLBACK_LOSING: {
2957                    callback.onLosing(network, message.arg1);
2958                    break;
2959                }
2960                case CALLBACK_LOST: {
2961                    callback.onLost(network);
2962                    break;
2963                }
2964                case CALLBACK_UNAVAIL: {
2965                    callback.onUnavailable();
2966                    break;
2967                }
2968                case CALLBACK_CAP_CHANGED: {
2969                    NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
2970                    callback.onCapabilitiesChanged(network, cap);
2971                    break;
2972                }
2973                case CALLBACK_IP_CHANGED: {
2974                    LinkProperties lp = getObject(message, LinkProperties.class);
2975                    callback.onLinkPropertiesChanged(network, lp);
2976                    break;
2977                }
2978                case CALLBACK_SUSPENDED: {
2979                    callback.onNetworkSuspended(network);
2980                    break;
2981                }
2982                case CALLBACK_RESUMED: {
2983                    callback.onNetworkResumed(network);
2984                    break;
2985                }
2986            }
2987        }
2988
2989        private <T> T getObject(Message msg, Class<T> c) {
2990            return (T) msg.getData().getParcelable(c.getSimpleName());
2991        }
2992    }
2993
2994    private CallbackHandler getDefaultHandler() {
2995        synchronized (sCallbacks) {
2996            if (sCallbackHandler == null) {
2997                sCallbackHandler = new CallbackHandler(ConnectivityThread.getInstanceLooper());
2998            }
2999            return sCallbackHandler;
3000        }
3001    }
3002
3003    private static final HashMap<NetworkRequest, NetworkCallback> sCallbacks = new HashMap<>();
3004    private static CallbackHandler sCallbackHandler;
3005
3006    private static final int LISTEN  = 1;
3007    private static final int REQUEST = 2;
3008
3009    private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, NetworkCallback callback,
3010            int timeoutMs, int action, int legacyType, CallbackHandler handler) {
3011        checkCallbackNotNull(callback);
3012        Preconditions.checkArgument(action == REQUEST || need != null, "null NetworkCapabilities");
3013        final NetworkRequest request;
3014        try {
3015            synchronized(sCallbacks) {
3016                if (callback.networkRequest != null
3017                        && callback.networkRequest != ALREADY_UNREGISTERED) {
3018                    // TODO: throw exception instead and enforce 1:1 mapping of callbacks
3019                    // and requests (http://b/20701525).
3020                    Log.e(TAG, "NetworkCallback was already registered");
3021                }
3022                Messenger messenger = new Messenger(handler);
3023                Binder binder = new Binder();
3024                if (action == LISTEN) {
3025                    request = mService.listenForNetwork(need, messenger, binder);
3026                } else {
3027                    request = mService.requestNetwork(
3028                            need, messenger, timeoutMs, binder, legacyType);
3029                }
3030                if (request != null) {
3031                    sCallbacks.put(request, callback);
3032                }
3033                callback.networkRequest = request;
3034            }
3035        } catch (RemoteException e) {
3036            throw e.rethrowFromSystemServer();
3037        } catch (ServiceSpecificException e) {
3038            throw convertServiceException(e);
3039        }
3040        return request;
3041    }
3042
3043    /**
3044     * Helper function to request a network with a particular legacy type.
3045     *
3046     * This is temporarily public @hide so it can be called by system code that uses the
3047     * NetworkRequest API to request networks but relies on CONNECTIVITY_ACTION broadcasts for
3048     * instead network notifications.
3049     *
3050     * TODO: update said system code to rely on NetworkCallbacks and make this method private.
3051     *
3052     * @hide
3053     */
3054    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
3055            int timeoutMs, int legacyType, Handler handler) {
3056        CallbackHandler cbHandler = new CallbackHandler(handler);
3057        NetworkCapabilities nc = request.networkCapabilities;
3058        sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, legacyType, cbHandler);
3059    }
3060
3061    /**
3062     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
3063     *
3064     * This {@link NetworkRequest} will live until released via
3065     * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits. A
3066     * version of the method which takes a timeout is
3067     * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)}.
3068     * Status of the request can be followed by listening to the various
3069     * callbacks described in {@link NetworkCallback}.  The {@link Network}
3070     * can be used to direct traffic to the network.
3071     * <p>It is presently unsupported to request a network with mutable
3072     * {@link NetworkCapabilities} such as
3073     * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
3074     * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
3075     * as these {@code NetworkCapabilities} represent states that a particular
3076     * network may never attain, and whether a network will attain these states
3077     * is unknown prior to bringing up the network so the framework does not
3078     * know how to go about satisfing a request with these capabilities.
3079     *
3080     * <p>This method requires the caller to hold either the
3081     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
3082     * or the ability to modify system settings as determined by
3083     * {@link android.provider.Settings.System#canWrite}.</p>
3084     *
3085     * @param request {@link NetworkRequest} describing this request.
3086     * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
3087     *                        the callback must not be shared - it uniquely specifies this request.
3088     *                        The callback is invoked on the default internal Handler.
3089     * @throws IllegalArgumentException if {@code request} specifies any mutable
3090     *         {@code NetworkCapabilities}.
3091     */
3092    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) {
3093        requestNetwork(request, networkCallback, getDefaultHandler());
3094    }
3095
3096    /**
3097     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
3098     *
3099     * This {@link NetworkRequest} will live until released via
3100     * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits. A
3101     * version of the method which takes a timeout is
3102     * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)}.
3103     * Status of the request can be followed by listening to the various
3104     * callbacks described in {@link NetworkCallback}.  The {@link Network}
3105     * can be used to direct traffic to the network.
3106     * <p>It is presently unsupported to request a network with mutable
3107     * {@link NetworkCapabilities} such as
3108     * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
3109     * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
3110     * as these {@code NetworkCapabilities} represent states that a particular
3111     * network may never attain, and whether a network will attain these states
3112     * is unknown prior to bringing up the network so the framework does not
3113     * know how to go about satisfing a request with these capabilities.
3114     *
3115     * <p>This method requires the caller to hold either the
3116     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
3117     * or the ability to modify system settings as determined by
3118     * {@link android.provider.Settings.System#canWrite}.</p>
3119     *
3120     * @param request {@link NetworkRequest} describing this request.
3121     * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
3122     *                        the callback must not be shared - it uniquely specifies this request.
3123     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
3124     * @throws IllegalArgumentException if {@code request} specifies any mutable
3125     *         {@code NetworkCapabilities}.
3126     */
3127    public void requestNetwork(
3128            NetworkRequest request, NetworkCallback networkCallback, Handler handler) {
3129        int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
3130        CallbackHandler cbHandler = new CallbackHandler(handler);
3131        requestNetwork(request, networkCallback, 0, legacyType, cbHandler);
3132    }
3133
3134    /**
3135     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
3136     * by a timeout.
3137     *
3138     * This function behaves identically to the non-timed-out version
3139     * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, but if a suitable network
3140     * is not found within the given time (in milliseconds) the
3141     * {@link NetworkCallback#onUnavailable()} callback is called. The request can still be
3142     * released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)} but does
3143     * not have to be released if timed-out (it is automatically released). Unregistering a
3144     * request that timed out is not an error.
3145     *
3146     * <p>Do not use this method to poll for the existence of specific networks (e.g. with a small
3147     * timeout) - {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} is provided
3148     * for that purpose. Calling this method will attempt to bring up the requested network.
3149     *
3150     * <p>This method requires the caller to hold either the
3151     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
3152     * or the ability to modify system settings as determined by
3153     * {@link android.provider.Settings.System#canWrite}.</p>
3154     *
3155     * @param request {@link NetworkRequest} describing this request.
3156     * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
3157     *                        the callback must not be shared - it uniquely specifies this request.
3158     * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
3159     *                  before {@link NetworkCallback#onUnavailable()} is called. The timeout must
3160     *                  be a positive value (i.e. >0).
3161     */
3162    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
3163            int timeoutMs) {
3164        checkTimeout(timeoutMs);
3165        int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
3166        requestNetwork(request, networkCallback, timeoutMs, legacyType, getDefaultHandler());
3167    }
3168
3169    /**
3170     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
3171     * by a timeout.
3172     *
3173     * This function behaves identically to the non-timedout version, but if a suitable
3174     * network is not found within the given time (in milliseconds) the
3175     * {@link NetworkCallback#onUnavailable} callback is called. The request can still be
3176     * released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)} but does
3177     * not have to be released if timed-out (it is automatically released). Unregistering a
3178     * request that timed out is not an error.
3179     *
3180     * <p>Do not use this method to poll for the existence of specific networks (e.g. with a small
3181     * timeout) - {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} is provided
3182     * for that purpose. Calling this method will attempt to bring up the requested network.
3183     *
3184     * <p>This method requires the caller to hold either the
3185     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
3186     * or the ability to modify system settings as determined by
3187     * {@link android.provider.Settings.System#canWrite}.</p>
3188     *
3189     * @param request {@link NetworkRequest} describing this request.
3190     * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
3191     *                        the callback must not be shared - it uniquely specifies this request.
3192     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
3193     * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
3194     *                  before {@link NetworkCallback#onUnavailable} is called.
3195     */
3196    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
3197            Handler handler, int timeoutMs) {
3198        checkTimeout(timeoutMs);
3199        int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
3200        CallbackHandler cbHandler = new CallbackHandler(handler);
3201        requestNetwork(request, networkCallback, timeoutMs, legacyType, cbHandler);
3202    }
3203
3204    /**
3205     * The lookup key for a {@link Network} object included with the intent after
3206     * successfully finding a network for the applications request.  Retrieve it with
3207     * {@link android.content.Intent#getParcelableExtra(String)}.
3208     * <p>
3209     * Note that if you intend to invoke {@link Network#openConnection(java.net.URL)}
3210     * then you must get a ConnectivityManager instance before doing so.
3211     */
3212    public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
3213
3214    /**
3215     * The lookup key for a {@link NetworkRequest} object included with the intent after
3216     * successfully finding a network for the applications request.  Retrieve it with
3217     * {@link android.content.Intent#getParcelableExtra(String)}.
3218     */
3219    public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
3220
3221
3222    /**
3223     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
3224     *
3225     * This function behaves identically to the version that takes a NetworkCallback, but instead
3226     * of {@link NetworkCallback} a {@link PendingIntent} is used.  This means
3227     * the request may outlive the calling application and get called back when a suitable
3228     * network is found.
3229     * <p>
3230     * The operation is an Intent broadcast that goes to a broadcast receiver that
3231     * you registered with {@link Context#registerReceiver} or through the
3232     * &lt;receiver&gt; tag in an AndroidManifest.xml file
3233     * <p>
3234     * The operation Intent is delivered with two extras, a {@link Network} typed
3235     * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest}
3236     * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing
3237     * the original requests parameters.  It is important to create a new,
3238     * {@link NetworkCallback} based request before completing the processing of the
3239     * Intent to reserve the network or it will be released shortly after the Intent
3240     * is processed.
3241     * <p>
3242     * If there is already a request for this Intent registered (with the equality of
3243     * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
3244     * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
3245     * <p>
3246     * The request may be released normally by calling
3247     * {@link #releaseNetworkRequest(android.app.PendingIntent)}.
3248     * <p>It is presently unsupported to request a network with either
3249     * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
3250     * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
3251     * as these {@code NetworkCapabilities} represent states that a particular
3252     * network may never attain, and whether a network will attain these states
3253     * is unknown prior to bringing up the network so the framework does not
3254     * know how to go about satisfing a request with these capabilities.
3255     *
3256     * <p>This method requires the caller to hold either the
3257     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
3258     * or the ability to modify system settings as determined by
3259     * {@link android.provider.Settings.System#canWrite}.</p>
3260     *
3261     * @param request {@link NetworkRequest} describing this request.
3262     * @param operation Action to perform when the network is available (corresponds
3263     *                  to the {@link NetworkCallback#onAvailable} call.  Typically
3264     *                  comes from {@link PendingIntent#getBroadcast}. Cannot be null.
3265     * @throws IllegalArgumentException if {@code request} contains either
3266     *         {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
3267     *         {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}.
3268     */
3269    public void requestNetwork(NetworkRequest request, PendingIntent operation) {
3270        checkPendingIntentNotNull(operation);
3271        try {
3272            mService.pendingRequestForNetwork(request.networkCapabilities, operation);
3273        } catch (RemoteException e) {
3274            throw e.rethrowFromSystemServer();
3275        } catch (ServiceSpecificException e) {
3276            throw convertServiceException(e);
3277        }
3278    }
3279
3280    /**
3281     * Removes a request made via {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)}
3282     * <p>
3283     * This method has the same behavior as
3284     * {@link #unregisterNetworkCallback(android.app.PendingIntent)} with respect to
3285     * releasing network resources and disconnecting.
3286     *
3287     * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the
3288     *                  PendingIntent passed to
3289     *                  {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)} with the
3290     *                  corresponding NetworkRequest you'd like to remove. Cannot be null.
3291     */
3292    public void releaseNetworkRequest(PendingIntent operation) {
3293        checkPendingIntentNotNull(operation);
3294        try {
3295            mService.releasePendingNetworkRequest(operation);
3296        } catch (RemoteException e) {
3297            throw e.rethrowFromSystemServer();
3298        }
3299    }
3300
3301    private static void checkPendingIntentNotNull(PendingIntent intent) {
3302        Preconditions.checkNotNull(intent, "PendingIntent cannot be null.");
3303    }
3304
3305    private static void checkCallbackNotNull(NetworkCallback callback) {
3306        Preconditions.checkNotNull(callback, "null NetworkCallback");
3307    }
3308
3309    private static void checkTimeout(int timeoutMs) {
3310        Preconditions.checkArgumentPositive(timeoutMs, "timeoutMs must be strictly positive.");
3311    }
3312
3313    /**
3314     * Registers to receive notifications about all networks which satisfy the given
3315     * {@link NetworkRequest}.  The callbacks will continue to be called until
3316     * either the application exits or link #unregisterNetworkCallback(NetworkCallback)} is called.
3317     *
3318     * @param request {@link NetworkRequest} describing this request.
3319     * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
3320     *                        networks change state.
3321     *                        The callback is invoked on the default internal Handler.
3322     */
3323    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
3324    public void registerNetworkCallback(NetworkRequest request, NetworkCallback networkCallback) {
3325        registerNetworkCallback(request, networkCallback, getDefaultHandler());
3326    }
3327
3328    /**
3329     * Registers to receive notifications about all networks which satisfy the given
3330     * {@link NetworkRequest}.  The callbacks will continue to be called until
3331     * either the application exits or link #unregisterNetworkCallback(NetworkCallback)} is called.
3332     *
3333     * @param request {@link NetworkRequest} describing this request.
3334     * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
3335     *                        networks change state.
3336     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
3337     */
3338    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
3339    public void registerNetworkCallback(
3340            NetworkRequest request, NetworkCallback networkCallback, Handler handler) {
3341        CallbackHandler cbHandler = new CallbackHandler(handler);
3342        NetworkCapabilities nc = request.networkCapabilities;
3343        sendRequestForNetwork(nc, networkCallback, 0, LISTEN, TYPE_NONE, cbHandler);
3344    }
3345
3346    /**
3347     * Registers a PendingIntent to be sent when a network is available which satisfies the given
3348     * {@link NetworkRequest}.
3349     *
3350     * This function behaves identically to the version that takes a NetworkCallback, but instead
3351     * of {@link NetworkCallback} a {@link PendingIntent} is used.  This means
3352     * the request may outlive the calling application and get called back when a suitable
3353     * network is found.
3354     * <p>
3355     * The operation is an Intent broadcast that goes to a broadcast receiver that
3356     * you registered with {@link Context#registerReceiver} or through the
3357     * &lt;receiver&gt; tag in an AndroidManifest.xml file
3358     * <p>
3359     * The operation Intent is delivered with two extras, a {@link Network} typed
3360     * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest}
3361     * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing
3362     * the original requests parameters.
3363     * <p>
3364     * If there is already a request for this Intent registered (with the equality of
3365     * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
3366     * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
3367     * <p>
3368     * The request may be released normally by calling
3369     * {@link #unregisterNetworkCallback(android.app.PendingIntent)}.
3370     * @param request {@link NetworkRequest} describing this request.
3371     * @param operation Action to perform when the network is available (corresponds
3372     *                  to the {@link NetworkCallback#onAvailable} call.  Typically
3373     *                  comes from {@link PendingIntent#getBroadcast}. Cannot be null.
3374     */
3375    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
3376    public void registerNetworkCallback(NetworkRequest request, PendingIntent operation) {
3377        checkPendingIntentNotNull(operation);
3378        try {
3379            mService.pendingListenForNetwork(request.networkCapabilities, operation);
3380        } catch (RemoteException e) {
3381            throw e.rethrowFromSystemServer();
3382        } catch (ServiceSpecificException e) {
3383            throw convertServiceException(e);
3384        }
3385    }
3386
3387    /**
3388     * Registers to receive notifications about changes in the system default network. The callbacks
3389     * will continue to be called until either the application exits or
3390     * {@link #unregisterNetworkCallback(NetworkCallback)} is called.
3391     *
3392     * @param networkCallback The {@link NetworkCallback} that the system will call as the
3393     *                        system default network changes.
3394     *                        The callback is invoked on the default internal Handler.
3395     */
3396    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
3397    public void registerDefaultNetworkCallback(NetworkCallback networkCallback) {
3398        registerDefaultNetworkCallback(networkCallback, getDefaultHandler());
3399    }
3400
3401    /**
3402     * Registers to receive notifications about changes in the system default network. The callbacks
3403     * will continue to be called until either the application exits or
3404     * {@link #unregisterNetworkCallback(NetworkCallback)} is called.
3405     *
3406     * @param networkCallback The {@link NetworkCallback} that the system will call as the
3407     *                        system default network changes.
3408     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
3409     */
3410    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
3411    public void registerDefaultNetworkCallback(NetworkCallback networkCallback, Handler handler) {
3412        // This works because if the NetworkCapabilities are null,
3413        // ConnectivityService takes them from the default request.
3414        //
3415        // Since the capabilities are exactly the same as the default request's
3416        // capabilities, this request is guaranteed, at all times, to be
3417        // satisfied by the same network, if any, that satisfies the default
3418        // request, i.e., the system default network.
3419        NetworkCapabilities nullCapabilities = null;
3420        CallbackHandler cbHandler = new CallbackHandler(handler);
3421        sendRequestForNetwork(nullCapabilities, networkCallback, 0, REQUEST, TYPE_NONE, cbHandler);
3422    }
3423
3424    /**
3425     * Requests bandwidth update for a given {@link Network} and returns whether the update request
3426     * is accepted by ConnectivityService. Once accepted, ConnectivityService will poll underlying
3427     * network connection for updated bandwidth information. The caller will be notified via
3428     * {@link ConnectivityManager.NetworkCallback} if there is an update. Notice that this
3429     * method assumes that the caller has previously called
3430     * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} to listen for network
3431     * changes.
3432     *
3433     * @param network {@link Network} specifying which network you're interested.
3434     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
3435     */
3436    public boolean requestBandwidthUpdate(Network network) {
3437        try {
3438            return mService.requestBandwidthUpdate(network);
3439        } catch (RemoteException e) {
3440            throw e.rethrowFromSystemServer();
3441        }
3442    }
3443
3444    /**
3445     * Unregisters a {@code NetworkCallback} and possibly releases networks originating from
3446     * {@link #requestNetwork(NetworkRequest, NetworkCallback)} and
3447     * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} calls.
3448     * If the given {@code NetworkCallback} had previously been used with
3449     * {@code #requestNetwork}, any networks that had been connected to only to satisfy that request
3450     * will be disconnected.
3451     *
3452     * Notifications that would have triggered that {@code NetworkCallback} will immediately stop
3453     * triggering it as soon as this call returns.
3454     *
3455     * @param networkCallback The {@link NetworkCallback} used when making the request.
3456     */
3457    public void unregisterNetworkCallback(NetworkCallback networkCallback) {
3458        checkCallbackNotNull(networkCallback);
3459        final List<NetworkRequest> reqs = new ArrayList<>();
3460        // Find all requests associated to this callback and stop callback triggers immediately.
3461        // Callback is reusable immediately. http://b/20701525, http://b/35921499.
3462        synchronized (sCallbacks) {
3463            Preconditions.checkArgument(networkCallback.networkRequest != null,
3464                    "NetworkCallback was not registered");
3465            Preconditions.checkArgument(networkCallback.networkRequest != ALREADY_UNREGISTERED,
3466                    "NetworkCallback was already unregistered");
3467            for (Map.Entry<NetworkRequest, NetworkCallback> e : sCallbacks.entrySet()) {
3468                if (e.getValue() == networkCallback) {
3469                    reqs.add(e.getKey());
3470                }
3471            }
3472            // TODO: throw exception if callback was registered more than once (http://b/20701525).
3473            for (NetworkRequest r : reqs) {
3474                try {
3475                    mService.releaseNetworkRequest(r);
3476                } catch (RemoteException e) {
3477                    throw e.rethrowFromSystemServer();
3478                }
3479                // Only remove mapping if rpc was successful.
3480                sCallbacks.remove(r);
3481            }
3482            networkCallback.networkRequest = ALREADY_UNREGISTERED;
3483        }
3484    }
3485
3486    /**
3487     * Unregisters a callback previously registered via
3488     * {@link #registerNetworkCallback(NetworkRequest, android.app.PendingIntent)}.
3489     *
3490     * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the
3491     *                  PendingIntent passed to
3492     *                  {@link #registerNetworkCallback(NetworkRequest, android.app.PendingIntent)}.
3493     *                  Cannot be null.
3494     */
3495    public void unregisterNetworkCallback(PendingIntent operation) {
3496        checkPendingIntentNotNull(operation);
3497        releaseNetworkRequest(operation);
3498    }
3499
3500    /**
3501     * Informs the system whether it should switch to {@code network} regardless of whether it is
3502     * validated or not. If {@code accept} is true, and the network was explicitly selected by the
3503     * user (e.g., by selecting a Wi-Fi network in the Settings app), then the network will become
3504     * the system default network regardless of any other network that's currently connected. If
3505     * {@code always} is true, then the choice is remembered, so that the next time the user
3506     * connects to this network, the system will switch to it.
3507     *
3508     * @param network The network to accept.
3509     * @param accept Whether to accept the network even if unvalidated.
3510     * @param always Whether to remember this choice in the future.
3511     *
3512     * @hide
3513     */
3514    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
3515    public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
3516        try {
3517            mService.setAcceptUnvalidated(network, accept, always);
3518        } catch (RemoteException e) {
3519            throw e.rethrowFromSystemServer();
3520        }
3521    }
3522
3523    /**
3524     * Informs the system to penalize {@code network}'s score when it becomes unvalidated. This is
3525     * only meaningful if the system is configured not to penalize such networks, e.g., if the
3526     * {@code config_networkAvoidBadWifi} configuration variable is set to 0 and the {@code
3527     * NETWORK_AVOID_BAD_WIFI setting is unset}.
3528     *
3529     * @param network The network to accept.
3530     *
3531     * @hide
3532     */
3533    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
3534    public void setAvoidUnvalidated(Network network) {
3535        try {
3536            mService.setAvoidUnvalidated(network);
3537        } catch (RemoteException e) {
3538            throw e.rethrowFromSystemServer();
3539        }
3540    }
3541
3542    /**
3543     * Requests that the system open the captive portal app on the specified network.
3544     *
3545     * @param network The network to log into.
3546     *
3547     * @hide
3548     */
3549    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
3550    public void startCaptivePortalApp(Network network) {
3551        try {
3552            mService.startCaptivePortalApp(network);
3553        } catch (RemoteException e) {
3554            throw e.rethrowFromSystemServer();
3555        }
3556    }
3557
3558    /**
3559     * It is acceptable to briefly use multipath data to provide seamless connectivity for
3560     * time-sensitive user-facing operations when the system default network is temporarily
3561     * unresponsive. The amount of data should be limited (less than one megabyte for every call to
3562     * this method), and the operation should be infrequent to ensure that data usage is limited.
3563     *
3564     * An example of such an operation might be a time-sensitive foreground activity, such as a
3565     * voice command, that the user is performing while walking out of range of a Wi-Fi network.
3566     */
3567    public static final int MULTIPATH_PREFERENCE_HANDOVER = 1 << 0;
3568
3569    /**
3570     * It is acceptable to use small amounts of multipath data on an ongoing basis to provide
3571     * a backup channel for traffic that is primarily going over another network.
3572     *
3573     * An example might be maintaining backup connections to peers or servers for the purpose of
3574     * fast fallback if the default network is temporarily unresponsive or disconnects. The traffic
3575     * on backup paths should be negligible compared to the traffic on the main path.
3576     */
3577    public static final int MULTIPATH_PREFERENCE_RELIABILITY = 1 << 1;
3578
3579    /**
3580     * It is acceptable to use metered data to improve network latency and performance.
3581     */
3582    public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 1 << 2;
3583
3584    /**
3585     * Return value to use for unmetered networks. On such networks we currently set all the flags
3586     * to true.
3587     * @hide
3588     */
3589    public static final int MULTIPATH_PREFERENCE_UNMETERED =
3590            MULTIPATH_PREFERENCE_HANDOVER |
3591            MULTIPATH_PREFERENCE_RELIABILITY |
3592            MULTIPATH_PREFERENCE_PERFORMANCE;
3593
3594    /** @hide */
3595    @Retention(RetentionPolicy.SOURCE)
3596    @IntDef(flag = true, value = {
3597            MULTIPATH_PREFERENCE_HANDOVER,
3598            MULTIPATH_PREFERENCE_RELIABILITY,
3599            MULTIPATH_PREFERENCE_PERFORMANCE,
3600    })
3601    public @interface MultipathPreference {
3602    }
3603
3604    /**
3605     * Provides a hint to the calling application on whether it is desirable to use the
3606     * multinetwork APIs (e.g., {@link Network#openConnection}, {@link Network#bindSocket}, etc.)
3607     * for multipath data transfer on this network when it is not the system default network.
3608     * Applications desiring to use multipath network protocols should call this method before
3609     * each such operation.
3610     *
3611     * @param network The network on which the application desires to use multipath data.
3612     *                If {@code null}, this method will return the a preference that will generally
3613     *                apply to metered networks.
3614     * @return a bitwise OR of zero or more of the  {@code MULTIPATH_PREFERENCE_*} constants.
3615     */
3616    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
3617    public @MultipathPreference int getMultipathPreference(Network network) {
3618        try {
3619            return mService.getMultipathPreference(network);
3620        } catch (RemoteException e) {
3621            throw e.rethrowFromSystemServer();
3622        }
3623    }
3624
3625    /**
3626     * Resets all connectivity manager settings back to factory defaults.
3627     * @hide
3628     */
3629    public void factoryReset() {
3630        try {
3631            mService.factoryReset();
3632        } catch (RemoteException e) {
3633            throw e.rethrowFromSystemServer();
3634        }
3635    }
3636
3637    /**
3638     * Binds the current process to {@code network}.  All Sockets created in the future
3639     * (and not explicitly bound via a bound SocketFactory from
3640     * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
3641     * {@code network}.  All host name resolutions will be limited to {@code network} as well.
3642     * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
3643     * work and all host name resolutions will fail.  This is by design so an application doesn't
3644     * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
3645     * To clear binding pass {@code null} for {@code network}.  Using individually bound
3646     * Sockets created by Network.getSocketFactory().createSocket() and
3647     * performing network-specific host name resolutions via
3648     * {@link Network#getAllByName Network.getAllByName} is preferred to calling
3649     * {@code bindProcessToNetwork}.
3650     *
3651     * @param network The {@link Network} to bind the current process to, or {@code null} to clear
3652     *                the current binding.
3653     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
3654     */
3655    public boolean bindProcessToNetwork(Network network) {
3656        // Forcing callers to call thru non-static function ensures ConnectivityManager
3657        // instantiated.
3658        return setProcessDefaultNetwork(network);
3659    }
3660
3661    /**
3662     * Binds the current process to {@code network}.  All Sockets created in the future
3663     * (and not explicitly bound via a bound SocketFactory from
3664     * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
3665     * {@code network}.  All host name resolutions will be limited to {@code network} as well.
3666     * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
3667     * work and all host name resolutions will fail.  This is by design so an application doesn't
3668     * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
3669     * To clear binding pass {@code null} for {@code network}.  Using individually bound
3670     * Sockets created by Network.getSocketFactory().createSocket() and
3671     * performing network-specific host name resolutions via
3672     * {@link Network#getAllByName Network.getAllByName} is preferred to calling
3673     * {@code setProcessDefaultNetwork}.
3674     *
3675     * @param network The {@link Network} to bind the current process to, or {@code null} to clear
3676     *                the current binding.
3677     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
3678     * @deprecated This function can throw {@link IllegalStateException}.  Use
3679     *             {@link #bindProcessToNetwork} instead.  {@code bindProcessToNetwork}
3680     *             is a direct replacement.
3681     */
3682    @Deprecated
3683    public static boolean setProcessDefaultNetwork(Network network) {
3684        int netId = (network == null) ? NETID_UNSET : network.netId;
3685        if (netId == NetworkUtils.getBoundNetworkForProcess()) {
3686            return true;
3687        }
3688        if (NetworkUtils.bindProcessToNetwork(netId)) {
3689            // Set HTTP proxy system properties to match network.
3690            // TODO: Deprecate this static method and replace it with a non-static version.
3691            try {
3692                Proxy.setHttpProxySystemProperty(getInstance().getDefaultProxy());
3693            } catch (SecurityException e) {
3694                // The process doesn't have ACCESS_NETWORK_STATE, so we can't fetch the proxy.
3695                Log.e(TAG, "Can't set proxy properties", e);
3696            }
3697            // Must flush DNS cache as new network may have different DNS resolutions.
3698            InetAddress.clearDnsCache();
3699            // Must flush socket pool as idle sockets will be bound to previous network and may
3700            // cause subsequent fetches to be performed on old network.
3701            NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
3702            return true;
3703        } else {
3704            return false;
3705        }
3706    }
3707
3708    /**
3709     * Returns the {@link Network} currently bound to this process via
3710     * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
3711     *
3712     * @return {@code Network} to which this process is bound, or {@code null}.
3713     */
3714    public Network getBoundNetworkForProcess() {
3715        // Forcing callers to call thru non-static function ensures ConnectivityManager
3716        // instantiated.
3717        return getProcessDefaultNetwork();
3718    }
3719
3720    /**
3721     * Returns the {@link Network} currently bound to this process via
3722     * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
3723     *
3724     * @return {@code Network} to which this process is bound, or {@code null}.
3725     * @deprecated Using this function can lead to other functions throwing
3726     *             {@link IllegalStateException}.  Use {@link #getBoundNetworkForProcess} instead.
3727     *             {@code getBoundNetworkForProcess} is a direct replacement.
3728     */
3729    @Deprecated
3730    public static Network getProcessDefaultNetwork() {
3731        int netId = NetworkUtils.getBoundNetworkForProcess();
3732        if (netId == NETID_UNSET) return null;
3733        return new Network(netId);
3734    }
3735
3736    private void unsupportedStartingFrom(int version) {
3737        if (Process.myUid() == Process.SYSTEM_UID) {
3738            // The getApplicationInfo() call we make below is not supported in system context, and
3739            // we want to allow the system to use these APIs anyway.
3740            return;
3741        }
3742
3743        if (mContext.getApplicationInfo().targetSdkVersion >= version) {
3744            throw new UnsupportedOperationException(
3745                    "This method is not supported in target SDK version " + version + " and above");
3746        }
3747    }
3748
3749    // Checks whether the calling app can use the legacy routing API (startUsingNetworkFeature,
3750    // stopUsingNetworkFeature, requestRouteToHost), and if not throw UnsupportedOperationException.
3751    // TODO: convert the existing system users (Tethering, GnssLocationProvider) to the new APIs and
3752    // remove these exemptions. Note that this check is not secure, and apps can still access these
3753    // functions by accessing ConnectivityService directly. However, it should be clear that doing
3754    // so is unsupported and may break in the future. http://b/22728205
3755    private void checkLegacyRoutingApiAccess() {
3756        if (mContext.checkCallingOrSelfPermission("com.android.permission.INJECT_OMADM_SETTINGS")
3757                == PackageManager.PERMISSION_GRANTED) {
3758            return;
3759        }
3760
3761        unsupportedStartingFrom(VERSION_CODES.M);
3762    }
3763
3764    /**
3765     * Binds host resolutions performed by this process to {@code network}.
3766     * {@link #bindProcessToNetwork} takes precedence over this setting.
3767     *
3768     * @param network The {@link Network} to bind host resolutions from the current process to, or
3769     *                {@code null} to clear the current binding.
3770     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
3771     * @hide
3772     * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}.
3773     */
3774    @Deprecated
3775    public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
3776        return NetworkUtils.bindProcessToNetworkForHostResolution(
3777                network == null ? NETID_UNSET : network.netId);
3778    }
3779
3780    /**
3781     * Device is not restricting metered network activity while application is running on
3782     * background.
3783     */
3784    public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1;
3785
3786    /**
3787     * Device is restricting metered network activity while application is running on background,
3788     * but application is allowed to bypass it.
3789     * <p>
3790     * In this state, application should take action to mitigate metered network access.
3791     * For example, a music streaming application should switch to a low-bandwidth bitrate.
3792     */
3793    public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2;
3794
3795    /**
3796     * Device is restricting metered network activity while application is running on background.
3797     * <p>
3798     * In this state, application should not try to use the network while running on background,
3799     * because it would be denied.
3800     */
3801    public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3;
3802
3803    /**
3804     * A change in the background metered network activity restriction has occurred.
3805     * <p>
3806     * Applications should call {@link #getRestrictBackgroundStatus()} to check if the restriction
3807     * applies to them.
3808     * <p>
3809     * This is only sent to registered receivers, not manifest receivers.
3810     */
3811    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
3812    public static final String ACTION_RESTRICT_BACKGROUND_CHANGED =
3813            "android.net.conn.RESTRICT_BACKGROUND_CHANGED";
3814
3815    /** @hide */
3816    @Retention(RetentionPolicy.SOURCE)
3817    @IntDef(flag = false, value = {
3818            RESTRICT_BACKGROUND_STATUS_DISABLED,
3819            RESTRICT_BACKGROUND_STATUS_WHITELISTED,
3820            RESTRICT_BACKGROUND_STATUS_ENABLED,
3821    })
3822    public @interface RestrictBackgroundStatus {
3823    }
3824
3825    private INetworkPolicyManager getNetworkPolicyManager() {
3826        synchronized (this) {
3827            if (mNPManager != null) {
3828                return mNPManager;
3829            }
3830            mNPManager = INetworkPolicyManager.Stub.asInterface(ServiceManager
3831                    .getService(Context.NETWORK_POLICY_SERVICE));
3832            return mNPManager;
3833        }
3834    }
3835
3836    /**
3837     * Determines if the calling application is subject to metered network restrictions while
3838     * running on background.
3839     *
3840     * @return {@link #RESTRICT_BACKGROUND_STATUS_DISABLED},
3841     * {@link #RESTRICT_BACKGROUND_STATUS_ENABLED},
3842     * or {@link #RESTRICT_BACKGROUND_STATUS_WHITELISTED}
3843     */
3844    public @RestrictBackgroundStatus int getRestrictBackgroundStatus() {
3845        try {
3846            return getNetworkPolicyManager().getRestrictBackgroundByCaller();
3847        } catch (RemoteException e) {
3848            throw e.rethrowFromSystemServer();
3849        }
3850    }
3851
3852    /**
3853     * The network watchlist is a list of domains and IP addresses that are associated with
3854     * potentially harmful apps. This method returns the hash of the watchlist currently
3855     * used by the system.
3856     *
3857     * @return Hash of network watchlist config file. Null if config does not exist.
3858     */
3859    public byte[] getNetworkWatchlistConfigHash() {
3860        try {
3861            return mService.getNetworkWatchlistConfigHash();
3862        } catch (RemoteException e) {
3863            Log.e(TAG, "Unable to get watchlist config hash");
3864            throw e.rethrowFromSystemServer();
3865        }
3866    }
3867}
3868