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