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