OSDN Git Service

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