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