ConnectivityManager.java revision a86d5d5624d691b4b1906eae25a67ee19a600c80
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 boolean checkChangePermission(Context context) {
1981        int uid = Binder.getCallingUid();
1982        return Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings
1983                .getPackageNameForUid(context, uid), false /* throwException */);
1984    }
1985
1986    /** {@hide} */
1987    public static final void enforceChangePermission(Context context) {
1988        int uid = Binder.getCallingUid();
1989        Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings
1990                .getPackageNameForUid(context, uid), true /* throwException */);
1991    }
1992
1993    /** {@hide} */
1994    public static final void enforceTetherChangePermission(Context context, String callingPkg) {
1995        Preconditions.checkNotNull(context, "Context cannot be null");
1996        Preconditions.checkNotNull(callingPkg, "callingPkg cannot be null");
1997
1998        if (context.getResources().getStringArray(
1999                com.android.internal.R.array.config_mobile_hotspot_provision_app).length == 2) {
2000            // Have a provisioning app - must only let system apps (which check this app)
2001            // turn on tethering
2002            context.enforceCallingOrSelfPermission(
2003                    android.Manifest.permission.TETHER_PRIVILEGED, "ConnectivityService");
2004        } else {
2005            int uid = Binder.getCallingUid();
2006            // If callingPkg's uid is not same as Binder.getCallingUid(),
2007            // AppOpsService throws SecurityException.
2008            Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPkg,
2009                    true /* throwException */);
2010        }
2011    }
2012
2013    /**
2014     * @deprecated - use getSystemService. This is a kludge to support static access in certain
2015     *               situations where a Context pointer is unavailable.
2016     * @hide
2017     */
2018    @Deprecated
2019    static ConnectivityManager getInstanceOrNull() {
2020        return sInstance;
2021    }
2022
2023    /**
2024     * @deprecated - use getSystemService. This is a kludge to support static access in certain
2025     *               situations where a Context pointer is unavailable.
2026     * @hide
2027     */
2028    @Deprecated
2029    private static ConnectivityManager getInstance() {
2030        if (getInstanceOrNull() == null) {
2031            throw new IllegalStateException("No ConnectivityManager yet constructed");
2032        }
2033        return getInstanceOrNull();
2034    }
2035
2036    /**
2037     * Get the set of tetherable, available interfaces.  This list is limited by
2038     * device configuration and current interface existence.
2039     *
2040     * @return an array of 0 or more Strings of tetherable interface names.
2041     *
2042     * {@hide}
2043     */
2044    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2045    public String[] getTetherableIfaces() {
2046        try {
2047            return mService.getTetherableIfaces();
2048        } catch (RemoteException e) {
2049            throw e.rethrowFromSystemServer();
2050        }
2051    }
2052
2053    /**
2054     * Get the set of tethered interfaces.
2055     *
2056     * @return an array of 0 or more String of currently tethered interface names.
2057     *
2058     * {@hide}
2059     */
2060    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2061    public String[] getTetheredIfaces() {
2062        try {
2063            return mService.getTetheredIfaces();
2064        } catch (RemoteException e) {
2065            throw e.rethrowFromSystemServer();
2066        }
2067    }
2068
2069    /**
2070     * Get the set of interface names which attempted to tether but
2071     * failed.  Re-attempting to tether may cause them to reset to the Tethered
2072     * state.  Alternatively, causing the interface to be destroyed and recreated
2073     * may cause them to reset to the available state.
2074     * {@link ConnectivityManager#getLastTetherError} can be used to get more
2075     * information on the cause of the errors.
2076     *
2077     * @return an array of 0 or more String indicating the interface names
2078     *        which failed to tether.
2079     *
2080     * {@hide}
2081     */
2082    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2083    public String[] getTetheringErroredIfaces() {
2084        try {
2085            return mService.getTetheringErroredIfaces();
2086        } catch (RemoteException e) {
2087            throw e.rethrowFromSystemServer();
2088        }
2089    }
2090
2091    /**
2092     * Get the set of tethered dhcp ranges.
2093     *
2094     * @return an array of 0 or more {@code String} of tethered dhcp ranges.
2095     * {@hide}
2096     */
2097    public String[] getTetheredDhcpRanges() {
2098        try {
2099            return mService.getTetheredDhcpRanges();
2100        } catch (RemoteException e) {
2101            throw e.rethrowFromSystemServer();
2102        }
2103    }
2104
2105    /**
2106     * Attempt to tether the named interface.  This will setup a dhcp server
2107     * on the interface, forward and NAT IP packets and forward DNS requests
2108     * to the best active upstream network interface.  Note that if no upstream
2109     * IP network interface is available, dhcp will still run and traffic will be
2110     * allowed between the tethered devices and this device, though upstream net
2111     * access will of course fail until an upstream network interface becomes
2112     * active.
2113     *
2114     * <p>This method requires the caller to hold either the
2115     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
2116     * or the ability to modify system settings as determined by
2117     * {@link android.provider.Settings.System#canWrite}.</p>
2118     *
2119     * <p>WARNING: New clients should not use this function. The only usages should be in PanService
2120     * and WifiStateMachine which need direct access. All other clients should use
2121     * {@link #startTethering} and {@link #stopTethering} which encapsulate proper provisioning
2122     * logic.</p>
2123     *
2124     * @param iface the interface name to tether.
2125     * @return error a {@code TETHER_ERROR} value indicating success or failure type
2126     *
2127     * {@hide}
2128     */
2129    public int tether(String iface) {
2130        try {
2131            String pkgName = mContext.getOpPackageName();
2132            Log.i(TAG, "tether caller:" + pkgName);
2133            return mService.tether(iface, pkgName);
2134        } catch (RemoteException e) {
2135            throw e.rethrowFromSystemServer();
2136        }
2137    }
2138
2139    /**
2140     * Stop tethering the named interface.
2141     *
2142     * <p>This method requires the caller to hold either the
2143     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
2144     * or the ability to modify system settings as determined by
2145     * {@link android.provider.Settings.System#canWrite}.</p>
2146     *
2147     * <p>WARNING: New clients should not use this function. The only usages should be in PanService
2148     * and WifiStateMachine which need direct access. All other clients should use
2149     * {@link #startTethering} and {@link #stopTethering} which encapsulate proper provisioning
2150     * logic.</p>
2151     *
2152     * @param iface the interface name to untether.
2153     * @return error a {@code TETHER_ERROR} value indicating success or failure type
2154     *
2155     * {@hide}
2156     */
2157    public int untether(String iface) {
2158        try {
2159            String pkgName = mContext.getOpPackageName();
2160            Log.i(TAG, "untether caller:" + pkgName);
2161            return mService.untether(iface, pkgName);
2162        } catch (RemoteException e) {
2163            throw e.rethrowFromSystemServer();
2164        }
2165    }
2166
2167    /**
2168     * Check if the device allows for tethering.  It may be disabled via
2169     * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
2170     * due to device configuration.
2171     *
2172     * <p>If this app does not have permission to use this API, it will always
2173     * return false rather than throw an exception.</p>
2174     *
2175     * <p>If the device has a hotspot provisioning app, the caller is required to hold the
2176     * {@link android.Manifest.permission.TETHER_PRIVILEGED} permission.</p>
2177     *
2178     * <p>Otherwise, this method requires the caller to hold the ability to modify system
2179     * settings as determined by {@link android.provider.Settings.System#canWrite}.</p>
2180     *
2181     * @return a boolean - {@code true} indicating Tethering is supported.
2182     *
2183     * {@hide}
2184     */
2185    @SystemApi
2186    @RequiresPermission(anyOf = {android.Manifest.permission.TETHER_PRIVILEGED,
2187            android.Manifest.permission.WRITE_SETTINGS})
2188    public boolean isTetheringSupported() {
2189        String pkgName = mContext.getOpPackageName();
2190        try {
2191            return mService.isTetheringSupported(pkgName);
2192        } catch (SecurityException e) {
2193            // This API is not available to this caller, but for backward-compatibility
2194            // this will just return false instead of throwing.
2195            return false;
2196        } catch (RemoteException e) {
2197            throw e.rethrowFromSystemServer();
2198        }
2199    }
2200
2201    /**
2202     * Callback for use with {@link #startTethering} to find out whether tethering succeeded.
2203     * @hide
2204     */
2205    @SystemApi
2206    public static abstract class OnStartTetheringCallback {
2207        /**
2208         * Called when tethering has been successfully started.
2209         */
2210        public void onTetheringStarted() {};
2211
2212        /**
2213         * Called when starting tethering failed.
2214         */
2215        public void onTetheringFailed() {};
2216    }
2217
2218    /**
2219     * Convenient overload for
2220     * {@link #startTethering(int, boolean, OnStartTetheringCallback, Handler)} which passes a null
2221     * handler to run on the current thread's {@link Looper}.
2222     * @hide
2223     */
2224    @SystemApi
2225    @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
2226    public void startTethering(int type, boolean showProvisioningUi,
2227            final OnStartTetheringCallback callback) {
2228        startTethering(type, showProvisioningUi, callback, null);
2229    }
2230
2231    /**
2232     * Runs tether provisioning for the given type if needed and then starts tethering if
2233     * the check succeeds. If no carrier provisioning is required for tethering, tethering is
2234     * enabled immediately. If provisioning fails, tethering will not be enabled. It also
2235     * schedules tether provisioning re-checks if appropriate.
2236     *
2237     * @param type The type of tethering to start. Must be one of
2238     *         {@link ConnectivityManager.TETHERING_WIFI},
2239     *         {@link ConnectivityManager.TETHERING_USB}, or
2240     *         {@link ConnectivityManager.TETHERING_BLUETOOTH}.
2241     * @param showProvisioningUi a boolean indicating to show the provisioning app UI if there
2242     *         is one. This should be true the first time this function is called and also any time
2243     *         the user can see this UI. It gives users information from their carrier about the
2244     *         check failing and how they can sign up for tethering if possible.
2245     * @param callback an {@link OnStartTetheringCallback} which will be called to notify the caller
2246     *         of the result of trying to tether.
2247     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
2248     * @hide
2249     */
2250    @SystemApi
2251    @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
2252    public void startTethering(int type, boolean showProvisioningUi,
2253            final OnStartTetheringCallback callback, Handler handler) {
2254        Preconditions.checkNotNull(callback, "OnStartTetheringCallback cannot be null.");
2255
2256        ResultReceiver wrappedCallback = new ResultReceiver(handler) {
2257            @Override
2258            protected void onReceiveResult(int resultCode, Bundle resultData) {
2259                if (resultCode == TETHER_ERROR_NO_ERROR) {
2260                    callback.onTetheringStarted();
2261                } else {
2262                    callback.onTetheringFailed();
2263                }
2264            }
2265        };
2266
2267        try {
2268            String pkgName = mContext.getOpPackageName();
2269            Log.i(TAG, "startTethering caller:" + pkgName);
2270            mService.startTethering(type, wrappedCallback, showProvisioningUi, pkgName);
2271        } catch (RemoteException e) {
2272            Log.e(TAG, "Exception trying to start tethering.", e);
2273            wrappedCallback.send(TETHER_ERROR_SERVICE_UNAVAIL, null);
2274        }
2275    }
2276
2277    /**
2278     * Stops tethering for the given type. Also cancels any provisioning rechecks for that type if
2279     * applicable.
2280     *
2281     * @param type The type of tethering to stop. Must be one of
2282     *         {@link ConnectivityManager.TETHERING_WIFI},
2283     *         {@link ConnectivityManager.TETHERING_USB}, or
2284     *         {@link ConnectivityManager.TETHERING_BLUETOOTH}.
2285     * @hide
2286     */
2287    @SystemApi
2288    @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
2289    public void stopTethering(int type) {
2290        try {
2291            String pkgName = mContext.getOpPackageName();
2292            Log.i(TAG, "stopTethering caller:" + pkgName);
2293            mService.stopTethering(type, pkgName);
2294        } catch (RemoteException e) {
2295            throw e.rethrowFromSystemServer();
2296        }
2297    }
2298
2299    /**
2300     * Get the list of regular expressions that define any tetherable
2301     * USB network interfaces.  If USB tethering is not supported by the
2302     * device, this list should be empty.
2303     *
2304     * @return an array of 0 or more regular expression Strings defining
2305     *        what interfaces are considered tetherable usb interfaces.
2306     *
2307     * {@hide}
2308     */
2309    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2310    public String[] getTetherableUsbRegexs() {
2311        try {
2312            return mService.getTetherableUsbRegexs();
2313        } catch (RemoteException e) {
2314            throw e.rethrowFromSystemServer();
2315        }
2316    }
2317
2318    /**
2319     * Get the list of regular expressions that define any tetherable
2320     * Wifi network interfaces.  If Wifi tethering is not supported by the
2321     * device, this list should be empty.
2322     *
2323     * @return an array of 0 or more regular expression Strings defining
2324     *        what interfaces are considered tetherable wifi interfaces.
2325     *
2326     * {@hide}
2327     */
2328    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2329    public String[] getTetherableWifiRegexs() {
2330        try {
2331            return mService.getTetherableWifiRegexs();
2332        } catch (RemoteException e) {
2333            throw e.rethrowFromSystemServer();
2334        }
2335    }
2336
2337    /**
2338     * Get the list of regular expressions that define any tetherable
2339     * Bluetooth network interfaces.  If Bluetooth tethering is not supported by the
2340     * device, this list should be empty.
2341     *
2342     * @return an array of 0 or more regular expression Strings defining
2343     *        what interfaces are considered tetherable bluetooth interfaces.
2344     *
2345     * {@hide}
2346     */
2347    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2348    public String[] getTetherableBluetoothRegexs() {
2349        try {
2350            return mService.getTetherableBluetoothRegexs();
2351        } catch (RemoteException e) {
2352            throw e.rethrowFromSystemServer();
2353        }
2354    }
2355
2356    /**
2357     * Attempt to both alter the mode of USB and Tethering of USB.  A
2358     * utility method to deal with some of the complexity of USB - will
2359     * attempt to switch to Rndis and subsequently tether the resulting
2360     * interface on {@code true} or turn off tethering and switch off
2361     * Rndis on {@code false}.
2362     *
2363     * <p>This method requires the caller to hold either the
2364     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
2365     * or the ability to modify system settings as determined by
2366     * {@link android.provider.Settings.System#canWrite}.</p>
2367     *
2368     * @param enable a boolean - {@code true} to enable tethering
2369     * @return error a {@code TETHER_ERROR} value indicating success or failure type
2370     *
2371     * {@hide}
2372     */
2373    public int setUsbTethering(boolean enable) {
2374        try {
2375            String pkgName = mContext.getOpPackageName();
2376            Log.i(TAG, "setUsbTethering caller:" + pkgName);
2377            return mService.setUsbTethering(enable, pkgName);
2378        } catch (RemoteException e) {
2379            throw e.rethrowFromSystemServer();
2380        }
2381    }
2382
2383    /** {@hide} */
2384    public static final int TETHER_ERROR_NO_ERROR           = 0;
2385    /** {@hide} */
2386    public static final int TETHER_ERROR_UNKNOWN_IFACE      = 1;
2387    /** {@hide} */
2388    public static final int TETHER_ERROR_SERVICE_UNAVAIL    = 2;
2389    /** {@hide} */
2390    public static final int TETHER_ERROR_UNSUPPORTED        = 3;
2391    /** {@hide} */
2392    public static final int TETHER_ERROR_UNAVAIL_IFACE      = 4;
2393    /** {@hide} */
2394    public static final int TETHER_ERROR_MASTER_ERROR       = 5;
2395    /** {@hide} */
2396    public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
2397    /** {@hide} */
2398    public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
2399    /** {@hide} */
2400    public static final int TETHER_ERROR_ENABLE_NAT_ERROR     = 8;
2401    /** {@hide} */
2402    public static final int TETHER_ERROR_DISABLE_NAT_ERROR    = 9;
2403    /** {@hide} */
2404    public static final int TETHER_ERROR_IFACE_CFG_ERROR      = 10;
2405    /** {@hide} */
2406    public static final int TETHER_ERROR_PROVISION_FAILED     = 11;
2407
2408    /**
2409     * Get a more detailed error code after a Tethering or Untethering
2410     * request asynchronously failed.
2411     *
2412     * @param iface The name of the interface of interest
2413     * @return error The error code of the last error tethering or untethering the named
2414     *               interface
2415     *
2416     * {@hide}
2417     */
2418    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2419    public int getLastTetherError(String iface) {
2420        try {
2421            return mService.getLastTetherError(iface);
2422        } catch (RemoteException e) {
2423            throw e.rethrowFromSystemServer();
2424        }
2425    }
2426
2427    /**
2428     * Report network connectivity status.  This is currently used only
2429     * to alter status bar UI.
2430     * <p>This method requires the caller to hold the permission
2431     * {@link android.Manifest.permission#STATUS_BAR}.
2432     *
2433     * @param networkType The type of network you want to report on
2434     * @param percentage The quality of the connection 0 is bad, 100 is good
2435     * @deprecated Types are deprecated. Use {@link #reportNetworkConnectivity} instead.
2436     * {@hide}
2437     */
2438    public void reportInetCondition(int networkType, int percentage) {
2439        try {
2440            mService.reportInetCondition(networkType, percentage);
2441        } catch (RemoteException e) {
2442            throw e.rethrowFromSystemServer();
2443        }
2444    }
2445
2446    /**
2447     * Report a problem network to the framework.  This provides a hint to the system
2448     * that there might be connectivity problems on this network and may cause
2449     * the framework to re-evaluate network connectivity and/or switch to another
2450     * network.
2451     *
2452     * @param network The {@link Network} the application was attempting to use
2453     *                or {@code null} to indicate the current default network.
2454     * @deprecated Use {@link #reportNetworkConnectivity} which allows reporting both
2455     *             working and non-working connectivity.
2456     */
2457    @Deprecated
2458    public void reportBadNetwork(Network network) {
2459        try {
2460            // One of these will be ignored because it matches system's current state.
2461            // The other will trigger the necessary reevaluation.
2462            mService.reportNetworkConnectivity(network, true);
2463            mService.reportNetworkConnectivity(network, false);
2464        } catch (RemoteException e) {
2465            throw e.rethrowFromSystemServer();
2466        }
2467    }
2468
2469    /**
2470     * Report to the framework whether a network has working connectivity.
2471     * This provides a hint to the system that a particular network is providing
2472     * working connectivity or not.  In response the framework may re-evaluate
2473     * the network's connectivity and might take further action thereafter.
2474     *
2475     * @param network The {@link Network} the application was attempting to use
2476     *                or {@code null} to indicate the current default network.
2477     * @param hasConnectivity {@code true} if the application was able to successfully access the
2478     *                        Internet using {@code network} or {@code false} if not.
2479     */
2480    public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
2481        try {
2482            mService.reportNetworkConnectivity(network, hasConnectivity);
2483        } catch (RemoteException e) {
2484            throw e.rethrowFromSystemServer();
2485        }
2486    }
2487
2488    /**
2489     * Set a network-independent global http proxy.  This is not normally what you want
2490     * for typical HTTP proxies - they are general network dependent.  However if you're
2491     * doing something unusual like general internal filtering this may be useful.  On
2492     * a private network where the proxy is not accessible, you may break HTTP using this.
2493     *
2494     * @param p A {@link ProxyInfo} object defining the new global
2495     *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
2496     * @hide
2497     */
2498    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
2499    public void setGlobalProxy(ProxyInfo p) {
2500        try {
2501            mService.setGlobalProxy(p);
2502        } catch (RemoteException e) {
2503            throw e.rethrowFromSystemServer();
2504        }
2505    }
2506
2507    /**
2508     * Retrieve any network-independent global HTTP proxy.
2509     *
2510     * @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
2511     *        if no global HTTP proxy is set.
2512     * @hide
2513     */
2514    public ProxyInfo getGlobalProxy() {
2515        try {
2516            return mService.getGlobalProxy();
2517        } catch (RemoteException e) {
2518            throw e.rethrowFromSystemServer();
2519        }
2520    }
2521
2522    /**
2523     * Retrieve the global HTTP proxy, or if no global HTTP proxy is set, a
2524     * network-specific HTTP proxy.  If {@code network} is null, the
2525     * network-specific proxy returned is the proxy of the default active
2526     * network.
2527     *
2528     * @return {@link ProxyInfo} for the current global HTTP proxy, or if no
2529     *         global HTTP proxy is set, {@code ProxyInfo} for {@code network},
2530     *         or when {@code network} is {@code null},
2531     *         the {@code ProxyInfo} for the default active network.  Returns
2532     *         {@code null} when no proxy applies or the caller doesn't have
2533     *         permission to use {@code network}.
2534     * @hide
2535     */
2536    public ProxyInfo getProxyForNetwork(Network network) {
2537        try {
2538            return mService.getProxyForNetwork(network);
2539        } catch (RemoteException e) {
2540            throw e.rethrowFromSystemServer();
2541        }
2542    }
2543
2544    /**
2545     * Get the current default HTTP proxy settings.  If a global proxy is set it will be returned,
2546     * otherwise if this process is bound to a {@link Network} using
2547     * {@link #bindProcessToNetwork} then that {@code Network}'s proxy is returned, otherwise
2548     * the default network's proxy is returned.
2549     *
2550     * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no
2551     *        HTTP proxy is active.
2552     */
2553    public ProxyInfo getDefaultProxy() {
2554        return getProxyForNetwork(getBoundNetworkForProcess());
2555    }
2556
2557    /**
2558     * Returns true if the hardware supports the given network type
2559     * else it returns false.  This doesn't indicate we have coverage
2560     * or are authorized onto a network, just whether or not the
2561     * hardware supports it.  For example a GSM phone without a SIM
2562     * should still return {@code true} for mobile data, but a wifi only
2563     * tablet would return {@code false}.
2564     *
2565     * @param networkType The network type we'd like to check
2566     * @return {@code true} if supported, else {@code false}
2567     * @deprecated Types are deprecated. Use {@link NetworkCapabilities} instead.
2568     * @hide
2569     */
2570    @Deprecated
2571    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2572    public boolean isNetworkSupported(int networkType) {
2573        try {
2574            return mService.isNetworkSupported(networkType);
2575        } catch (RemoteException e) {
2576            throw e.rethrowFromSystemServer();
2577        }
2578    }
2579
2580    /**
2581     * Returns if the currently active data network is metered. A network is
2582     * classified as metered when the user is sensitive to heavy data usage on
2583     * that connection due to monetary costs, data limitations or
2584     * battery/performance issues. You should check this before doing large
2585     * data transfers, and warn the user or delay the operation until another
2586     * network is available.
2587     *
2588     * @return {@code true} if large transfers should be avoided, otherwise
2589     *        {@code false}.
2590     */
2591    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
2592    public boolean isActiveNetworkMetered() {
2593        try {
2594            return mService.isActiveNetworkMetered();
2595        } catch (RemoteException e) {
2596            throw e.rethrowFromSystemServer();
2597        }
2598    }
2599
2600    /**
2601     * If the LockdownVpn mechanism is enabled, updates the vpn
2602     * with a reload of its profile.
2603     *
2604     * @return a boolean with {@code} indicating success
2605     *
2606     * <p>This method can only be called by the system UID
2607     * {@hide}
2608     */
2609    public boolean updateLockdownVpn() {
2610        try {
2611            return mService.updateLockdownVpn();
2612        } catch (RemoteException e) {
2613            throw e.rethrowFromSystemServer();
2614        }
2615    }
2616
2617    /**
2618     * Check mobile provisioning.
2619     *
2620     * @param suggestedTimeOutMs, timeout in milliseconds
2621     *
2622     * @return time out that will be used, maybe less that suggestedTimeOutMs
2623     * -1 if an error.
2624     *
2625     * {@hide}
2626     */
2627    public int checkMobileProvisioning(int suggestedTimeOutMs) {
2628        int timeOutMs = -1;
2629        try {
2630            timeOutMs = mService.checkMobileProvisioning(suggestedTimeOutMs);
2631        } catch (RemoteException e) {
2632            throw e.rethrowFromSystemServer();
2633        }
2634        return timeOutMs;
2635    }
2636
2637    /**
2638     * Get the mobile provisioning url.
2639     * {@hide}
2640     */
2641    public String getMobileProvisioningUrl() {
2642        try {
2643            return mService.getMobileProvisioningUrl();
2644        } catch (RemoteException e) {
2645            throw e.rethrowFromSystemServer();
2646        }
2647    }
2648
2649    /**
2650     * Set sign in error notification to visible or in visible
2651     *
2652     * @param visible
2653     * @param networkType
2654     *
2655     * {@hide}
2656     * @deprecated Doesn't properly deal with multiple connected networks of the same type.
2657     */
2658    @Deprecated
2659    public void setProvisioningNotificationVisible(boolean visible, int networkType,
2660            String action) {
2661        try {
2662            mService.setProvisioningNotificationVisible(visible, networkType, action);
2663        } catch (RemoteException e) {
2664            throw e.rethrowFromSystemServer();
2665        }
2666    }
2667
2668    /**
2669     * Set the value for enabling/disabling airplane mode
2670     *
2671     * @param enable whether to enable airplane mode or not
2672     *
2673     * @hide
2674     */
2675    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
2676    public void setAirplaneMode(boolean enable) {
2677        try {
2678            mService.setAirplaneMode(enable);
2679        } catch (RemoteException e) {
2680            throw e.rethrowFromSystemServer();
2681        }
2682    }
2683
2684    /** {@hide} */
2685    public void registerNetworkFactory(Messenger messenger, String name) {
2686        try {
2687            mService.registerNetworkFactory(messenger, name);
2688        } catch (RemoteException e) {
2689            throw e.rethrowFromSystemServer();
2690        }
2691    }
2692
2693    /** {@hide} */
2694    public void unregisterNetworkFactory(Messenger messenger) {
2695        try {
2696            mService.unregisterNetworkFactory(messenger);
2697        } catch (RemoteException e) {
2698            throw e.rethrowFromSystemServer();
2699        }
2700    }
2701
2702    /**
2703     * @hide
2704     * Register a NetworkAgent with ConnectivityService.
2705     * @return NetID corresponding to NetworkAgent.
2706     */
2707    public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
2708            NetworkCapabilities nc, int score, NetworkMisc misc) {
2709        try {
2710            return mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc);
2711        } catch (RemoteException e) {
2712            throw e.rethrowFromSystemServer();
2713        }
2714    }
2715
2716    /**
2717     * Base class for {@code NetworkRequest} callbacks. Used for notifications about network
2718     * changes. Should be extended by applications wanting notifications.
2719     *
2720     * A {@code NetworkCallback} is registered by calling
2721     * {@link #requestNetwork(NetworkRequest, NetworkCallback)},
2722     * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)},
2723     * or {@link #registerDefaultNetworkCallback(NetworkCallback)}. A {@code NetworkCallback} is
2724     * unregistered by calling {@link #unregisterNetworkCallback(NetworkCallback)}.
2725     * A {@code NetworkCallback} should be registered at most once at any time.
2726     * A {@code NetworkCallback} that has been unregistered can be registered again.
2727     */
2728    public static class NetworkCallback {
2729        /**
2730         * Called when the framework connects to a new network to evaluate whether it satisfies this
2731         * request. If evaluation succeeds, this callback may be followed by an {@link #onAvailable}
2732         * callback. There is no guarantee that this new network will satisfy any requests, or that
2733         * the network will stay connected for longer than the time necessary to evaluate it.
2734         * <p>
2735         * Most applications <b>should not</b> act on this callback, and should instead use
2736         * {@link #onAvailable}. This callback is intended for use by applications that can assist
2737         * the framework in properly evaluating the network &mdash; for example, an application that
2738         * can automatically log in to a captive portal without user intervention.
2739         *
2740         * @param network The {@link Network} of the network that is being evaluated.
2741         *
2742         * @hide
2743         */
2744        public void onPreCheck(Network network) {}
2745
2746        /**
2747         * Called when the framework connects and has declared a new network ready for use.
2748         * This callback may be called more than once if the {@link Network} that is
2749         * satisfying the request changes.
2750         *
2751         * @param network The {@link Network} of the satisfying network.
2752         * @param networkCapabilities The {@link NetworkCapabilities} of the satisfying network.
2753         * @param linkProperties The {@link LinkProperties} of the satisfying network.
2754         * @hide
2755         */
2756        public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
2757                LinkProperties linkProperties) {
2758            // Internally only this method is called when a new network is available, and
2759            // it calls the callback in the same way and order that older versions used
2760            // to call so as not to change the behavior.
2761            onAvailable(network);
2762            if (!networkCapabilities.hasCapability(
2763                    NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)) {
2764                onNetworkSuspended(network);
2765            }
2766            onCapabilitiesChanged(network, networkCapabilities);
2767            onLinkPropertiesChanged(network, linkProperties);
2768        }
2769
2770        /**
2771         * Called when the framework connects and has declared a new network ready for use.
2772         * This callback may be called more than once if the {@link Network} that is
2773         * satisfying the request changes. This will always immediately be followed by a
2774         * call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} then by a
2775         * call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}.
2776         *
2777         * @param network The {@link Network} of the satisfying network.
2778         */
2779        public void onAvailable(Network network) {}
2780
2781        /**
2782         * Called when the network is about to be disconnected.  Often paired with an
2783         * {@link NetworkCallback#onAvailable} call with the new replacement network
2784         * for graceful handover.  This may not be called if we have a hard loss
2785         * (loss without warning).  This may be followed by either a
2786         * {@link NetworkCallback#onLost} call or a
2787         * {@link NetworkCallback#onAvailable} call for this network depending
2788         * on whether we lose or regain it.
2789         *
2790         * @param network The {@link Network} that is about to be disconnected.
2791         * @param maxMsToLive The time in ms the framework will attempt to keep the
2792         *                     network connected.  Note that the network may suffer a
2793         *                     hard loss at any time.
2794         */
2795        public void onLosing(Network network, int maxMsToLive) {}
2796
2797        /**
2798         * Called when the framework has a hard loss of the network or when the
2799         * graceful failure ends.
2800         *
2801         * @param network The {@link Network} lost.
2802         */
2803        public void onLost(Network network) {}
2804
2805        /**
2806         * Called if no network is found in the timeout time specified in
2807         * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)} call. This callback is not
2808         * called for the version of {@link #requestNetwork(NetworkRequest, NetworkCallback)}
2809         * without timeout. When this callback is invoked the associated
2810         * {@link NetworkRequest} will have already been removed and released, as if
2811         * {@link #unregisterNetworkCallback(NetworkCallback)} had been called.
2812         */
2813        public void onUnavailable() {}
2814
2815        /**
2816         * Called when the network the framework connected to for this request
2817         * changes capabilities but still satisfies the stated need.
2818         *
2819         * @param network The {@link Network} whose capabilities have changed.
2820         * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this
2821         *                            network.
2822         */
2823        public void onCapabilitiesChanged(Network network,
2824                NetworkCapabilities networkCapabilities) {}
2825
2826        /**
2827         * Called when the network the framework connected to for this request
2828         * changes {@link LinkProperties}.
2829         *
2830         * @param network The {@link Network} whose link properties have changed.
2831         * @param linkProperties The new {@link LinkProperties} for this network.
2832         */
2833        public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {}
2834
2835        /**
2836         * Called when the network the framework connected to for this request
2837         * goes into {@link NetworkInfo.State#SUSPENDED}.
2838         * This generally means that while the TCP connections are still live,
2839         * temporarily network data fails to transfer.  Specifically this is used
2840         * on cellular networks to mask temporary outages when driving through
2841         * a tunnel, etc.
2842         * @hide
2843         */
2844        public void onNetworkSuspended(Network network) {}
2845
2846        /**
2847         * Called when the network the framework connected to for this request
2848         * returns from a {@link NetworkInfo.State#SUSPENDED} state. This should always be
2849         * preceded by a matching {@link NetworkCallback#onNetworkSuspended} call.
2850         * @hide
2851         */
2852        public void onNetworkResumed(Network network) {}
2853
2854        private NetworkRequest networkRequest;
2855    }
2856
2857    /**
2858     * Constant error codes used by ConnectivityService to communicate about failures and errors
2859     * across a Binder boundary.
2860     * @hide
2861     */
2862    public interface Errors {
2863        static int TOO_MANY_REQUESTS = 1;
2864    }
2865
2866    /** @hide */
2867    public static class TooManyRequestsException extends RuntimeException {}
2868
2869    private static RuntimeException convertServiceException(ServiceSpecificException e) {
2870        switch (e.errorCode) {
2871            case Errors.TOO_MANY_REQUESTS:
2872                return new TooManyRequestsException();
2873            default:
2874                Log.w(TAG, "Unknown service error code " + e.errorCode);
2875                return new RuntimeException(e);
2876        }
2877    }
2878
2879    private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER;
2880    /** @hide */
2881    public static final int CALLBACK_PRECHECK            = BASE + 1;
2882    /** @hide */
2883    public static final int CALLBACK_AVAILABLE           = BASE + 2;
2884    /** @hide arg1 = TTL */
2885    public static final int CALLBACK_LOSING              = BASE + 3;
2886    /** @hide */
2887    public static final int CALLBACK_LOST                = BASE + 4;
2888    /** @hide */
2889    public static final int CALLBACK_UNAVAIL             = BASE + 5;
2890    /** @hide */
2891    public static final int CALLBACK_CAP_CHANGED         = BASE + 6;
2892    /** @hide */
2893    public static final int CALLBACK_IP_CHANGED          = BASE + 7;
2894    /** @hide obj = NetworkCapabilities, arg1 = seq number */
2895    private static final int EXPIRE_LEGACY_REQUEST       = BASE + 8;
2896    /** @hide */
2897    public static final int CALLBACK_SUSPENDED           = BASE + 9;
2898    /** @hide */
2899    public static final int CALLBACK_RESUMED             = BASE + 10;
2900
2901    /** @hide */
2902    public static String getCallbackName(int whichCallback) {
2903        switch (whichCallback) {
2904            case CALLBACK_PRECHECK:     return "CALLBACK_PRECHECK";
2905            case CALLBACK_AVAILABLE:    return "CALLBACK_AVAILABLE";
2906            case CALLBACK_LOSING:       return "CALLBACK_LOSING";
2907            case CALLBACK_LOST:         return "CALLBACK_LOST";
2908            case CALLBACK_UNAVAIL:      return "CALLBACK_UNAVAIL";
2909            case CALLBACK_CAP_CHANGED:  return "CALLBACK_CAP_CHANGED";
2910            case CALLBACK_IP_CHANGED:   return "CALLBACK_IP_CHANGED";
2911            case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST";
2912            case CALLBACK_SUSPENDED:    return "CALLBACK_SUSPENDED";
2913            case CALLBACK_RESUMED:      return "CALLBACK_RESUMED";
2914            default:
2915                return Integer.toString(whichCallback);
2916        }
2917    }
2918
2919    private class CallbackHandler extends Handler {
2920        private static final String TAG = "ConnectivityManager.CallbackHandler";
2921        private static final boolean DBG = false;
2922
2923        CallbackHandler(Looper looper) {
2924            super(looper);
2925        }
2926
2927        CallbackHandler(Handler handler) {
2928            this(Preconditions.checkNotNull(handler, "Handler cannot be null.").getLooper());
2929        }
2930
2931        @Override
2932        public void handleMessage(Message message) {
2933            if (message.what == EXPIRE_LEGACY_REQUEST) {
2934                expireRequest((NetworkCapabilities) message.obj, message.arg1);
2935                return;
2936            }
2937
2938            final NetworkRequest request = getObject(message, NetworkRequest.class);
2939            final Network network = getObject(message, Network.class);
2940            final NetworkCallback callback;
2941            synchronized (sCallbacks) {
2942                callback = sCallbacks.get(request);
2943            }
2944            if (DBG) {
2945                Log.d(TAG, getCallbackName(message.what) + " for network " + network);
2946            }
2947            if (callback == null) {
2948                Log.w(TAG, "callback not found for " + getCallbackName(message.what) + " message");
2949                return;
2950            }
2951
2952            switch (message.what) {
2953                case CALLBACK_PRECHECK: {
2954                    callback.onPreCheck(network);
2955                    break;
2956                }
2957                case CALLBACK_AVAILABLE: {
2958                    NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
2959                    LinkProperties lp = getObject(message, LinkProperties.class);
2960                    callback.onAvailable(network, cap, lp);
2961                    break;
2962                }
2963                case CALLBACK_LOSING: {
2964                    callback.onLosing(network, message.arg1);
2965                    break;
2966                }
2967                case CALLBACK_LOST: {
2968                    callback.onLost(network);
2969                    break;
2970                }
2971                case CALLBACK_UNAVAIL: {
2972                    callback.onUnavailable();
2973                    break;
2974                }
2975                case CALLBACK_CAP_CHANGED: {
2976                    NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
2977                    callback.onCapabilitiesChanged(network, cap);
2978                    break;
2979                }
2980                case CALLBACK_IP_CHANGED: {
2981                    LinkProperties lp = getObject(message, LinkProperties.class);
2982                    callback.onLinkPropertiesChanged(network, lp);
2983                    break;
2984                }
2985                case CALLBACK_SUSPENDED: {
2986                    callback.onNetworkSuspended(network);
2987                    break;
2988                }
2989                case CALLBACK_RESUMED: {
2990                    callback.onNetworkResumed(network);
2991                    break;
2992                }
2993            }
2994        }
2995
2996        private <T> T getObject(Message msg, Class<T> c) {
2997            return (T) msg.getData().getParcelable(c.getSimpleName());
2998        }
2999    }
3000
3001    private CallbackHandler getDefaultHandler() {
3002        synchronized (sCallbacks) {
3003            if (sCallbackHandler == null) {
3004                sCallbackHandler = new CallbackHandler(ConnectivityThread.getInstanceLooper());
3005            }
3006            return sCallbackHandler;
3007        }
3008    }
3009
3010    private static final HashMap<NetworkRequest, NetworkCallback> sCallbacks = new HashMap<>();
3011    private static CallbackHandler sCallbackHandler;
3012
3013    private static final int LISTEN  = 1;
3014    private static final int REQUEST = 2;
3015
3016    private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, NetworkCallback callback,
3017            int timeoutMs, int action, int legacyType, CallbackHandler handler) {
3018        checkCallbackNotNull(callback);
3019        Preconditions.checkArgument(action == REQUEST || need != null, "null NetworkCapabilities");
3020        final NetworkRequest request;
3021        try {
3022            synchronized(sCallbacks) {
3023                if (callback.networkRequest != null
3024                        && callback.networkRequest != ALREADY_UNREGISTERED) {
3025                    // TODO: throw exception instead and enforce 1:1 mapping of callbacks
3026                    // and requests (http://b/20701525).
3027                    Log.e(TAG, "NetworkCallback was already registered");
3028                }
3029                Messenger messenger = new Messenger(handler);
3030                Binder binder = new Binder();
3031                if (action == LISTEN) {
3032                    request = mService.listenForNetwork(need, messenger, binder);
3033                } else {
3034                    request = mService.requestNetwork(
3035                            need, messenger, timeoutMs, binder, legacyType);
3036                }
3037                if (request != null) {
3038                    sCallbacks.put(request, callback);
3039                }
3040                callback.networkRequest = request;
3041            }
3042        } catch (RemoteException e) {
3043            throw e.rethrowFromSystemServer();
3044        } catch (ServiceSpecificException e) {
3045            throw convertServiceException(e);
3046        }
3047        return request;
3048    }
3049
3050    /**
3051     * Helper function to request a network with a particular legacy type.
3052     *
3053     * This is temporarily public @hide so it can be called by system code that uses the
3054     * NetworkRequest API to request networks but relies on CONNECTIVITY_ACTION broadcasts for
3055     * instead network notifications.
3056     *
3057     * TODO: update said system code to rely on NetworkCallbacks and make this method private.
3058     *
3059     * @hide
3060     */
3061    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
3062            int timeoutMs, int legacyType, Handler handler) {
3063        CallbackHandler cbHandler = new CallbackHandler(handler);
3064        NetworkCapabilities nc = request.networkCapabilities;
3065        sendRequestForNetwork(nc, networkCallback, timeoutMs, REQUEST, legacyType, cbHandler);
3066    }
3067
3068    /**
3069     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
3070     *
3071     * This {@link NetworkRequest} will live until released via
3072     * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits. A
3073     * version of the method which takes a timeout is
3074     * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)}.
3075     * Status of the request can be followed by listening to the various
3076     * callbacks described in {@link NetworkCallback}.  The {@link Network}
3077     * can be used to direct traffic to the network.
3078     * <p>It is presently unsupported to request a network with mutable
3079     * {@link NetworkCapabilities} such as
3080     * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
3081     * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
3082     * as these {@code NetworkCapabilities} represent states that a particular
3083     * network may never attain, and whether a network will attain these states
3084     * is unknown prior to bringing up the network so the framework does not
3085     * know how to go about satisfing a request with these capabilities.
3086     *
3087     * <p>This method requires the caller to hold either the
3088     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
3089     * or the ability to modify system settings as determined by
3090     * {@link android.provider.Settings.System#canWrite}.</p>
3091     *
3092     * @param request {@link NetworkRequest} describing this request.
3093     * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
3094     *                        the callback must not be shared - it uniquely specifies this request.
3095     *                        The callback is invoked on the default internal Handler.
3096     * @throws IllegalArgumentException if {@code request} specifies any mutable
3097     *         {@code NetworkCapabilities}.
3098     */
3099    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) {
3100        requestNetwork(request, networkCallback, getDefaultHandler());
3101    }
3102
3103    /**
3104     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
3105     *
3106     * This {@link NetworkRequest} will live until released via
3107     * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits. A
3108     * version of the method which takes a timeout is
3109     * {@link #requestNetwork(NetworkRequest, NetworkCallback, int)}.
3110     * Status of the request can be followed by listening to the various
3111     * callbacks described in {@link NetworkCallback}.  The {@link Network}
3112     * can be used to direct traffic to the network.
3113     * <p>It is presently unsupported to request a network with mutable
3114     * {@link NetworkCapabilities} such as
3115     * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
3116     * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
3117     * as these {@code NetworkCapabilities} represent states that a particular
3118     * network may never attain, and whether a network will attain these states
3119     * is unknown prior to bringing up the network so the framework does not
3120     * know how to go about satisfing a request with these capabilities.
3121     *
3122     * <p>This method requires the caller to hold either the
3123     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
3124     * or the ability to modify system settings as determined by
3125     * {@link android.provider.Settings.System#canWrite}.</p>
3126     *
3127     * @param request {@link NetworkRequest} describing this request.
3128     * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
3129     *                        the callback must not be shared - it uniquely specifies this request.
3130     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
3131     * @throws IllegalArgumentException if {@code request} specifies any mutable
3132     *         {@code NetworkCapabilities}.
3133     */
3134    public void requestNetwork(
3135            NetworkRequest request, NetworkCallback networkCallback, Handler handler) {
3136        int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
3137        CallbackHandler cbHandler = new CallbackHandler(handler);
3138        requestNetwork(request, networkCallback, 0, legacyType, cbHandler);
3139    }
3140
3141    /**
3142     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
3143     * by a timeout.
3144     *
3145     * This function behaves identically to the non-timed-out version
3146     * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, but if a suitable network
3147     * is not found within the given time (in milliseconds) the
3148     * {@link NetworkCallback#onUnavailable()} callback is called. The request can still be
3149     * released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)} but does
3150     * not have to be released if timed-out (it is automatically released). Unregistering a
3151     * request that timed out is not an error.
3152     *
3153     * <p>Do not use this method to poll for the existence of specific networks (e.g. with a small
3154     * timeout) - {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} is provided
3155     * for that purpose. Calling this method will attempt to bring up the requested network.
3156     *
3157     * <p>This method requires the caller to hold either the
3158     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
3159     * or the ability to modify system settings as determined by
3160     * {@link android.provider.Settings.System#canWrite}.</p>
3161     *
3162     * @param request {@link NetworkRequest} describing this request.
3163     * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
3164     *                        the callback must not be shared - it uniquely specifies this request.
3165     * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
3166     *                  before {@link NetworkCallback#onUnavailable()} is called. The timeout must
3167     *                  be a positive value (i.e. >0).
3168     */
3169    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
3170            int timeoutMs) {
3171        checkTimeout(timeoutMs);
3172        int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
3173        requestNetwork(request, networkCallback, timeoutMs, legacyType, getDefaultHandler());
3174    }
3175
3176    /**
3177     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
3178     * by a timeout.
3179     *
3180     * This function behaves identically to the non-timedout version, but if a suitable
3181     * network is not found within the given time (in milliseconds) the
3182     * {@link NetworkCallback#onUnavailable} callback is called. The request can still be
3183     * released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)} but does
3184     * not have to be released if timed-out (it is automatically released). Unregistering a
3185     * request that timed out is not an error.
3186     *
3187     * <p>Do not use this method to poll for the existence of specific networks (e.g. with a small
3188     * timeout) - {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} is provided
3189     * for that purpose. Calling this method will attempt to bring up the requested network.
3190     *
3191     * <p>This method requires the caller to hold either the
3192     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
3193     * or the ability to modify system settings as determined by
3194     * {@link android.provider.Settings.System#canWrite}.</p>
3195     *
3196     * @param request {@link NetworkRequest} describing this request.
3197     * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
3198     *                        the callback must not be shared - it uniquely specifies this request.
3199     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
3200     * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
3201     *                  before {@link NetworkCallback#onUnavailable} is called.
3202     */
3203    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
3204            Handler handler, int timeoutMs) {
3205        checkTimeout(timeoutMs);
3206        int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
3207        CallbackHandler cbHandler = new CallbackHandler(handler);
3208        requestNetwork(request, networkCallback, timeoutMs, legacyType, cbHandler);
3209    }
3210
3211    /**
3212     * The lookup key for a {@link Network} object included with the intent after
3213     * successfully finding a network for the applications request.  Retrieve it with
3214     * {@link android.content.Intent#getParcelableExtra(String)}.
3215     * <p>
3216     * Note that if you intend to invoke {@link Network#openConnection(java.net.URL)}
3217     * then you must get a ConnectivityManager instance before doing so.
3218     */
3219    public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
3220
3221    /**
3222     * The lookup key for a {@link NetworkRequest} object included with the intent after
3223     * successfully finding a network for the applications request.  Retrieve it with
3224     * {@link android.content.Intent#getParcelableExtra(String)}.
3225     */
3226    public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
3227
3228
3229    /**
3230     * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
3231     *
3232     * This function behaves identically to the version that takes a NetworkCallback, but instead
3233     * of {@link NetworkCallback} a {@link PendingIntent} is used.  This means
3234     * the request may outlive the calling application and get called back when a suitable
3235     * network is found.
3236     * <p>
3237     * The operation is an Intent broadcast that goes to a broadcast receiver that
3238     * you registered with {@link Context#registerReceiver} or through the
3239     * &lt;receiver&gt; tag in an AndroidManifest.xml file
3240     * <p>
3241     * The operation Intent is delivered with two extras, a {@link Network} typed
3242     * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest}
3243     * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing
3244     * the original requests parameters.  It is important to create a new,
3245     * {@link NetworkCallback} based request before completing the processing of the
3246     * Intent to reserve the network or it will be released shortly after the Intent
3247     * is processed.
3248     * <p>
3249     * If there is already a request for this Intent registered (with the equality of
3250     * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
3251     * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
3252     * <p>
3253     * The request may be released normally by calling
3254     * {@link #releaseNetworkRequest(android.app.PendingIntent)}.
3255     * <p>It is presently unsupported to request a network with either
3256     * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
3257     * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}
3258     * as these {@code NetworkCapabilities} represent states that a particular
3259     * network may never attain, and whether a network will attain these states
3260     * is unknown prior to bringing up the network so the framework does not
3261     * know how to go about satisfing a request with these capabilities.
3262     *
3263     * <p>This method requires the caller to hold either the
3264     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
3265     * or the ability to modify system settings as determined by
3266     * {@link android.provider.Settings.System#canWrite}.</p>
3267     *
3268     * @param request {@link NetworkRequest} describing this request.
3269     * @param operation Action to perform when the network is available (corresponds
3270     *                  to the {@link NetworkCallback#onAvailable} call.  Typically
3271     *                  comes from {@link PendingIntent#getBroadcast}. Cannot be null.
3272     * @throws IllegalArgumentException if {@code request} contains either
3273     *         {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
3274     *         {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}.
3275     */
3276    public void requestNetwork(NetworkRequest request, PendingIntent operation) {
3277        checkPendingIntentNotNull(operation);
3278        try {
3279            mService.pendingRequestForNetwork(request.networkCapabilities, operation);
3280        } catch (RemoteException e) {
3281            throw e.rethrowFromSystemServer();
3282        } catch (ServiceSpecificException e) {
3283            throw convertServiceException(e);
3284        }
3285    }
3286
3287    /**
3288     * Removes a request made via {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)}
3289     * <p>
3290     * This method has the same behavior as
3291     * {@link #unregisterNetworkCallback(android.app.PendingIntent)} with respect to
3292     * releasing network resources and disconnecting.
3293     *
3294     * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the
3295     *                  PendingIntent passed to
3296     *                  {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)} with the
3297     *                  corresponding NetworkRequest you'd like to remove. Cannot be null.
3298     */
3299    public void releaseNetworkRequest(PendingIntent operation) {
3300        checkPendingIntentNotNull(operation);
3301        try {
3302            mService.releasePendingNetworkRequest(operation);
3303        } catch (RemoteException e) {
3304            throw e.rethrowFromSystemServer();
3305        }
3306    }
3307
3308    private static void checkPendingIntentNotNull(PendingIntent intent) {
3309        Preconditions.checkNotNull(intent, "PendingIntent cannot be null.");
3310    }
3311
3312    private static void checkCallbackNotNull(NetworkCallback callback) {
3313        Preconditions.checkNotNull(callback, "null NetworkCallback");
3314    }
3315
3316    private static void checkTimeout(int timeoutMs) {
3317        Preconditions.checkArgumentPositive(timeoutMs, "timeoutMs must be strictly positive.");
3318    }
3319
3320    /**
3321     * Registers to receive notifications about all networks which satisfy the given
3322     * {@link NetworkRequest}.  The callbacks will continue to be called until
3323     * either the application exits or link #unregisterNetworkCallback(NetworkCallback)} is called.
3324     *
3325     * @param request {@link NetworkRequest} describing this request.
3326     * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
3327     *                        networks change state.
3328     *                        The callback is invoked on the default internal Handler.
3329     */
3330    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
3331    public void registerNetworkCallback(NetworkRequest request, NetworkCallback networkCallback) {
3332        registerNetworkCallback(request, networkCallback, getDefaultHandler());
3333    }
3334
3335    /**
3336     * Registers to receive notifications about all networks which satisfy the given
3337     * {@link NetworkRequest}.  The callbacks will continue to be called until
3338     * either the application exits or link #unregisterNetworkCallback(NetworkCallback)} is called.
3339     *
3340     * @param request {@link NetworkRequest} describing this request.
3341     * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
3342     *                        networks change state.
3343     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
3344     */
3345    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
3346    public void registerNetworkCallback(
3347            NetworkRequest request, NetworkCallback networkCallback, Handler handler) {
3348        CallbackHandler cbHandler = new CallbackHandler(handler);
3349        NetworkCapabilities nc = request.networkCapabilities;
3350        sendRequestForNetwork(nc, networkCallback, 0, LISTEN, TYPE_NONE, cbHandler);
3351    }
3352
3353    /**
3354     * Registers a PendingIntent to be sent when a network is available which satisfies the given
3355     * {@link NetworkRequest}.
3356     *
3357     * This function behaves identically to the version that takes a NetworkCallback, but instead
3358     * of {@link NetworkCallback} a {@link PendingIntent} is used.  This means
3359     * the request may outlive the calling application and get called back when a suitable
3360     * network is found.
3361     * <p>
3362     * The operation is an Intent broadcast that goes to a broadcast receiver that
3363     * you registered with {@link Context#registerReceiver} or through the
3364     * &lt;receiver&gt; tag in an AndroidManifest.xml file
3365     * <p>
3366     * The operation Intent is delivered with two extras, a {@link Network} typed
3367     * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest}
3368     * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing
3369     * the original requests parameters.
3370     * <p>
3371     * If there is already a request for this Intent registered (with the equality of
3372     * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
3373     * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
3374     * <p>
3375     * The request may be released normally by calling
3376     * {@link #unregisterNetworkCallback(android.app.PendingIntent)}.
3377     * @param request {@link NetworkRequest} describing this request.
3378     * @param operation Action to perform when the network is available (corresponds
3379     *                  to the {@link NetworkCallback#onAvailable} call.  Typically
3380     *                  comes from {@link PendingIntent#getBroadcast}. Cannot be null.
3381     */
3382    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
3383    public void registerNetworkCallback(NetworkRequest request, PendingIntent operation) {
3384        checkPendingIntentNotNull(operation);
3385        try {
3386            mService.pendingListenForNetwork(request.networkCapabilities, operation);
3387        } catch (RemoteException e) {
3388            throw e.rethrowFromSystemServer();
3389        } catch (ServiceSpecificException e) {
3390            throw convertServiceException(e);
3391        }
3392    }
3393
3394    /**
3395     * Registers to receive notifications about changes in the system default network. The callbacks
3396     * will continue to be called until either the application exits or
3397     * {@link #unregisterNetworkCallback(NetworkCallback)} is called.
3398     *
3399     * @param networkCallback The {@link NetworkCallback} that the system will call as the
3400     *                        system default network changes.
3401     *                        The callback is invoked on the default internal Handler.
3402     */
3403    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
3404    public void registerDefaultNetworkCallback(NetworkCallback networkCallback) {
3405        registerDefaultNetworkCallback(networkCallback, getDefaultHandler());
3406    }
3407
3408    /**
3409     * Registers to receive notifications about changes in the system default network. The callbacks
3410     * will continue to be called until either the application exits or
3411     * {@link #unregisterNetworkCallback(NetworkCallback)} is called.
3412     *
3413     * @param networkCallback The {@link NetworkCallback} that the system will call as the
3414     *                        system default network changes.
3415     * @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
3416     */
3417    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
3418    public void registerDefaultNetworkCallback(NetworkCallback networkCallback, Handler handler) {
3419        // This works because if the NetworkCapabilities are null,
3420        // ConnectivityService takes them from the default request.
3421        //
3422        // Since the capabilities are exactly the same as the default request's
3423        // capabilities, this request is guaranteed, at all times, to be
3424        // satisfied by the same network, if any, that satisfies the default
3425        // request, i.e., the system default network.
3426        NetworkCapabilities nullCapabilities = null;
3427        CallbackHandler cbHandler = new CallbackHandler(handler);
3428        sendRequestForNetwork(nullCapabilities, networkCallback, 0, REQUEST, TYPE_NONE, cbHandler);
3429    }
3430
3431    /**
3432     * Requests bandwidth update for a given {@link Network} and returns whether the update request
3433     * is accepted by ConnectivityService. Once accepted, ConnectivityService will poll underlying
3434     * network connection for updated bandwidth information. The caller will be notified via
3435     * {@link ConnectivityManager.NetworkCallback} if there is an update. Notice that this
3436     * method assumes that the caller has previously called
3437     * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} to listen for network
3438     * changes.
3439     *
3440     * @param network {@link Network} specifying which network you're interested.
3441     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
3442     */
3443    public boolean requestBandwidthUpdate(Network network) {
3444        try {
3445            return mService.requestBandwidthUpdate(network);
3446        } catch (RemoteException e) {
3447            throw e.rethrowFromSystemServer();
3448        }
3449    }
3450
3451    /**
3452     * Unregisters a {@code NetworkCallback} and possibly releases networks originating from
3453     * {@link #requestNetwork(NetworkRequest, NetworkCallback)} and
3454     * {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} calls.
3455     * If the given {@code NetworkCallback} had previously been used with
3456     * {@code #requestNetwork}, any networks that had been connected to only to satisfy that request
3457     * will be disconnected.
3458     *
3459     * Notifications that would have triggered that {@code NetworkCallback} will immediately stop
3460     * triggering it as soon as this call returns.
3461     *
3462     * @param networkCallback The {@link NetworkCallback} used when making the request.
3463     */
3464    public void unregisterNetworkCallback(NetworkCallback networkCallback) {
3465        checkCallbackNotNull(networkCallback);
3466        final List<NetworkRequest> reqs = new ArrayList<>();
3467        // Find all requests associated to this callback and stop callback triggers immediately.
3468        // Callback is reusable immediately. http://b/20701525, http://b/35921499.
3469        synchronized (sCallbacks) {
3470            Preconditions.checkArgument(networkCallback.networkRequest != null,
3471                    "NetworkCallback was not registered");
3472            Preconditions.checkArgument(networkCallback.networkRequest != ALREADY_UNREGISTERED,
3473                    "NetworkCallback was already unregistered");
3474            for (Map.Entry<NetworkRequest, NetworkCallback> e : sCallbacks.entrySet()) {
3475                if (e.getValue() == networkCallback) {
3476                    reqs.add(e.getKey());
3477                }
3478            }
3479            // TODO: throw exception if callback was registered more than once (http://b/20701525).
3480            for (NetworkRequest r : reqs) {
3481                try {
3482                    mService.releaseNetworkRequest(r);
3483                } catch (RemoteException e) {
3484                    throw e.rethrowFromSystemServer();
3485                }
3486                // Only remove mapping if rpc was successful.
3487                sCallbacks.remove(r);
3488            }
3489            networkCallback.networkRequest = ALREADY_UNREGISTERED;
3490        }
3491    }
3492
3493    /**
3494     * Unregisters a callback previously registered via
3495     * {@link #registerNetworkCallback(NetworkRequest, android.app.PendingIntent)}.
3496     *
3497     * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the
3498     *                  PendingIntent passed to
3499     *                  {@link #registerNetworkCallback(NetworkRequest, android.app.PendingIntent)}.
3500     *                  Cannot be null.
3501     */
3502    public void unregisterNetworkCallback(PendingIntent operation) {
3503        checkPendingIntentNotNull(operation);
3504        releaseNetworkRequest(operation);
3505    }
3506
3507    /**
3508     * Informs the system whether it should switch to {@code network} regardless of whether it is
3509     * validated or not. If {@code accept} is true, and the network was explicitly selected by the
3510     * user (e.g., by selecting a Wi-Fi network in the Settings app), then the network will become
3511     * the system default network regardless of any other network that's currently connected. If
3512     * {@code always} is true, then the choice is remembered, so that the next time the user
3513     * connects to this network, the system will switch to it.
3514     *
3515     * @param network The network to accept.
3516     * @param accept Whether to accept the network even if unvalidated.
3517     * @param always Whether to remember this choice in the future.
3518     *
3519     * @hide
3520     */
3521    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
3522    public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {
3523        try {
3524            mService.setAcceptUnvalidated(network, accept, always);
3525        } catch (RemoteException e) {
3526            throw e.rethrowFromSystemServer();
3527        }
3528    }
3529
3530    /**
3531     * Informs the system to penalize {@code network}'s score when it becomes unvalidated. This is
3532     * only meaningful if the system is configured not to penalize such networks, e.g., if the
3533     * {@code config_networkAvoidBadWifi} configuration variable is set to 0 and the {@code
3534     * NETWORK_AVOID_BAD_WIFI setting is unset}.
3535     *
3536     * @param network The network to accept.
3537     *
3538     * @hide
3539     */
3540    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
3541    public void setAvoidUnvalidated(Network network) {
3542        try {
3543            mService.setAvoidUnvalidated(network);
3544        } catch (RemoteException e) {
3545            throw e.rethrowFromSystemServer();
3546        }
3547    }
3548
3549    /**
3550     * Requests that the system open the captive portal app on the specified network.
3551     *
3552     * @param network The network to log into.
3553     *
3554     * @hide
3555     */
3556    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
3557    public void startCaptivePortalApp(Network network) {
3558        try {
3559            mService.startCaptivePortalApp(network);
3560        } catch (RemoteException e) {
3561            throw e.rethrowFromSystemServer();
3562        }
3563    }
3564
3565    /**
3566     * It is acceptable to briefly use multipath data to provide seamless connectivity for
3567     * time-sensitive user-facing operations when the system default network is temporarily
3568     * unresponsive. The amount of data should be limited (less than one megabyte for every call to
3569     * this method), and the operation should be infrequent to ensure that data usage is limited.
3570     *
3571     * An example of such an operation might be a time-sensitive foreground activity, such as a
3572     * voice command, that the user is performing while walking out of range of a Wi-Fi network.
3573     */
3574    public static final int MULTIPATH_PREFERENCE_HANDOVER = 1 << 0;
3575
3576    /**
3577     * It is acceptable to use small amounts of multipath data on an ongoing basis to provide
3578     * a backup channel for traffic that is primarily going over another network.
3579     *
3580     * An example might be maintaining backup connections to peers or servers for the purpose of
3581     * fast fallback if the default network is temporarily unresponsive or disconnects. The traffic
3582     * on backup paths should be negligible compared to the traffic on the main path.
3583     */
3584    public static final int MULTIPATH_PREFERENCE_RELIABILITY = 1 << 1;
3585
3586    /**
3587     * It is acceptable to use metered data to improve network latency and performance.
3588     */
3589    public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 1 << 2;
3590
3591    /**
3592     * Return value to use for unmetered networks. On such networks we currently set all the flags
3593     * to true.
3594     * @hide
3595     */
3596    public static final int MULTIPATH_PREFERENCE_UNMETERED =
3597            MULTIPATH_PREFERENCE_HANDOVER |
3598            MULTIPATH_PREFERENCE_RELIABILITY |
3599            MULTIPATH_PREFERENCE_PERFORMANCE;
3600
3601    /** @hide */
3602    @Retention(RetentionPolicy.SOURCE)
3603    @IntDef(flag = true, value = {
3604            MULTIPATH_PREFERENCE_HANDOVER,
3605            MULTIPATH_PREFERENCE_RELIABILITY,
3606            MULTIPATH_PREFERENCE_PERFORMANCE,
3607    })
3608    public @interface MultipathPreference {
3609    }
3610
3611    /**
3612     * Provides a hint to the calling application on whether it is desirable to use the
3613     * multinetwork APIs (e.g., {@link Network#openConnection}, {@link Network#bindSocket}, etc.)
3614     * for multipath data transfer on this network when it is not the system default network.
3615     * Applications desiring to use multipath network protocols should call this method before
3616     * each such operation.
3617     *
3618     * @param network The network on which the application desires to use multipath data.
3619     *                If {@code null}, this method will return the a preference that will generally
3620     *                apply to metered networks.
3621     * @return a bitwise OR of zero or more of the  {@code MULTIPATH_PREFERENCE_*} constants.
3622     */
3623    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
3624    public @MultipathPreference int getMultipathPreference(Network network) {
3625        try {
3626            return mService.getMultipathPreference(network);
3627        } catch (RemoteException e) {
3628            throw e.rethrowFromSystemServer();
3629        }
3630    }
3631
3632    /**
3633     * Resets all connectivity manager settings back to factory defaults.
3634     * @hide
3635     */
3636    public void factoryReset() {
3637        try {
3638            mService.factoryReset();
3639        } catch (RemoteException e) {
3640            throw e.rethrowFromSystemServer();
3641        }
3642    }
3643
3644    /**
3645     * Binds the current process to {@code network}.  All Sockets created in the future
3646     * (and not explicitly bound via a bound SocketFactory from
3647     * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
3648     * {@code network}.  All host name resolutions will be limited to {@code network} as well.
3649     * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
3650     * work and all host name resolutions will fail.  This is by design so an application doesn't
3651     * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
3652     * To clear binding pass {@code null} for {@code network}.  Using individually bound
3653     * Sockets created by Network.getSocketFactory().createSocket() and
3654     * performing network-specific host name resolutions via
3655     * {@link Network#getAllByName Network.getAllByName} is preferred to calling
3656     * {@code bindProcessToNetwork}.
3657     *
3658     * @param network The {@link Network} to bind the current process to, or {@code null} to clear
3659     *                the current binding.
3660     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
3661     */
3662    public boolean bindProcessToNetwork(Network network) {
3663        // Forcing callers to call thru non-static function ensures ConnectivityManager
3664        // instantiated.
3665        return setProcessDefaultNetwork(network);
3666    }
3667
3668    /**
3669     * Binds the current process to {@code network}.  All Sockets created in the future
3670     * (and not explicitly bound via a bound SocketFactory from
3671     * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
3672     * {@code network}.  All host name resolutions will be limited to {@code network} as well.
3673     * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
3674     * work and all host name resolutions will fail.  This is by design so an application doesn't
3675     * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
3676     * To clear binding pass {@code null} for {@code network}.  Using individually bound
3677     * Sockets created by Network.getSocketFactory().createSocket() and
3678     * performing network-specific host name resolutions via
3679     * {@link Network#getAllByName Network.getAllByName} is preferred to calling
3680     * {@code setProcessDefaultNetwork}.
3681     *
3682     * @param network The {@link Network} to bind the current process to, or {@code null} to clear
3683     *                the current binding.
3684     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
3685     * @deprecated This function can throw {@link IllegalStateException}.  Use
3686     *             {@link #bindProcessToNetwork} instead.  {@code bindProcessToNetwork}
3687     *             is a direct replacement.
3688     */
3689    @Deprecated
3690    public static boolean setProcessDefaultNetwork(Network network) {
3691        int netId = (network == null) ? NETID_UNSET : network.netId;
3692        if (netId == NetworkUtils.getBoundNetworkForProcess()) {
3693            return true;
3694        }
3695        if (NetworkUtils.bindProcessToNetwork(netId)) {
3696            // Set HTTP proxy system properties to match network.
3697            // TODO: Deprecate this static method and replace it with a non-static version.
3698            try {
3699                Proxy.setHttpProxySystemProperty(getInstance().getDefaultProxy());
3700            } catch (SecurityException e) {
3701                // The process doesn't have ACCESS_NETWORK_STATE, so we can't fetch the proxy.
3702                Log.e(TAG, "Can't set proxy properties", e);
3703            }
3704            // Must flush DNS cache as new network may have different DNS resolutions.
3705            InetAddress.clearDnsCache();
3706            // Must flush socket pool as idle sockets will be bound to previous network and may
3707            // cause subsequent fetches to be performed on old network.
3708            NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
3709            return true;
3710        } else {
3711            return false;
3712        }
3713    }
3714
3715    /**
3716     * Returns the {@link Network} currently bound to this process via
3717     * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
3718     *
3719     * @return {@code Network} to which this process is bound, or {@code null}.
3720     */
3721    public Network getBoundNetworkForProcess() {
3722        // Forcing callers to call thru non-static function ensures ConnectivityManager
3723        // instantiated.
3724        return getProcessDefaultNetwork();
3725    }
3726
3727    /**
3728     * Returns the {@link Network} currently bound to this process via
3729     * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
3730     *
3731     * @return {@code Network} to which this process is bound, or {@code null}.
3732     * @deprecated Using this function can lead to other functions throwing
3733     *             {@link IllegalStateException}.  Use {@link #getBoundNetworkForProcess} instead.
3734     *             {@code getBoundNetworkForProcess} is a direct replacement.
3735     */
3736    @Deprecated
3737    public static Network getProcessDefaultNetwork() {
3738        int netId = NetworkUtils.getBoundNetworkForProcess();
3739        if (netId == NETID_UNSET) return null;
3740        return new Network(netId);
3741    }
3742
3743    private void unsupportedStartingFrom(int version) {
3744        if (Process.myUid() == Process.SYSTEM_UID) {
3745            // The getApplicationInfo() call we make below is not supported in system context, and
3746            // we want to allow the system to use these APIs anyway.
3747            return;
3748        }
3749
3750        if (mContext.getApplicationInfo().targetSdkVersion >= version) {
3751            throw new UnsupportedOperationException(
3752                    "This method is not supported in target SDK version " + version + " and above");
3753        }
3754    }
3755
3756    // Checks whether the calling app can use the legacy routing API (startUsingNetworkFeature,
3757    // stopUsingNetworkFeature, requestRouteToHost), and if not throw UnsupportedOperationException.
3758    // TODO: convert the existing system users (Tethering, GnssLocationProvider) to the new APIs and
3759    // remove these exemptions. Note that this check is not secure, and apps can still access these
3760    // functions by accessing ConnectivityService directly. However, it should be clear that doing
3761    // so is unsupported and may break in the future. http://b/22728205
3762    private void checkLegacyRoutingApiAccess() {
3763        if (mContext.checkCallingOrSelfPermission("com.android.permission.INJECT_OMADM_SETTINGS")
3764                == PackageManager.PERMISSION_GRANTED) {
3765            return;
3766        }
3767
3768        unsupportedStartingFrom(VERSION_CODES.M);
3769    }
3770
3771    /**
3772     * Binds host resolutions performed by this process to {@code network}.
3773     * {@link #bindProcessToNetwork} takes precedence over this setting.
3774     *
3775     * @param network The {@link Network} to bind host resolutions from the current process to, or
3776     *                {@code null} to clear the current binding.
3777     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
3778     * @hide
3779     * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}.
3780     */
3781    @Deprecated
3782    public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
3783        return NetworkUtils.bindProcessToNetworkForHostResolution(
3784                network == null ? NETID_UNSET : network.netId);
3785    }
3786
3787    /**
3788     * Device is not restricting metered network activity while application is running on
3789     * background.
3790     */
3791    public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1;
3792
3793    /**
3794     * Device is restricting metered network activity while application is running on background,
3795     * but application is allowed to bypass it.
3796     * <p>
3797     * In this state, application should take action to mitigate metered network access.
3798     * For example, a music streaming application should switch to a low-bandwidth bitrate.
3799     */
3800    public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2;
3801
3802    /**
3803     * Device is restricting metered network activity while application is running on background.
3804     * <p>
3805     * In this state, application should not try to use the network while running on background,
3806     * because it would be denied.
3807     */
3808    public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3;
3809
3810    /**
3811     * A change in the background metered network activity restriction has occurred.
3812     * <p>
3813     * Applications should call {@link #getRestrictBackgroundStatus()} to check if the restriction
3814     * applies to them.
3815     * <p>
3816     * This is only sent to registered receivers, not manifest receivers.
3817     */
3818    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
3819    public static final String ACTION_RESTRICT_BACKGROUND_CHANGED =
3820            "android.net.conn.RESTRICT_BACKGROUND_CHANGED";
3821
3822    /** @hide */
3823    @Retention(RetentionPolicy.SOURCE)
3824    @IntDef(flag = false, value = {
3825            RESTRICT_BACKGROUND_STATUS_DISABLED,
3826            RESTRICT_BACKGROUND_STATUS_WHITELISTED,
3827            RESTRICT_BACKGROUND_STATUS_ENABLED,
3828    })
3829    public @interface RestrictBackgroundStatus {
3830    }
3831
3832    private INetworkPolicyManager getNetworkPolicyManager() {
3833        synchronized (this) {
3834            if (mNPManager != null) {
3835                return mNPManager;
3836            }
3837            mNPManager = INetworkPolicyManager.Stub.asInterface(ServiceManager
3838                    .getService(Context.NETWORK_POLICY_SERVICE));
3839            return mNPManager;
3840        }
3841    }
3842
3843    /**
3844     * Determines if the calling application is subject to metered network restrictions while
3845     * running on background.
3846     *
3847     * @return {@link #RESTRICT_BACKGROUND_STATUS_DISABLED},
3848     * {@link #RESTRICT_BACKGROUND_STATUS_ENABLED},
3849     * or {@link #RESTRICT_BACKGROUND_STATUS_WHITELISTED}
3850     */
3851    public @RestrictBackgroundStatus int getRestrictBackgroundStatus() {
3852        try {
3853            return getNetworkPolicyManager().getRestrictBackgroundByCaller();
3854        } catch (RemoteException e) {
3855            throw e.rethrowFromSystemServer();
3856        }
3857    }
3858
3859    /**
3860     * The network watchlist is a list of domains and IP addresses that are associated with
3861     * potentially harmful apps. This method returns the SHA-256 of the watchlist config file
3862     * currently used by the system for validation purposes.
3863     *
3864     * @return Hash of network watchlist config file. Null if config does not exist.
3865     */
3866    public byte[] getNetworkWatchlistConfigHash() {
3867        try {
3868            return mService.getNetworkWatchlistConfigHash();
3869        } catch (RemoteException e) {
3870            Log.e(TAG, "Unable to get watchlist config hash");
3871            throw e.rethrowFromSystemServer();
3872        }
3873    }
3874}
3875