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