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