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