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