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