ConnectivityManager.java revision e0bef71662d81caaaa0d7214fb0bef5d39996a69
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright (C) 2008 The Android Open Source Project
38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Licensed under the Apache License, Version 2.0 (the "License");
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * you may not use this file except in compliance with the License.
68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * You may obtain a copy of the License at
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *      http://www.apache.org/licenses/LICENSE-2.0
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * Unless required by applicable law or agreed to in writing, software
11c12e1b138e736f70d698f14a3ffc74af6f3d8621tomhudson@google.com * distributed under the License is distributed on an "AS IS" BASIS,
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * See the License for the specific language governing permissions and
14d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips * limitations under the License.
15d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips */
16d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipspackage android.net;
17d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips
18d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport static com.android.internal.util.Preconditions.checkNotNull;
19d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillips
20d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.annotation.SdkConstant;
21d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.annotation.SdkConstant.SdkConstantType;
22d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.app.PendingIntent;
23d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.content.Context;
24d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.content.Intent;
25d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.net.NetworkUtils;
26d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.os.Binder;
27d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.os.Build.VERSION_CODES;
28d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.os.Bundle;
29d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.os.Handler;
30d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.os.HandlerThread;
31d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.os.IBinder;
32d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.os.INetworkActivityListener;
33d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.os.INetworkManagementService;
34d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.os.Looper;
35d537341e16524d1e22ac5e6c8b9c8f274ba1833crobertphillipsimport android.os.Message;
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comimport android.os.Messenger;
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comimport android.os.RemoteException;
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comimport android.os.ServiceManager;
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comimport android.provider.Settings;
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comimport android.telephony.TelephonyManager;
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comimport android.util.ArrayMap;
426f8f292aa768869a9e85c314b124875f57504f2creed@google.comimport android.util.Log;
43ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com
44ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.comimport com.android.internal.telephony.ITelephony;
45ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.comimport com.android.internal.telephony.PhoneConstants;
46ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.comimport com.android.internal.util.Protocol;
47ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comimport java.net.InetAddress;
496f8f292aa768869a9e85c314b124875f57504f2creed@google.comimport java.util.concurrent.atomic.AtomicInteger;
506f8f292aa768869a9e85c314b124875f57504f2creed@google.comimport java.util.HashMap;
516f8f292aa768869a9e85c314b124875f57504f2creed@google.com
526f8f292aa768869a9e85c314b124875f57504f2creed@google.comimport libcore.net.event.NetworkEventDispatcher;
536f8f292aa768869a9e85c314b124875f57504f2creed@google.com
546f8f292aa768869a9e85c314b124875f57504f2creed@google.com/**
556f8f292aa768869a9e85c314b124875f57504f2creed@google.com * Class that answers queries about the state of network connectivity. It also
566f8f292aa768869a9e85c314b124875f57504f2creed@google.com * notifies applications when network connectivity changes. Get an instance
576f8f292aa768869a9e85c314b124875f57504f2creed@google.com * of this class by calling
586f8f292aa768869a9e85c314b124875f57504f2creed@google.com * {@link android.content.Context#getSystemService(String) Context.getSystemService(Context.CONNECTIVITY_SERVICE)}.
596f8f292aa768869a9e85c314b124875f57504f2creed@google.com * <p>
606f8f292aa768869a9e85c314b124875f57504f2creed@google.com * The primary responsibilities of this class are to:
616f8f292aa768869a9e85c314b124875f57504f2creed@google.com * <ol>
626f8f292aa768869a9e85c314b124875f57504f2creed@google.com * <li>Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)</li>
636f8f292aa768869a9e85c314b124875f57504f2creed@google.com * <li>Send broadcast intents when network connectivity changes</li>
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * <li>Attempt to "fail over" to another network when connectivity to a network
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * is lost</li>
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * <li>Provide an API that allows applications to query the coarse-grained or fine-grained
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * state of the available networks</li>
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * <li>Provide an API that allows applications to request and select networks for their data
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * traffic</li>
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * </ol>
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic class ConnectivityManager {
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    private static final String TAG = "ConnectivityManager";
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * A change in network connectivity has occurred. A default connection has either
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * been established or lost. The NetworkInfo for the affected network is
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * sent as an extra; it should be consulted to see what kind of
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * connectivity event occurred.
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * <p/>
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * If this is a connection that was the result of failing over from a
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * disconnected network, then the FAILOVER_CONNECTION boolean extra is
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * set to true.
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * <p/>
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * For a loss of connectivity, if the connectivity manager is attempting
866f8f292aa768869a9e85c314b124875f57504f2creed@google.com     * to connect (or has already connected) to another network, the
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * NetworkInfo for the new network is also passed as an extra. This lets
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * any receivers of the broadcast know that they should not necessarily
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * tell the user that no data traffic will be possible. Instead, the
906f8f292aa768869a9e85c314b124875f57504f2creed@google.com     * receiver should expect another broadcast soon, indicating either that
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * the failover attempt succeeded (and so there is still overall data
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * connectivity), or that the failover attempt failed, meaning that all
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * connectivity has been lost.
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * <p/>
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * is set to {@code true} if there are no connected networks at all.
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * Identical to {@link #CONNECTIVITY_ACTION} broadcast, but sent without any
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * applicable {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY}.
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     *
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * @hide
1066f8f292aa768869a9e85c314b124875f57504f2creed@google.com     */
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String CONNECTIVITY_ACTION_IMMEDIATE =
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE";
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * The lookup key for a {@link NetworkInfo} object. Retrieve with
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * {@link android.content.Intent#getParcelableExtra(String)}.
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     *
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * @deprecated Since {@link NetworkInfo} can vary based on UID, applications
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     *             should always obtain network information through
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     *             {@link #getActiveNetworkInfo()} or
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     *             {@link #getAllNetworkInfo()}.
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * @see #EXTRA_NETWORK_TYPE
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
1216f8f292aa768869a9e85c314b124875f57504f2creed@google.com    @Deprecated
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String EXTRA_NETWORK_INFO = "networkInfo";
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * Network type which triggered a {@link #CONNECTIVITY_ACTION} broadcast.
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * Can be used with {@link #getNetworkInfo(int)} to get {@link NetworkInfo}
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * state based on the calling application.
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     *
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * @see android.content.Intent#getIntExtra(String, int)
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String EXTRA_NETWORK_TYPE = "networkType";
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * The lookup key for a boolean that indicates whether a connect event
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * is for a network to which the connectivity manager was failing over
1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * following a disconnect on another network.
1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String EXTRA_IS_FAILOVER = "isFailover";
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * The lookup key for a {@link NetworkInfo} object. This is supplied when
1426f8f292aa768869a9e85c314b124875f57504f2creed@google.com     * there is another network that it may be possible to connect to. Retrieve with
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * {@link android.content.Intent#getParcelableExtra(String)}.
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * The lookup key for a boolean that indicates whether there is a
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * complete lack of connectivity, i.e., no network is available.
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * The lookup key for a string that indicates why an attempt to connect
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * to a network failed. The string has no particular structure. It is
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * intended to be used in notifications presented to users. Retrieve
1567ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.org     * it with {@link android.content.Intent#getStringExtra(String)}.
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String EXTRA_REASON = "reason";
159ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com    /**
160ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com     * The lookup key for a string that provides optionally supplied
161ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com     * extra information about the network state. The information
162ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com     * may be passed up from the lower networking layers, and its
163ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com     * meaning may be specific to a particular network type. Retrieve
1646f8f292aa768869a9e85c314b124875f57504f2creed@google.com     * it with {@link android.content.Intent#getStringExtra(String)}.
165b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org     */
166b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    public static final String EXTRA_EXTRA_INFO = "extraInfo";
167b7d956df4665e06f3ae98cb696cef7c04452ab8emike@reedtribe.org    /**
168398b1bcb7d30f9e55504b6de37d31ccc1a26c876mike@reedtribe.org     * The lookup key for an int that provides information about
169398b1bcb7d30f9e55504b6de37d31ccc1a26c876mike@reedtribe.org     * our connection to the internet at large.  0 indicates no connection,
170398b1bcb7d30f9e55504b6de37d31ccc1a26c876mike@reedtribe.org     * 100 indicates a great connection.  Retrieve it with
171398b1bcb7d30f9e55504b6de37d31ccc1a26c876mike@reedtribe.org     * {@link android.content.Intent#getIntExtra(String, int)}.
172398b1bcb7d30f9e55504b6de37d31ccc1a26c876mike@reedtribe.org     * {@hide}
1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String EXTRA_INET_CONDITION = "inetCondition";
1756f8f292aa768869a9e85c314b124875f57504f2creed@google.com
1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * Broadcast action to indicate the change of data activity status
1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * (idle or active) on a network in a recent period.
1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * The network becomes active when data transmission is started, or
1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * idle if there is no data transmission for a period of time.
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * {@hide}
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
1836f8f292aa768869a9e85c314b124875f57504f2creed@google.com    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String ACTION_DATA_ACTIVITY_CHANGE = "android.net.conn.DATA_ACTIVITY_CHANGE";
1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * The lookup key for an enum that indicates the network device type on which this data activity
1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * change happens.
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * {@hide}
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String EXTRA_DEVICE_TYPE = "deviceType";
1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
1927744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * The lookup key for a boolean that indicates the device is active or not. {@code true} means
1937744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * it is actively sending or receiving data and {@code false} means it is idle.
1947744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * {@hide}
1957744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     */
196fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    public static final String EXTRA_IS_ACTIVE = "isActive";
1977744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com    /**
1987744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * The lookup key for a long that contains the timestamp (nanos) of the radio state change.
1997744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * {@hide}
2007744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     */
2017744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com    public static final String EXTRA_REALTIME_NS = "tsNanos";
2027744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com
2037744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com    /**
2047744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * Broadcast Action: The setting for background data usage has changed
2057744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * values. Use {@link #getBackgroundDataSetting()} to get the current value.
2067744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * <p>
2077744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * If an application uses the network in the background, it should listen
2087744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * for this broadcast and stop using the background data if the value is
2097744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * {@code false}.
2107744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * <p>
2117744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     *
2127744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability
2137744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     *             of background data depends on several combined factors, and
2147744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     *             this broadcast is no longer sent. Instead, when background
2157744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     *             data is unavailable, {@link #getActiveNetworkInfo()} will now
2167744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     *             appear disconnected. During first boot after a platform
217dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com     *             upgrade, this broadcast will be sent once if
218dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com     *             {@link #getBackgroundDataSetting()} was {@code false} before
219dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com     *             the upgrade.
220dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com     */
221dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
222dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com    @Deprecated
223dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com    public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED =
224dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com            "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
225dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com
226dbeeac33329f5fd7dbd3514cd7189ca6ed080476bsalomon@google.com    /**
2277744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * Broadcast Action: The network connection may not be good
2287744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * uses {@code ConnectivityManager.EXTRA_INET_CONDITION} and
2297744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * {@code ConnectivityManager.EXTRA_NETWORK_INFO} to specify
2307744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * the network and it's condition.
2317744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * @hide
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String INET_CONDITION_ACTION =
2357744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com            "android.net.conn.INET_CONDITION_ACTION";
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
23755b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    /**
23855b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com     * Broadcast Action: A tetherable connection has come or gone.
23955b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com     * Uses {@code ConnectivityManager.EXTRA_AVAILABLE_TETHER},
24055b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com     * {@code ConnectivityManager.EXTRA_ACTIVE_TETHER} and
24111e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org     * {@code ConnectivityManager.EXTRA_ERRORED_TETHER} to indicate
24211e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org     * the current state of tethering.  Each include a list of
24311e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org     * interface names in that state (may be empty).
24411e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org     * @hide
24555b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com     */
24655b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
24755b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com    public static final String ACTION_TETHER_STATE_CHANGED =
24855b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com            "android.net.conn.TETHER_STATE_CHANGED";
24955b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
2511fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com     * @hide
2521fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com     * gives a String[] listing all the interfaces configured for
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * tethering and currently available for tethering.
2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
2556f8f292aa768869a9e85c314b124875f57504f2creed@google.com    public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * @hide
2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * gives a String[] listing all the interfaces currently tethered
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * (ie, has dhcp support and packets potentially forwarded/NATed)
2616f8f292aa768869a9e85c314b124875f57504f2creed@google.com     */
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String EXTRA_ACTIVE_TETHER = "activeArray";
2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * @hide
2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * gives a String[] listing all the interfaces we tried to tether and
2676f8f292aa768869a9e85c314b124875f57504f2creed@google.com     * failed.  Use {@link #getLastTetherError} to find the error code
2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * for any interfaces listed here.
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final String EXTRA_ERRORED_TETHER = "erroredArray";
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * Broadcast Action: The captive portal tracker has finished its test.
27411e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org     * Sent only while running Setup Wizard, in lieu of showing a user
27511e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org     * notification.
27611e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org     * @hide
27711e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org     */
27811e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
27911e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org    public static final String ACTION_CAPTIVE_PORTAL_TEST_COMPLETED =
28011e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org            "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED";
28111e5b972a984c7b4e09ba4dfeacc7bd805107c5acommit-bot@chromium.org    /**
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * The lookup key for a boolean that indicates whether a captive portal was detected.
2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * @hide
2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
2866f8f292aa768869a9e85c314b124875f57504f2creed@google.com    public static final String EXTRA_IS_CAPTIVE_PORTAL = "captivePortal";
2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * The absence of a connection type.
290fc25abdabff76f913fb9d4f373418c10a1eca92breed@android.com     * @hide
2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int TYPE_NONE        = -1;
2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * The Mobile data connection.  When active, all data traffic
2966f8f292aa768869a9e85c314b124875f57504f2creed@google.com     * will use this network type's interface by default
2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * (it has a default route)
2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int TYPE_MOBILE      = 0;
3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
3016f8f292aa768869a9e85c314b124875f57504f2creed@google.com     * The WIFI data connection.  When active, all data traffic
3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * will use this network type's interface by default
3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * (it has a default route).
3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int TYPE_WIFI        = 1;
3066f8f292aa768869a9e85c314b124875f57504f2creed@google.com    /**
3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * An MMS-specific Mobile data connection.  This network type may use the
3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * same network interface as {@link #TYPE_MOBILE} or it may use a different
3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * one.  This is used by applications needing to talk to the carrier's
3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * Multimedia Messaging Service servers.
3116f8f292aa768869a9e85c314b124875f57504f2creed@google.com     */
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int TYPE_MOBILE_MMS  = 2;
3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * A SUPL-specific Mobile data connection.  This network type may use the
3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * same network interface as {@link #TYPE_MOBILE} or it may use a different
3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * one.  This is used by applications needing to talk to the carrier's
3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * Secure User Plane Location servers for help locating the device.
3186f8f292aa768869a9e85c314b124875f57504f2creed@google.com     */
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int TYPE_MOBILE_SUPL = 3;
3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * A DUN-specific Mobile data connection.  This network type may use the
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * same network interface as {@link #TYPE_MOBILE} or it may use a different
3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * one.  This is sometimes by the system when setting up an upstream connection
3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * for tethering so that the carrier is aware of DUN traffic.
3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int TYPE_MOBILE_DUN  = 4;
3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * A High Priority Mobile data connection.  This network type uses the
3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * same network interface as {@link #TYPE_MOBILE} but the routing setup
3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * is different.  Only requesting processes will have access to the
3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * Mobile DNS servers and only IP's explicitly requested via {@link #requestRouteToHost}
3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * will route over this interface if no default route exists.
3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
3346f8f292aa768869a9e85c314b124875f57504f2creed@google.com    public static final int TYPE_MOBILE_HIPRI = 5;
3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * The WiMAX data connection.  When active, all data traffic
3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * will use this network type's interface by default
3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * (it has a default route).
3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int TYPE_WIMAX       = 6;
3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3420bb18bb264b26afca45452910437c09445e23a3creed@google.com    /**
3430bb18bb264b26afca45452910437c09445e23a3creed@google.com     * The Bluetooth data connection.  When active, all data traffic
3440bb18bb264b26afca45452910437c09445e23a3creed@google.com     * will use this network type's interface by default
3450bb18bb264b26afca45452910437c09445e23a3creed@google.com     * (it has a default route).
3460bb18bb264b26afca45452910437c09445e23a3creed@google.com     */
3470bb18bb264b26afca45452910437c09445e23a3creed@google.com    public static final int TYPE_BLUETOOTH   = 7;
3480bb18bb264b26afca45452910437c09445e23a3creed@google.com
349fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    /**
3500bb18bb264b26afca45452910437c09445e23a3creed@google.com     * Dummy data connection.  This should not be used on shipping devices.
3510bb18bb264b26afca45452910437c09445e23a3creed@google.com     */
352fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    public static final int TYPE_DUMMY       = 8;
3530bb18bb264b26afca45452910437c09445e23a3creed@google.com
3540bb18bb264b26afca45452910437c09445e23a3creed@google.com    /**
3550bb18bb264b26afca45452910437c09445e23a3creed@google.com     * The Ethernet data connection.  When active, all data traffic
3560bb18bb264b26afca45452910437c09445e23a3creed@google.com     * will use this network type's interface by default
3570bb18bb264b26afca45452910437c09445e23a3creed@google.com     * (it has a default route).
35824d10cb635b002462dc503bf603d3ec487fcb557reed@google.com     */
35924d10cb635b002462dc503bf603d3ec487fcb557reed@google.com    public static final int TYPE_ETHERNET    = 9;
36024d10cb635b002462dc503bf603d3ec487fcb557reed@google.com
36124d10cb635b002462dc503bf603d3ec487fcb557reed@google.com    /**
36224d10cb635b002462dc503bf603d3ec487fcb557reed@google.com     * Over the air Administration.
36324d10cb635b002462dc503bf603d3ec487fcb557reed@google.com     * {@hide}
3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int TYPE_MOBILE_FOTA = 10;
3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
3686f8f292aa768869a9e85c314b124875f57504f2creed@google.com     * IP Multimedia Subsystem.
3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * {@hide}
3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int TYPE_MOBILE_IMS  = 11;
3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
37394fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com    /**
37494fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com     * Carrier Branded Services.
37594fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com     * {@hide}
3764469938e92d779dff05e745559e67907bbf21e78reed@google.com     */
37794fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com    public static final int TYPE_MOBILE_CBS  = 12;
37894fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com
37994fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com    /**
38094fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com     * A Wi-Fi p2p connection. Only requesting processes will have access to
3814da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org     * the peers connected.
38294fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com     * {@hide}
38394fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com     */
38494fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com    public static final int TYPE_WIFI_P2P    = 13;
38594fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com
3864469938e92d779dff05e745559e67907bbf21e78reed@google.com    /**
38794fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com     * The network to use for initially attaching to the network
38894fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com     * {@hide}
38994fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com     */
39094fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com    public static final int TYPE_MOBILE_IA = 14;
39194fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com
39294fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com/**
3934da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org     * Emergency PDN connection for emergency calls
3944da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org     * {@hide}
3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int TYPE_MOBILE_EMERGENCY = 15;
3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * The network that uses proxy to achieve connectivity.
4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * {@hide}
4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int TYPE_PROXY = 16;
4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * A virtual network using one or more native bearers.
4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * It may or may not be providing security services.
4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int TYPE_VPN = 17;
4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** {@hide} */
4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int MAX_RADIO_TYPE   = TYPE_VPN;
4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** {@hide} */
4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int MAX_NETWORK_TYPE = TYPE_VPN;
415ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com
416ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com    /**
41755b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com     * If you want to set the default network preference,you can directly
41855b5f4bd6a69e70feeaf6018171882ab9cd250aereed@google.com     * change the networkAttributes array in framework's config.xml.
4191fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com     *
4201fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com     * @deprecated Since we support so many more networks now, the single
4211fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com     *             network default network preference can't really express
4221fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com     *             the hierarchy.  Instead, the default is defined by the
4231fd56dc6e189ea0e94b5df9af959c243573f8883epoger@google.com     *             networkAttributes in config.xml.  You can determine
424ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com     *             the current value by calling {@link #getNetworkPreference()}
425ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com     *             from an App.
426ac753098e8af4a17e5df97b3a4dd0ce123f8d70creed@android.com     */
4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    @Deprecated
4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /**
4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * Default value for {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY} in
4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * milliseconds.  This was introduced because IPv6 routes seem to take a
4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * moment to settle - trying network activity before the routes are adjusted
4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * can lead to packets using the wrong interface or having the wrong IP address.
4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * This delay is a bit crude, but in the future hopefully we will have kernel
4361a5e51f94ed8cb01600184119e52bb64bdb3dcccreed@google.com     * notifications letting us know when it's safe to use the new network.
4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     *
4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * @hide
4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static final int CONNECTIVITY_CHANGE_DELAY_DEFAULT = 3000;
4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4421a5e51f94ed8cb01600184119e52bb64bdb3dcccreed@google.com    /**
4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     * @hide
4447744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     */
4457744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com    public final static int REQUEST_ID_UNSET = 0;
4467744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com
4477744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com    /**
4487744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * A NetID indicating no Network is selected.
4497744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * Keep in sync with bionic/libc/dns/include/resolv_netid.h
4507744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * @hide
4517744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     */
452fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    public static final int NETID_UNSET = 0;
4537744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com
4547744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com    private final IConnectivityManager mService;
4557744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com    /**
456fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com     * A kludge to facilitate static access where a Context pointer isn't available, like in the
4577744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * case of the static set/getProcessDefaultNetwork methods and from the Network class.
4587744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * TODO: Remove this after deprecating the static methods in favor of non-static methods or
4597744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com     * methods that take a Context argument.
4601a5e51f94ed8cb01600184119e52bb64bdb3dcccreed@google.com     */
4617744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com    private static ConnectivityManager sInstance;
462647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com
463647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com    private INetworkManagementService mNMService;
464647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com
465647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com    /**
466647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com     * Tests if a given integer represents a valid network type.
467647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com     * @param networkType the type to be tested
468647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com     * @return a boolean.  {@code true} if the type is valid, else {@code false}
469647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com     */
470647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com    public static boolean isNetworkTypeValid(int networkType) {
471647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com        return networkType >= 0 && networkType <= MAX_NETWORK_TYPE;
472647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com    }
473647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com
474647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com    /**
475647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com     * Returns a non-localized string representing a given network type.
476647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com     * ONLY used for debugging output.
477647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com     * @param type the type needing naming
478647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com     * @return a String for the given type, or a string version of the type ("87")
479647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com     * if no name is known.
480647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com     * {@hide}
481647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com     */
482647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com    public static String getNetworkTypeName(int type) {
483647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com        switch (type) {
484647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_MOBILE:
485647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com                return "MOBILE";
486647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_WIFI:
487647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com                return "WIFI";
488647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_MOBILE_MMS:
489647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com                return "MOBILE_MMS";
490647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_MOBILE_SUPL:
491647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com                return "MOBILE_SUPL";
492647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_MOBILE_DUN:
493647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com                return "MOBILE_DUN";
494647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_MOBILE_HIPRI:
495647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com                return "MOBILE_HIPRI";
496647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_WIMAX:
4977744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com                return "WIMAX";
498647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_BLUETOOTH:
499647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com                return "BLUETOOTH";
500647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_DUMMY:
501647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com                return "DUMMY";
502647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_ETHERNET:
5037744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com                return "ETHERNET";
5047744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com            case TYPE_MOBILE_FOTA:
5057744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com                return "MOBILE_FOTA";
506647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_MOBILE_IMS:
507647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com                return "MOBILE_IMS";
508647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_MOBILE_CBS:
509647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com                return "MOBILE_CBS";
510647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_WIFI_P2P:
511647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com                return "WIFI_P2P";
512647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_MOBILE_IA:
513647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com                return "MOBILE_IA";
514647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_MOBILE_EMERGENCY:
515278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com                return "MOBILE_EMERGENCY";
516647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            case TYPE_PROXY:
517647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com                return "PROXY";
518647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com            default:
519278dc6929b6481204874dcfcc055e2aaa30a95b2bsalomon@google.com                return Integer.toString(type);
520647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com        }
521647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com    }
522647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com
523647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com    /**
524c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com     * Checks if a given type uses the cellular data connection.
525c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com     * This should be replaced in the future by a network property.
526c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com     * @param networkType the type to check
527c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com     * @return a boolean - {@code true} if uses cellular network, else {@code false}
528c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com     * {@hide}
5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     */
5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public static boolean isNetworkTypeMobile(int networkType) {
5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        switch (networkType) {
5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case TYPE_MOBILE:
5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case TYPE_MOBILE_MMS:
534            case TYPE_MOBILE_SUPL:
535            case TYPE_MOBILE_DUN:
536            case TYPE_MOBILE_HIPRI:
537            case TYPE_MOBILE_FOTA:
538            case TYPE_MOBILE_IMS:
539            case TYPE_MOBILE_CBS:
540            case TYPE_MOBILE_IA:
541            case TYPE_MOBILE_EMERGENCY:
542                return true;
543            default:
544                return false;
545        }
546    }
547
548    /**
549     * Checks if the given network type is backed by a Wi-Fi radio.
550     *
551     * @hide
552     */
553    public static boolean isNetworkTypeWifi(int networkType) {
554        switch (networkType) {
555            case TYPE_WIFI:
556            case TYPE_WIFI_P2P:
557                return true;
558            default:
559                return false;
560        }
561    }
562
563    /**
564     * Specifies the preferred network type.  When the device has more
565     * than one type available the preferred network type will be used.
566     *
567     * @param preference the network type to prefer over all others.  It is
568     *         unspecified what happens to the old preferred network in the
569     *         overall ordering.
570     * @deprecated Functionality has been removed as it no longer makes sense,
571     *             with many more than two networks - we'd need an array to express
572     *             preference.  Instead we use dynamic network properties of
573     *             the networks to describe their precedence.
574     */
575    public void setNetworkPreference(int preference) {
576    }
577
578    /**
579     * Retrieves the current preferred network type.
580     *
581     * @return an integer representing the preferred network type
582     *
583     * <p>This method requires the caller to hold the permission
584     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
585     * @deprecated Functionality has been removed as it no longer makes sense,
586     *             with many more than two networks - we'd need an array to express
587     *             preference.  Instead we use dynamic network properties of
588     *             the networks to describe their precedence.
589     */
590    public int getNetworkPreference() {
591        return TYPE_NONE;
592    }
593
594    /**
595     * Returns details about the currently active default data network. When
596     * connected, this network is the default route for outgoing connections.
597     * You should always check {@link NetworkInfo#isConnected()} before initiating
598     * network traffic. This may return {@code null} when there is no default
599     * network.
600     *
601     * @return a {@link NetworkInfo} object for the current default network
602     *        or {@code null} if no network default network is currently active
603     *
604     * <p>This method requires the call to hold the permission
605     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
606     */
607    public NetworkInfo getActiveNetworkInfo() {
608        try {
609            return mService.getActiveNetworkInfo();
610        } catch (RemoteException e) {
611            return null;
612        }
613    }
614
615    /**
616     * Returns details about the currently active default data network
617     * for a given uid.  This is for internal use only to avoid spying
618     * other apps.
619     *
620     * @return a {@link NetworkInfo} object for the current default network
621     *        for the given uid or {@code null} if no default network is
622     *        available for the specified uid.
623     *
624     * <p>This method requires the caller to hold the permission
625     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}
626     * {@hide}
627     */
628    public NetworkInfo getActiveNetworkInfoForUid(int uid) {
629        try {
630            return mService.getActiveNetworkInfoForUid(uid);
631        } catch (RemoteException e) {
632            return null;
633        }
634    }
635
636    /**
637     * Returns connection status information about a particular
638     * network type.
639     *
640     * @param networkType integer specifying which networkType in
641     *        which you're interested.
642     * @return a {@link NetworkInfo} object for the requested
643     *        network type or {@code null} if the type is not
644     *        supported by the device.
645     *
646     * <p>This method requires the caller to hold the permission
647     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
648     */
649    public NetworkInfo getNetworkInfo(int networkType) {
650        try {
651            return mService.getNetworkInfo(networkType);
652        } catch (RemoteException e) {
653            return null;
654        }
655    }
656
657    /**
658     * Returns connection status information about a particular
659     * Network.
660     *
661     * @param network {@link Network} specifying which network
662     *        in which you're interested.
663     * @return a {@link NetworkInfo} object for the requested
664     *        network or {@code null} if the {@code Network}
665     *        is not valid.
666     *
667     * <p>This method requires the caller to hold the permission
668     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
669     */
670    public NetworkInfo getNetworkInfo(Network network) {
671        try {
672            return mService.getNetworkInfoForNetwork(network);
673        } catch (RemoteException e) {
674            return null;
675        }
676    }
677
678    /**
679     * Returns connection status information about all network
680     * types supported by the device.
681     *
682     * @return an array of {@link NetworkInfo} objects.  Check each
683     * {@link NetworkInfo#getType} for which type each applies.
684     *
685     * <p>This method requires the caller to hold the permission
686     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
687     */
688    public NetworkInfo[] getAllNetworkInfo() {
689        try {
690            return mService.getAllNetworkInfo();
691        } catch (RemoteException e) {
692            return null;
693        }
694    }
695
696    /**
697     * Returns the {@link Network} object currently serving a given type, or
698     * null if the given type is not connected.
699     *
700     * <p>This method requires the caller to hold the permission
701     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
702     *
703     * @hide
704     */
705    public Network getNetworkForType(int networkType) {
706        try {
707            return mService.getNetworkForType(networkType);
708        } catch (RemoteException e) {
709            return null;
710        }
711    }
712
713    /**
714     * Returns an array of all {@link Network} currently tracked by the
715     * framework.
716     *
717     * @return an array of {@link Network} objects.
718     *
719     * <p>This method requires the caller to hold the permission
720     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
721     */
722    public Network[] getAllNetworks() {
723        try {
724            return mService.getAllNetworks();
725        } catch (RemoteException e) {
726            return null;
727        }
728    }
729
730    /**
731     * Returns an array of of {@link NetworkCapabilities} objects, representing
732     * the Networks that applications run by the given user will use by default.
733     * @hide
734     */
735    public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
736        try {
737            return mService.getDefaultNetworkCapabilitiesForUser(userId);
738        } catch (RemoteException e) {
739            return null;
740        }
741    }
742
743    /**
744     * Returns details about the Provisioning or currently active default data network. When
745     * connected, this network is the default route for outgoing connections.
746     * You should always check {@link NetworkInfo#isConnected()} before initiating
747     * network traffic. This may return {@code null} when there is no default
748     * network.
749     *
750     * @return a {@link NetworkInfo} object for the current default network
751     *        or {@code null} if no network default network is currently active
752     *
753     * <p>This method requires the call to hold the permission
754     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
755     *
756     * {@hide}
757     */
758    public NetworkInfo getProvisioningOrActiveNetworkInfo() {
759        try {
760            return mService.getProvisioningOrActiveNetworkInfo();
761        } catch (RemoteException e) {
762            return null;
763        }
764    }
765
766    /**
767     * Returns the IP information for the current default network.
768     *
769     * @return a {@link LinkProperties} object describing the IP info
770     *        for the current default network, or {@code null} if there
771     *        is no current default network.
772     *
773     * <p>This method requires the call to hold the permission
774     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
775     * {@hide}
776     */
777    public LinkProperties getActiveLinkProperties() {
778        try {
779            return mService.getActiveLinkProperties();
780        } catch (RemoteException e) {
781            return null;
782        }
783    }
784
785    /**
786     * Returns the IP information for a given network type.
787     *
788     * @param networkType the network type of interest.
789     * @return a {@link LinkProperties} object describing the IP info
790     *        for the given networkType, or {@code null} if there is
791     *        no current default network.
792     *
793     * <p>This method requires the call to hold the permission
794     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
795     * {@hide}
796     */
797    public LinkProperties getLinkProperties(int networkType) {
798        try {
799            return mService.getLinkPropertiesForType(networkType);
800        } catch (RemoteException e) {
801            return null;
802        }
803    }
804
805    /**
806     * Get the {@link LinkProperties} for the given {@link Network}.  This
807     * will return {@code null} if the network is unknown.
808     *
809     * @param network The {@link Network} object identifying the network in question.
810     * @return The {@link LinkProperties} for the network, or {@code null}.
811     **/
812    public LinkProperties getLinkProperties(Network network) {
813        try {
814            return mService.getLinkProperties(network);
815        } catch (RemoteException e) {
816            return null;
817        }
818    }
819
820    /**
821     * Get the {@link NetworkCapabilities} for the given {@link Network}.  This
822     * will return {@code null} if the network is unknown.
823     *
824     * @param network The {@link Network} object identifying the network in question.
825     * @return The {@link NetworkCapabilities} for the network, or {@code null}.
826     */
827    public NetworkCapabilities getNetworkCapabilities(Network network) {
828        try {
829            return mService.getNetworkCapabilities(network);
830        } catch (RemoteException e) {
831            return null;
832        }
833    }
834
835    /**
836     * Tells each network type to set its radio power state as directed.
837     *
838     * @param turnOn a boolean, {@code true} to turn the radios on,
839     *        {@code false} to turn them off.
840     * @return a boolean, {@code true} indicating success.  All network types
841     *        will be tried, even if some fail.
842     *
843     * <p>This method requires the call to hold the permission
844     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
845     * {@hide}
846     */
847// TODO - check for any callers and remove
848//    public boolean setRadios(boolean turnOn) {
849//        try {
850//            return mService.setRadios(turnOn);
851//        } catch (RemoteException e) {
852//            return false;
853//        }
854//    }
855
856    /**
857     * Tells a given networkType to set its radio power state as directed.
858     *
859     * @param networkType the int networkType of interest.
860     * @param turnOn a boolean, {@code true} to turn the radio on,
861     *        {@code} false to turn it off.
862     * @return a boolean, {@code true} indicating success.
863     *
864     * <p>This method requires the call to hold the permission
865     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
866     * {@hide}
867     */
868// TODO - check for any callers and remove
869//    public boolean setRadio(int networkType, boolean turnOn) {
870//        try {
871//            return mService.setRadio(networkType, turnOn);
872//        } catch (RemoteException e) {
873//            return false;
874//        }
875//    }
876
877    /**
878     * Tells the underlying networking system that the caller wants to
879     * begin using the named feature. The interpretation of {@code feature}
880     * is completely up to each networking implementation.
881     * <p>This method requires the caller to hold the permission
882     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
883     * @param networkType specifies which network the request pertains to
884     * @param feature the name of the feature to be used
885     * @return an integer value representing the outcome of the request.
886     * The interpretation of this value is specific to each networking
887     * implementation+feature combination, except that the value {@code -1}
888     * always indicates failure.
889     *
890     * @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
891     */
892    public int startUsingNetworkFeature(int networkType, String feature) {
893        NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
894        if (netCap == null) {
895            Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " +
896                    feature);
897            return PhoneConstants.APN_REQUEST_FAILED;
898        }
899
900        NetworkRequest request = null;
901        synchronized (sLegacyRequests) {
902            LegacyRequest l = sLegacyRequests.get(netCap);
903            if (l != null) {
904                Log.d(TAG, "renewing startUsingNetworkFeature request " + l.networkRequest);
905                renewRequestLocked(l);
906                if (l.currentNetwork != null) {
907                    return PhoneConstants.APN_ALREADY_ACTIVE;
908                } else {
909                    return PhoneConstants.APN_REQUEST_STARTED;
910                }
911            }
912
913            request = requestNetworkForFeatureLocked(netCap);
914        }
915        if (request != null) {
916            Log.d(TAG, "starting startUsingNetworkFeature for request " + request);
917            return PhoneConstants.APN_REQUEST_STARTED;
918        } else {
919            Log.d(TAG, " request Failed");
920            return PhoneConstants.APN_REQUEST_FAILED;
921        }
922    }
923
924    /**
925     * Tells the underlying networking system that the caller is finished
926     * using the named feature. The interpretation of {@code feature}
927     * is completely up to each networking implementation.
928     * <p>This method requires the caller to hold the permission
929     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
930     * @param networkType specifies which network the request pertains to
931     * @param feature the name of the feature that is no longer needed
932     * @return an integer value representing the outcome of the request.
933     * The interpretation of this value is specific to each networking
934     * implementation+feature combination, except that the value {@code -1}
935     * always indicates failure.
936     *
937     * @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
938     */
939    public int stopUsingNetworkFeature(int networkType, String feature) {
940        NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
941        if (netCap == null) {
942            Log.d(TAG, "Can't satisfy stopUsingNetworkFeature for " + networkType + ", " +
943                    feature);
944            return -1;
945        }
946
947        NetworkCallback networkCallback = removeRequestForFeature(netCap);
948        if (networkCallback != null) {
949            Log.d(TAG, "stopUsingNetworkFeature for " + networkType + ", " + feature);
950            unregisterNetworkCallback(networkCallback);
951        }
952        return 1;
953    }
954
955    /**
956     * Removes the NET_CAPABILITY_NOT_RESTRICTED capability from the given
957     * NetworkCapabilities object if all the capabilities it provides are
958     * typically provided by restricted networks.
959     *
960     * TODO: consider:
961     * - Moving to NetworkCapabilities
962     * - Renaming it to guessRestrictedCapability and make it set the
963     *   restricted capability bit in addition to clearing it.
964     * @hide
965     */
966    public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
967        for (int capability : nc.getCapabilities()) {
968            switch (capability) {
969                case NetworkCapabilities.NET_CAPABILITY_CBS:
970                case NetworkCapabilities.NET_CAPABILITY_DUN:
971                case NetworkCapabilities.NET_CAPABILITY_EIMS:
972                case NetworkCapabilities.NET_CAPABILITY_FOTA:
973                case NetworkCapabilities.NET_CAPABILITY_IA:
974                case NetworkCapabilities.NET_CAPABILITY_IMS:
975                case NetworkCapabilities.NET_CAPABILITY_RCS:
976                case NetworkCapabilities.NET_CAPABILITY_XCAP:
977                case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED: //there by default
978                    continue;
979                default:
980                    // At least one capability usually provided by unrestricted
981                    // networks. Conclude that this network is unrestricted.
982                    return;
983            }
984        }
985        // All the capabilities are typically provided by restricted networks.
986        // Conclude that this network is restricted.
987        nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
988    }
989
990    private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
991        if (networkType == TYPE_MOBILE) {
992            int cap = -1;
993            if ("enableMMS".equals(feature)) {
994                cap = NetworkCapabilities.NET_CAPABILITY_MMS;
995            } else if ("enableSUPL".equals(feature)) {
996                cap = NetworkCapabilities.NET_CAPABILITY_SUPL;
997            } else if ("enableDUN".equals(feature) || "enableDUNAlways".equals(feature)) {
998                cap = NetworkCapabilities.NET_CAPABILITY_DUN;
999            } else if ("enableHIPRI".equals(feature)) {
1000                cap = NetworkCapabilities.NET_CAPABILITY_INTERNET;
1001            } else if ("enableFOTA".equals(feature)) {
1002                cap = NetworkCapabilities.NET_CAPABILITY_FOTA;
1003            } else if ("enableIMS".equals(feature)) {
1004                cap = NetworkCapabilities.NET_CAPABILITY_IMS;
1005            } else if ("enableCBS".equals(feature)) {
1006                cap = NetworkCapabilities.NET_CAPABILITY_CBS;
1007            } else {
1008                return null;
1009            }
1010            NetworkCapabilities netCap = new NetworkCapabilities();
1011            netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
1012            maybeMarkCapabilitiesRestricted(netCap);
1013            return netCap;
1014        } else if (networkType == TYPE_WIFI) {
1015            if ("p2p".equals(feature)) {
1016                NetworkCapabilities netCap = new NetworkCapabilities();
1017                netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
1018                netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
1019                maybeMarkCapabilitiesRestricted(netCap);
1020                return netCap;
1021            }
1022        }
1023        return null;
1024    }
1025
1026    /**
1027     * Guess what the network request was trying to say so that the resulting
1028     * network is accessible via the legacy (deprecated) API such as
1029     * requestRouteToHost.
1030     * This means we should try to be fairly preceise about transport and
1031     * capability but ignore things such as networkSpecifier.
1032     * If the request has more than one transport or capability it doesn't
1033     * match the old legacy requests (they selected only single transport/capability)
1034     * so this function cannot map the request to a single legacy type and
1035     * the resulting network will not be available to the legacy APIs.
1036     *
1037     * TODO - This should be removed when the legacy APIs are removed.
1038     */
1039    private int inferLegacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
1040        if (netCap == null) {
1041            return TYPE_NONE;
1042        }
1043
1044        if (!netCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
1045            return TYPE_NONE;
1046        }
1047
1048        String type = null;
1049        int result = TYPE_NONE;
1050
1051        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
1052            type = "enableCBS";
1053            result = TYPE_MOBILE_CBS;
1054        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
1055            type = "enableIMS";
1056            result = TYPE_MOBILE_IMS;
1057        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
1058            type = "enableFOTA";
1059            result = TYPE_MOBILE_FOTA;
1060        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
1061            type = "enableDUN";
1062            result = TYPE_MOBILE_DUN;
1063        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
1064            type = "enableSUPL";
1065            result = TYPE_MOBILE_SUPL;
1066        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
1067            type = "enableMMS";
1068            result = TYPE_MOBILE_MMS;
1069        } else if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
1070            type = "enableHIPRI";
1071            result = TYPE_MOBILE_HIPRI;
1072        }
1073        if (type != null) {
1074            NetworkCapabilities testCap = networkCapabilitiesForFeature(TYPE_MOBILE, type);
1075            if (testCap.equalsNetCapabilities(netCap) && testCap.equalsTransportTypes(netCap)) {
1076                return result;
1077            }
1078        }
1079        return TYPE_NONE;
1080    }
1081
1082    private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
1083        if (netCap == null) return TYPE_NONE;
1084        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
1085            return TYPE_MOBILE_CBS;
1086        }
1087        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
1088            return TYPE_MOBILE_IMS;
1089        }
1090        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
1091            return TYPE_MOBILE_FOTA;
1092        }
1093        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
1094            return TYPE_MOBILE_DUN;
1095        }
1096        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
1097            return TYPE_MOBILE_SUPL;
1098        }
1099        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
1100            return TYPE_MOBILE_MMS;
1101        }
1102        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
1103            return TYPE_MOBILE_HIPRI;
1104        }
1105        if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) {
1106            return TYPE_WIFI_P2P;
1107        }
1108        return TYPE_NONE;
1109    }
1110
1111    private static class LegacyRequest {
1112        NetworkCapabilities networkCapabilities;
1113        NetworkRequest networkRequest;
1114        int expireSequenceNumber;
1115        Network currentNetwork;
1116        int delay = -1;
1117        NetworkCallback networkCallback = new NetworkCallback() {
1118            @Override
1119            public void onAvailable(Network network) {
1120                currentNetwork = network;
1121                Log.d(TAG, "startUsingNetworkFeature got Network:" + network);
1122                setProcessDefaultNetworkForHostResolution(network);
1123            }
1124            @Override
1125            public void onLost(Network network) {
1126                if (network.equals(currentNetwork)) {
1127                    currentNetwork = null;
1128                    setProcessDefaultNetworkForHostResolution(null);
1129                }
1130                Log.d(TAG, "startUsingNetworkFeature lost Network:" + network);
1131            }
1132        };
1133    }
1134
1135    private static HashMap<NetworkCapabilities, LegacyRequest> sLegacyRequests =
1136            new HashMap<NetworkCapabilities, LegacyRequest>();
1137
1138    private NetworkRequest findRequestForFeature(NetworkCapabilities netCap) {
1139        synchronized (sLegacyRequests) {
1140            LegacyRequest l = sLegacyRequests.get(netCap);
1141            if (l != null) return l.networkRequest;
1142        }
1143        return null;
1144    }
1145
1146    private void renewRequestLocked(LegacyRequest l) {
1147        l.expireSequenceNumber++;
1148        Log.d(TAG, "renewing request to seqNum " + l.expireSequenceNumber);
1149        sendExpireMsgForFeature(l.networkCapabilities, l.expireSequenceNumber, l.delay);
1150    }
1151
1152    private void expireRequest(NetworkCapabilities netCap, int sequenceNum) {
1153        int ourSeqNum = -1;
1154        synchronized (sLegacyRequests) {
1155            LegacyRequest l = sLegacyRequests.get(netCap);
1156            if (l == null) return;
1157            ourSeqNum = l.expireSequenceNumber;
1158            if (l.expireSequenceNumber == sequenceNum) {
1159                unregisterNetworkCallback(l.networkCallback);
1160                sLegacyRequests.remove(netCap);
1161            }
1162        }
1163        Log.d(TAG, "expireRequest with " + ourSeqNum + ", " + sequenceNum);
1164    }
1165
1166    private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) {
1167        int delay = -1;
1168        int type = legacyTypeForNetworkCapabilities(netCap);
1169        try {
1170            delay = mService.getRestoreDefaultNetworkDelay(type);
1171        } catch (RemoteException e) {}
1172        LegacyRequest l = new LegacyRequest();
1173        l.networkCapabilities = netCap;
1174        l.delay = delay;
1175        l.expireSequenceNumber = 0;
1176        l.networkRequest = sendRequestForNetwork(netCap, l.networkCallback, 0,
1177                REQUEST, type);
1178        if (l.networkRequest == null) return null;
1179        sLegacyRequests.put(netCap, l);
1180        sendExpireMsgForFeature(netCap, l.expireSequenceNumber, delay);
1181        return l.networkRequest;
1182    }
1183
1184    private void sendExpireMsgForFeature(NetworkCapabilities netCap, int seqNum, int delay) {
1185        if (delay >= 0) {
1186            Log.d(TAG, "sending expire msg with seqNum " + seqNum + " and delay " + delay);
1187            Message msg = sCallbackHandler.obtainMessage(EXPIRE_LEGACY_REQUEST, seqNum, 0, netCap);
1188            sCallbackHandler.sendMessageDelayed(msg, delay);
1189        }
1190    }
1191
1192    private NetworkCallback removeRequestForFeature(NetworkCapabilities netCap) {
1193        synchronized (sLegacyRequests) {
1194            LegacyRequest l = sLegacyRequests.remove(netCap);
1195            if (l == null) return null;
1196            return l.networkCallback;
1197        }
1198    }
1199
1200    /**
1201     * Ensure that a network route exists to deliver traffic to the specified
1202     * host via the specified network interface. An attempt to add a route that
1203     * already exists is ignored, but treated as successful.
1204     * <p>This method requires the caller to hold the permission
1205     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
1206     * @param networkType the type of the network over which traffic to the specified
1207     * host is to be routed
1208     * @param hostAddress the IP address of the host to which the route is desired
1209     * @return {@code true} on success, {@code false} on failure
1210     *
1211     * @deprecated Deprecated in favor of the {@link #requestNetwork},
1212     *             {@link #setProcessDefaultNetwork} and {@link Network#getSocketFactory} api.
1213     */
1214    public boolean requestRouteToHost(int networkType, int hostAddress) {
1215        return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress));
1216    }
1217
1218    /**
1219     * Ensure that a network route exists to deliver traffic to the specified
1220     * host via the specified network interface. An attempt to add a route that
1221     * already exists is ignored, but treated as successful.
1222     * <p>This method requires the caller to hold the permission
1223     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
1224     * @param networkType the type of the network over which traffic to the specified
1225     * host is to be routed
1226     * @param hostAddress the IP address of the host to which the route is desired
1227     * @return {@code true} on success, {@code false} on failure
1228     * @hide
1229     * @deprecated Deprecated in favor of the {@link #requestNetwork} and
1230     *             {@link #setProcessDefaultNetwork} api.
1231     */
1232    public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
1233        try {
1234            return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress());
1235        } catch (RemoteException e) {
1236            return false;
1237        }
1238    }
1239
1240    /**
1241     * Returns the value of the setting for background data usage. If false,
1242     * applications should not use the network if the application is not in the
1243     * foreground. Developers should respect this setting, and check the value
1244     * of this before performing any background data operations.
1245     * <p>
1246     * All applications that have background services that use the network
1247     * should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}.
1248     * <p>
1249     * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability of
1250     * background data depends on several combined factors, and this method will
1251     * always return {@code true}. Instead, when background data is unavailable,
1252     * {@link #getActiveNetworkInfo()} will now appear disconnected.
1253     *
1254     * @return Whether background data usage is allowed.
1255     */
1256    @Deprecated
1257    public boolean getBackgroundDataSetting() {
1258        // assume that background data is allowed; final authority is
1259        // NetworkInfo which may be blocked.
1260        return true;
1261    }
1262
1263    /**
1264     * Sets the value of the setting for background data usage.
1265     *
1266     * @param allowBackgroundData Whether an application should use data while
1267     *            it is in the background.
1268     *
1269     * @attr ref android.Manifest.permission#CHANGE_BACKGROUND_DATA_SETTING
1270     * @see #getBackgroundDataSetting()
1271     * @hide
1272     */
1273    @Deprecated
1274    public void setBackgroundDataSetting(boolean allowBackgroundData) {
1275        // ignored
1276    }
1277
1278    /**
1279     * Return quota status for the current active network, or {@code null} if no
1280     * network is active. Quota status can change rapidly, so these values
1281     * shouldn't be cached.
1282     *
1283     * <p>This method requires the call to hold the permission
1284     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1285     *
1286     * @hide
1287     */
1288    public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
1289        try {
1290            return mService.getActiveNetworkQuotaInfo();
1291        } catch (RemoteException e) {
1292            return null;
1293        }
1294    }
1295
1296    /**
1297     * @hide
1298     * @deprecated Talk to TelephonyManager directly
1299     */
1300    public boolean getMobileDataEnabled() {
1301        IBinder b = ServiceManager.getService(Context.TELEPHONY_SERVICE);
1302        if (b != null) {
1303            try {
1304                ITelephony it = ITelephony.Stub.asInterface(b);
1305                return it.getDataEnabled();
1306            } catch (RemoteException e) { }
1307        }
1308        return false;
1309    }
1310
1311    /**
1312     * Callback for use with {@link ConnectivityManager#addDefaultNetworkActiveListener}
1313     * to find out when the system default network has gone in to a high power state.
1314     */
1315    public interface OnNetworkActiveListener {
1316        /**
1317         * Called on the main thread of the process to report that the current data network
1318         * has become active, and it is now a good time to perform any pending network
1319         * operations.  Note that this listener only tells you when the network becomes
1320         * active; if at any other time you want to know whether it is active (and thus okay
1321         * to initiate network traffic), you can retrieve its instantaneous state with
1322         * {@link ConnectivityManager#isDefaultNetworkActive}.
1323         */
1324        public void onNetworkActive();
1325    }
1326
1327    private INetworkManagementService getNetworkManagementService() {
1328        synchronized (this) {
1329            if (mNMService != null) {
1330                return mNMService;
1331            }
1332            IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
1333            mNMService = INetworkManagementService.Stub.asInterface(b);
1334            return mNMService;
1335        }
1336    }
1337
1338    private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
1339            mNetworkActivityListeners
1340                    = new ArrayMap<OnNetworkActiveListener, INetworkActivityListener>();
1341
1342    /**
1343     * Start listening to reports when the system's default data network is active, meaning it is
1344     * a good time to perform network traffic.  Use {@link #isDefaultNetworkActive()}
1345     * to determine the current state of the system's default network after registering the
1346     * listener.
1347     * <p>
1348     * If the process default network has been set with
1349     * {@link ConnectivityManager#setProcessDefaultNetwork} this function will not
1350     * reflect the process's default, but the system default.
1351     *
1352     * @param l The listener to be told when the network is active.
1353     */
1354    public void addDefaultNetworkActiveListener(final OnNetworkActiveListener l) {
1355        INetworkActivityListener rl = new INetworkActivityListener.Stub() {
1356            @Override
1357            public void onNetworkActive() throws RemoteException {
1358                l.onNetworkActive();
1359            }
1360        };
1361
1362        try {
1363            getNetworkManagementService().registerNetworkActivityListener(rl);
1364            mNetworkActivityListeners.put(l, rl);
1365        } catch (RemoteException e) {
1366        }
1367    }
1368
1369    /**
1370     * Remove network active listener previously registered with
1371     * {@link #addDefaultNetworkActiveListener}.
1372     *
1373     * @param l Previously registered listener.
1374     */
1375    public void removeDefaultNetworkActiveListener(OnNetworkActiveListener l) {
1376        INetworkActivityListener rl = mNetworkActivityListeners.get(l);
1377        if (rl == null) {
1378            throw new IllegalArgumentException("Listener not registered: " + l);
1379        }
1380        try {
1381            getNetworkManagementService().unregisterNetworkActivityListener(rl);
1382        } catch (RemoteException e) {
1383        }
1384    }
1385
1386    /**
1387     * Return whether the data network is currently active.  An active network means that
1388     * it is currently in a high power state for performing data transmission.  On some
1389     * types of networks, it may be expensive to move and stay in such a state, so it is
1390     * more power efficient to batch network traffic together when the radio is already in
1391     * this state.  This method tells you whether right now is currently a good time to
1392     * initiate network traffic, as the network is already active.
1393     */
1394    public boolean isDefaultNetworkActive() {
1395        try {
1396            return getNetworkManagementService().isNetworkActive();
1397        } catch (RemoteException e) {
1398        }
1399        return false;
1400    }
1401
1402    /**
1403     * {@hide}
1404     */
1405    public ConnectivityManager(IConnectivityManager service) {
1406        mService = checkNotNull(service, "missing IConnectivityManager");
1407        sInstance = this;
1408    }
1409
1410    /** {@hide} */
1411    public static ConnectivityManager from(Context context) {
1412        return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
1413    }
1414
1415    /** {@hide */
1416    public static final void enforceTetherChangePermission(Context context) {
1417        if (context.getResources().getStringArray(
1418                com.android.internal.R.array.config_mobile_hotspot_provision_app).length == 2) {
1419            // Have a provisioning app - must only let system apps (which check this app)
1420            // turn on tethering
1421            context.enforceCallingOrSelfPermission(
1422                    android.Manifest.permission.CONNECTIVITY_INTERNAL, "ConnectivityService");
1423        } else {
1424            context.enforceCallingOrSelfPermission(
1425                    android.Manifest.permission.CHANGE_NETWORK_STATE, "ConnectivityService");
1426        }
1427    }
1428
1429    /**
1430     * @deprecated - use getSystemService. This is a kludge to support static access in certain
1431     *               situations where a Context pointer is unavailable.
1432     * @hide
1433     */
1434    public static ConnectivityManager getInstance() {
1435        if (sInstance == null) {
1436            throw new IllegalStateException("No ConnectivityManager yet constructed");
1437        }
1438        return sInstance;
1439    }
1440
1441    /**
1442     * Get the set of tetherable, available interfaces.  This list is limited by
1443     * device configuration and current interface existence.
1444     *
1445     * @return an array of 0 or more Strings of tetherable interface names.
1446     *
1447     * <p>This method requires the call to hold the permission
1448     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1449     * {@hide}
1450     */
1451    public String[] getTetherableIfaces() {
1452        try {
1453            return mService.getTetherableIfaces();
1454        } catch (RemoteException e) {
1455            return new String[0];
1456        }
1457    }
1458
1459    /**
1460     * Get the set of tethered interfaces.
1461     *
1462     * @return an array of 0 or more String of currently tethered interface names.
1463     *
1464     * <p>This method requires the call to hold the permission
1465     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1466     * {@hide}
1467     */
1468    public String[] getTetheredIfaces() {
1469        try {
1470            return mService.getTetheredIfaces();
1471        } catch (RemoteException e) {
1472            return new String[0];
1473        }
1474    }
1475
1476    /**
1477     * Get the set of interface names which attempted to tether but
1478     * failed.  Re-attempting to tether may cause them to reset to the Tethered
1479     * state.  Alternatively, causing the interface to be destroyed and recreated
1480     * may cause them to reset to the available state.
1481     * {@link ConnectivityManager#getLastTetherError} can be used to get more
1482     * information on the cause of the errors.
1483     *
1484     * @return an array of 0 or more String indicating the interface names
1485     *        which failed to tether.
1486     *
1487     * <p>This method requires the call to hold the permission
1488     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1489     * {@hide}
1490     */
1491    public String[] getTetheringErroredIfaces() {
1492        try {
1493            return mService.getTetheringErroredIfaces();
1494        } catch (RemoteException e) {
1495            return new String[0];
1496        }
1497    }
1498
1499    /**
1500     * Get the set of tethered dhcp ranges.
1501     *
1502     * @return an array of 0 or more {@code String} of tethered dhcp ranges.
1503     * {@hide}
1504     */
1505    public String[] getTetheredDhcpRanges() {
1506        try {
1507            return mService.getTetheredDhcpRanges();
1508        } catch (RemoteException e) {
1509            return new String[0];
1510        }
1511    }
1512
1513    /**
1514     * Attempt to tether the named interface.  This will setup a dhcp server
1515     * on the interface, forward and NAT IP packets and forward DNS requests
1516     * to the best active upstream network interface.  Note that if no upstream
1517     * IP network interface is available, dhcp will still run and traffic will be
1518     * allowed between the tethered devices and this device, though upstream net
1519     * access will of course fail until an upstream network interface becomes
1520     * active.
1521     *
1522     * @param iface the interface name to tether.
1523     * @return error a {@code TETHER_ERROR} value indicating success or failure type
1524     *
1525     * <p>This method requires the call to hold the permission
1526     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
1527     * {@hide}
1528     */
1529    public int tether(String iface) {
1530        try {
1531            return mService.tether(iface);
1532        } catch (RemoteException e) {
1533            return TETHER_ERROR_SERVICE_UNAVAIL;
1534        }
1535    }
1536
1537    /**
1538     * Stop tethering the named interface.
1539     *
1540     * @param iface the interface name to untether.
1541     * @return error a {@code TETHER_ERROR} value indicating success or failure type
1542     *
1543     * <p>This method requires the call to hold the permission
1544     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
1545     * {@hide}
1546     */
1547    public int untether(String iface) {
1548        try {
1549            return mService.untether(iface);
1550        } catch (RemoteException e) {
1551            return TETHER_ERROR_SERVICE_UNAVAIL;
1552        }
1553    }
1554
1555    /**
1556     * Check if the device allows for tethering.  It may be disabled via
1557     * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
1558     * due to device configuration.
1559     *
1560     * @return a boolean - {@code true} indicating Tethering is supported.
1561     *
1562     * <p>This method requires the call to hold the permission
1563     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1564     * {@hide}
1565     */
1566    public boolean isTetheringSupported() {
1567        try {
1568            return mService.isTetheringSupported();
1569        } catch (RemoteException e) {
1570            return false;
1571        }
1572    }
1573
1574    /**
1575     * Get the list of regular expressions that define any tetherable
1576     * USB network interfaces.  If USB tethering is not supported by the
1577     * device, this list should be empty.
1578     *
1579     * @return an array of 0 or more regular expression Strings defining
1580     *        what interfaces are considered tetherable usb interfaces.
1581     *
1582     * <p>This method requires the call to hold the permission
1583     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1584     * {@hide}
1585     */
1586    public String[] getTetherableUsbRegexs() {
1587        try {
1588            return mService.getTetherableUsbRegexs();
1589        } catch (RemoteException e) {
1590            return new String[0];
1591        }
1592    }
1593
1594    /**
1595     * Get the list of regular expressions that define any tetherable
1596     * Wifi network interfaces.  If Wifi tethering is not supported by the
1597     * device, this list should be empty.
1598     *
1599     * @return an array of 0 or more regular expression Strings defining
1600     *        what interfaces are considered tetherable wifi interfaces.
1601     *
1602     * <p>This method requires the call to hold the permission
1603     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1604     * {@hide}
1605     */
1606    public String[] getTetherableWifiRegexs() {
1607        try {
1608            return mService.getTetherableWifiRegexs();
1609        } catch (RemoteException e) {
1610            return new String[0];
1611        }
1612    }
1613
1614    /**
1615     * Get the list of regular expressions that define any tetherable
1616     * Bluetooth network interfaces.  If Bluetooth tethering is not supported by the
1617     * device, this list should be empty.
1618     *
1619     * @return an array of 0 or more regular expression Strings defining
1620     *        what interfaces are considered tetherable bluetooth interfaces.
1621     *
1622     * <p>This method requires the call to hold the permission
1623     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1624     * {@hide}
1625     */
1626    public String[] getTetherableBluetoothRegexs() {
1627        try {
1628            return mService.getTetherableBluetoothRegexs();
1629        } catch (RemoteException e) {
1630            return new String[0];
1631        }
1632    }
1633
1634    /**
1635     * Attempt to both alter the mode of USB and Tethering of USB.  A
1636     * utility method to deal with some of the complexity of USB - will
1637     * attempt to switch to Rndis and subsequently tether the resulting
1638     * interface on {@code true} or turn off tethering and switch off
1639     * Rndis on {@code false}.
1640     *
1641     * @param enable a boolean - {@code true} to enable tethering
1642     * @return error a {@code TETHER_ERROR} value indicating success or failure type
1643     *
1644     * <p>This method requires the call to hold the permission
1645     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
1646     * {@hide}
1647     */
1648    public int setUsbTethering(boolean enable) {
1649        try {
1650            return mService.setUsbTethering(enable);
1651        } catch (RemoteException e) {
1652            return TETHER_ERROR_SERVICE_UNAVAIL;
1653        }
1654    }
1655
1656    /** {@hide} */
1657    public static final int TETHER_ERROR_NO_ERROR           = 0;
1658    /** {@hide} */
1659    public static final int TETHER_ERROR_UNKNOWN_IFACE      = 1;
1660    /** {@hide} */
1661    public static final int TETHER_ERROR_SERVICE_UNAVAIL    = 2;
1662    /** {@hide} */
1663    public static final int TETHER_ERROR_UNSUPPORTED        = 3;
1664    /** {@hide} */
1665    public static final int TETHER_ERROR_UNAVAIL_IFACE      = 4;
1666    /** {@hide} */
1667    public static final int TETHER_ERROR_MASTER_ERROR       = 5;
1668    /** {@hide} */
1669    public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
1670    /** {@hide} */
1671    public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
1672    /** {@hide} */
1673    public static final int TETHER_ERROR_ENABLE_NAT_ERROR     = 8;
1674    /** {@hide} */
1675    public static final int TETHER_ERROR_DISABLE_NAT_ERROR    = 9;
1676    /** {@hide} */
1677    public static final int TETHER_ERROR_IFACE_CFG_ERROR      = 10;
1678
1679    /**
1680     * Get a more detailed error code after a Tethering or Untethering
1681     * request asynchronously failed.
1682     *
1683     * @param iface The name of the interface of interest
1684     * @return error The error code of the last error tethering or untethering the named
1685     *               interface
1686     *
1687     * <p>This method requires the call to hold the permission
1688     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1689     * {@hide}
1690     */
1691    public int getLastTetherError(String iface) {
1692        try {
1693            return mService.getLastTetherError(iface);
1694        } catch (RemoteException e) {
1695            return TETHER_ERROR_SERVICE_UNAVAIL;
1696        }
1697    }
1698
1699    /**
1700     * Report network connectivity status.  This is currently used only
1701     * to alter status bar UI.
1702     *
1703     * @param networkType The type of network you want to report on
1704     * @param percentage The quality of the connection 0 is bad, 100 is good
1705     *
1706     * <p>This method requires the call to hold the permission
1707     * {@link android.Manifest.permission#STATUS_BAR}.
1708     * {@hide}
1709     */
1710    public void reportInetCondition(int networkType, int percentage) {
1711        try {
1712            mService.reportInetCondition(networkType, percentage);
1713        } catch (RemoteException e) {
1714        }
1715    }
1716
1717    /**
1718     * Report a problem network to the framework.  This provides a hint to the system
1719     * that there might be connectivity problems on this network and may cause
1720     * the framework to re-evaluate network connectivity and/or switch to another
1721     * network.
1722     *
1723     * @param network The {@link Network} the application was attempting to use
1724     *                or {@code null} to indicate the current default network.
1725     */
1726    public void reportBadNetwork(Network network) {
1727        try {
1728            mService.reportBadNetwork(network);
1729        } catch (RemoteException e) {
1730        }
1731    }
1732
1733    /**
1734     * Set a network-independent global http proxy.  This is not normally what you want
1735     * for typical HTTP proxies - they are general network dependent.  However if you're
1736     * doing something unusual like general internal filtering this may be useful.  On
1737     * a private network where the proxy is not accessible, you may break HTTP using this.
1738     *
1739     * @param p The a {@link ProxyInfo} object defining the new global
1740     *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
1741     *
1742     * <p>This method requires the call to hold the permission
1743     * android.Manifest.permission#CONNECTIVITY_INTERNAL.
1744     * @hide
1745     */
1746    public void setGlobalProxy(ProxyInfo p) {
1747        try {
1748            mService.setGlobalProxy(p);
1749        } catch (RemoteException e) {
1750        }
1751    }
1752
1753    /**
1754     * Retrieve any network-independent global HTTP proxy.
1755     *
1756     * @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
1757     *        if no global HTTP proxy is set.
1758     *
1759     * <p>This method requires the call to hold the permission
1760     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1761     * @hide
1762     */
1763    public ProxyInfo getGlobalProxy() {
1764        try {
1765            return mService.getGlobalProxy();
1766        } catch (RemoteException e) {
1767            return null;
1768        }
1769    }
1770
1771    /**
1772     * Get the current default HTTP proxy settings.  If a global proxy is set it will be returned,
1773     * otherwise if this process is bound to a {@link Network} using
1774     * {@link #setProcessDefaultNetwork} then that {@code Network}'s proxy is returned, otherwise
1775     * the default network's proxy is returned.
1776     *
1777     * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no
1778     *        HTTP proxy is active.
1779     * @hide
1780     */
1781    public ProxyInfo getDefaultProxy() {
1782        final Network network = getProcessDefaultNetwork();
1783        if (network != null) {
1784            final ProxyInfo globalProxy = getGlobalProxy();
1785            if (globalProxy != null) return globalProxy;
1786            final LinkProperties lp = getLinkProperties(network);
1787            if (lp != null) return lp.getHttpProxy();
1788            return null;
1789        }
1790        try {
1791            return mService.getDefaultProxy();
1792        } catch (RemoteException e) {
1793            return null;
1794        }
1795    }
1796
1797    /**
1798     * Sets a secondary requirement bit for the given networkType.
1799     * This requirement bit is generally under the control of the carrier
1800     * or its agents and is not directly controlled by the user.
1801     *
1802     * @param networkType The network who's dependence has changed
1803     * @param met Boolean - true if network use is OK, false if not
1804     *
1805     * <p>This method requires the call to hold the permission
1806     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
1807     * {@hide}
1808     */
1809    public void setDataDependency(int networkType, boolean met) {
1810        try {
1811            mService.setDataDependency(networkType, met);
1812        } catch (RemoteException e) {
1813        }
1814    }
1815
1816    /**
1817     * Returns true if the hardware supports the given network type
1818     * else it returns false.  This doesn't indicate we have coverage
1819     * or are authorized onto a network, just whether or not the
1820     * hardware supports it.  For example a GSM phone without a SIM
1821     * should still return {@code true} for mobile data, but a wifi only
1822     * tablet would return {@code false}.
1823     *
1824     * @param networkType The network type we'd like to check
1825     * @return {@code true} if supported, else {@code false}
1826     *
1827     * <p>This method requires the call to hold the permission
1828     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1829     * @hide
1830     */
1831    public boolean isNetworkSupported(int networkType) {
1832        try {
1833            return mService.isNetworkSupported(networkType);
1834        } catch (RemoteException e) {}
1835        return false;
1836    }
1837
1838    /**
1839     * Returns if the currently active data network is metered. A network is
1840     * classified as metered when the user is sensitive to heavy data usage on
1841     * that connection due to monetary costs, data limitations or
1842     * battery/performance issues. You should check this before doing large
1843     * data transfers, and warn the user or delay the operation until another
1844     * network is available.
1845     *
1846     * @return {@code true} if large transfers should be avoided, otherwise
1847     *        {@code false}.
1848     *
1849     * <p>This method requires the call to hold the permission
1850     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
1851     */
1852    public boolean isActiveNetworkMetered() {
1853        try {
1854            return mService.isActiveNetworkMetered();
1855        } catch (RemoteException e) {
1856            return false;
1857        }
1858    }
1859
1860    /**
1861     * If the LockdownVpn mechanism is enabled, updates the vpn
1862     * with a reload of its profile.
1863     *
1864     * @return a boolean with {@code} indicating success
1865     *
1866     * <p>This method can only be called by the system UID
1867     * {@hide}
1868     */
1869    public boolean updateLockdownVpn() {
1870        try {
1871            return mService.updateLockdownVpn();
1872        } catch (RemoteException e) {
1873            return false;
1874        }
1875    }
1876
1877    /**
1878     * Signal that the captive portal check on the indicated network
1879     * is complete and whether its a captive portal or not.
1880     *
1881     * @param info the {@link NetworkInfo} object for the networkType
1882     *        in question.
1883     * @param isCaptivePortal true/false.
1884     *
1885     * <p>This method requires the call to hold the permission
1886     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
1887     * {@hide}
1888     */
1889    public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
1890        try {
1891            mService.captivePortalCheckCompleted(info, isCaptivePortal);
1892        } catch (RemoteException e) {
1893        }
1894    }
1895
1896    /**
1897     * Supply the backend messenger for a network tracker
1898     *
1899     * @param networkType NetworkType to set
1900     * @param messenger {@link Messenger}
1901     * {@hide}
1902     */
1903    public void supplyMessenger(int networkType, Messenger messenger) {
1904        try {
1905            mService.supplyMessenger(networkType, messenger);
1906        } catch (RemoteException e) {
1907        }
1908    }
1909
1910    /**
1911     * Check mobile provisioning.
1912     *
1913     * @param suggestedTimeOutMs, timeout in milliseconds
1914     *
1915     * @return time out that will be used, maybe less that suggestedTimeOutMs
1916     * -1 if an error.
1917     *
1918     * {@hide}
1919     */
1920    public int checkMobileProvisioning(int suggestedTimeOutMs) {
1921        int timeOutMs = -1;
1922        try {
1923            timeOutMs = mService.checkMobileProvisioning(suggestedTimeOutMs);
1924        } catch (RemoteException e) {
1925        }
1926        return timeOutMs;
1927    }
1928
1929    /**
1930     * Get the mobile provisioning url.
1931     * {@hide}
1932     */
1933    public String getMobileProvisioningUrl() {
1934        try {
1935            return mService.getMobileProvisioningUrl();
1936        } catch (RemoteException e) {
1937        }
1938        return null;
1939    }
1940
1941    /**
1942     * Get the mobile redirected provisioning url.
1943     * {@hide}
1944     */
1945    public String getMobileRedirectedProvisioningUrl() {
1946        try {
1947            return mService.getMobileRedirectedProvisioningUrl();
1948        } catch (RemoteException e) {
1949        }
1950        return null;
1951    }
1952
1953    /**
1954     * Set sign in error notification to visible or in visible
1955     *
1956     * @param visible
1957     * @param networkType
1958     *
1959     * {@hide}
1960     */
1961    public void setProvisioningNotificationVisible(boolean visible, int networkType,
1962            String action) {
1963        try {
1964            mService.setProvisioningNotificationVisible(visible, networkType, action);
1965        } catch (RemoteException e) {
1966        }
1967    }
1968
1969    /**
1970     * Set the value for enabling/disabling airplane mode
1971     *
1972     * @param enable whether to enable airplane mode or not
1973     *
1974     * <p>This method requires the call to hold the permission
1975     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
1976     * @hide
1977     */
1978    public void setAirplaneMode(boolean enable) {
1979        try {
1980            mService.setAirplaneMode(enable);
1981        } catch (RemoteException e) {
1982        }
1983    }
1984
1985    /** {@hide} */
1986    public void registerNetworkFactory(Messenger messenger, String name) {
1987        try {
1988            mService.registerNetworkFactory(messenger, name);
1989        } catch (RemoteException e) { }
1990    }
1991
1992    /** {@hide} */
1993    public void unregisterNetworkFactory(Messenger messenger) {
1994        try {
1995            mService.unregisterNetworkFactory(messenger);
1996        } catch (RemoteException e) { }
1997    }
1998
1999    /** {@hide} */
2000    public void registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
2001            NetworkCapabilities nc, int score, NetworkMisc misc) {
2002        try {
2003            mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc);
2004        } catch (RemoteException e) { }
2005    }
2006
2007    /**
2008     * Base class for NetworkRequest callbacks.  Used for notifications about network
2009     * changes.  Should be extended by applications wanting notifications.
2010     */
2011    public static class NetworkCallback {
2012        /** @hide */
2013        public static final int PRECHECK     = 1;
2014        /** @hide */
2015        public static final int AVAILABLE    = 2;
2016        /** @hide */
2017        public static final int LOSING       = 3;
2018        /** @hide */
2019        public static final int LOST         = 4;
2020        /** @hide */
2021        public static final int UNAVAIL      = 5;
2022        /** @hide */
2023        public static final int CAP_CHANGED  = 6;
2024        /** @hide */
2025        public static final int PROP_CHANGED = 7;
2026        /** @hide */
2027        public static final int CANCELED     = 8;
2028
2029        /**
2030         * @hide
2031         * Called whenever the framework connects to a network that it may use to
2032         * satisfy this request
2033         */
2034        public void onPreCheck(Network network) {}
2035
2036        /**
2037         * Called when the framework connects and has declared new network ready for use.
2038         * This callback may be called more than once if the {@link Network} that is
2039         * satisfying the request changes.
2040         *
2041         * @param network The {@link Network} of the satisfying network.
2042         */
2043        public void onAvailable(Network network) {}
2044
2045        /**
2046         * Called when the network is about to be disconnected.  Often paired with an
2047         * {@link NetworkCallback#onAvailable} call with the new replacement network
2048         * for graceful handover.  This may not be called if we have a hard loss
2049         * (loss without warning).  This may be followed by either a
2050         * {@link NetworkCallback#onLost} call or a
2051         * {@link NetworkCallback#onAvailable} call for this network depending
2052         * on whether we lose or regain it.
2053         *
2054         * @param network The {@link Network} that is about to be disconnected.
2055         * @param maxMsToLive The time in ms the framework will attempt to keep the
2056         *                     network connected.  Note that the network may suffer a
2057         *                     hard loss at any time.
2058         */
2059        public void onLosing(Network network, int maxMsToLive) {}
2060
2061        /**
2062         * Called when the framework has a hard loss of the network or when the
2063         * graceful failure ends.
2064         *
2065         * @param network The {@link Network} lost.
2066         */
2067        public void onLost(Network network) {}
2068
2069        /**
2070         * Called if no network is found in the given timeout time.  If no timeout is given,
2071         * this will not be called.
2072         * @hide
2073         */
2074        public void onUnavailable() {}
2075
2076        /**
2077         * Called when the network the framework connected to for this request
2078         * changes capabilities but still satisfies the stated need.
2079         *
2080         * @param network The {@link Network} whose capabilities have changed.
2081         * @param networkCapabilities The new {@link NetworkCapabilities} for this network.
2082         */
2083        public void onCapabilitiesChanged(Network network,
2084                NetworkCapabilities networkCapabilities) {}
2085
2086        /**
2087         * Called when the network the framework connected to for this request
2088         * changes {@link LinkProperties}.
2089         *
2090         * @param network The {@link Network} whose link properties have changed.
2091         * @param linkProperties The new {@link LinkProperties} for this network.
2092         */
2093        public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {}
2094
2095        private NetworkRequest networkRequest;
2096    }
2097
2098    private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER;
2099    /** @hide obj = pair(NetworkRequest, Network) */
2100    public static final int CALLBACK_PRECHECK           = BASE + 1;
2101    /** @hide obj = pair(NetworkRequest, Network) */
2102    public static final int CALLBACK_AVAILABLE          = BASE + 2;
2103    /** @hide obj = pair(NetworkRequest, Network), arg1 = ttl */
2104    public static final int CALLBACK_LOSING             = BASE + 3;
2105    /** @hide obj = pair(NetworkRequest, Network) */
2106    public static final int CALLBACK_LOST               = BASE + 4;
2107    /** @hide obj = NetworkRequest */
2108    public static final int CALLBACK_UNAVAIL            = BASE + 5;
2109    /** @hide obj = pair(NetworkRequest, Network) */
2110    public static final int CALLBACK_CAP_CHANGED        = BASE + 6;
2111    /** @hide obj = pair(NetworkRequest, Network) */
2112    public static final int CALLBACK_IP_CHANGED         = BASE + 7;
2113    /** @hide obj = NetworkRequest */
2114    public static final int CALLBACK_RELEASED           = BASE + 8;
2115    /** @hide */
2116    public static final int CALLBACK_EXIT               = BASE + 9;
2117    /** @hide obj = NetworkCapabilities, arg1 = seq number */
2118    private static final int EXPIRE_LEGACY_REQUEST      = BASE + 10;
2119
2120    private class CallbackHandler extends Handler {
2121        private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap;
2122        private final AtomicInteger mRefCount;
2123        private static final String TAG = "ConnectivityManager.CallbackHandler";
2124        private final ConnectivityManager mCm;
2125
2126        CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallback>callbackMap,
2127                AtomicInteger refCount, ConnectivityManager cm) {
2128            super(looper);
2129            mCallbackMap = callbackMap;
2130            mRefCount = refCount;
2131            mCm = cm;
2132        }
2133
2134        @Override
2135        public void handleMessage(Message message) {
2136            Log.d(TAG, "CM callback handler got msg " + message.what);
2137            switch (message.what) {
2138                case CALLBACK_PRECHECK: {
2139                    NetworkRequest request = (NetworkRequest)getObject(message,
2140                            NetworkRequest.class);
2141                    NetworkCallback callbacks = getCallbacks(request);
2142                    if (callbacks != null) {
2143                        callbacks.onPreCheck((Network)getObject(message, Network.class));
2144                    } else {
2145                        Log.e(TAG, "callback not found for PRECHECK message");
2146                    }
2147                    break;
2148                }
2149                case CALLBACK_AVAILABLE: {
2150                    NetworkRequest request = (NetworkRequest)getObject(message,
2151                            NetworkRequest.class);
2152                    NetworkCallback callbacks = getCallbacks(request);
2153                    if (callbacks != null) {
2154                        callbacks.onAvailable((Network)getObject(message, Network.class));
2155                    } else {
2156                        Log.e(TAG, "callback not found for AVAILABLE message");
2157                    }
2158                    break;
2159                }
2160                case CALLBACK_LOSING: {
2161                    NetworkRequest request = (NetworkRequest)getObject(message,
2162                            NetworkRequest.class);
2163                    NetworkCallback callbacks = getCallbacks(request);
2164                    if (callbacks != null) {
2165                        callbacks.onLosing((Network)getObject(message, Network.class),
2166                                message.arg1);
2167                    } else {
2168                        Log.e(TAG, "callback not found for LOSING message");
2169                    }
2170                    break;
2171                }
2172                case CALLBACK_LOST: {
2173                    NetworkRequest request = (NetworkRequest)getObject(message,
2174                            NetworkRequest.class);
2175
2176                    NetworkCallback callbacks = getCallbacks(request);
2177                    if (callbacks != null) {
2178                        callbacks.onLost((Network)getObject(message, Network.class));
2179                    } else {
2180                        Log.e(TAG, "callback not found for LOST message");
2181                    }
2182                    break;
2183                }
2184                case CALLBACK_UNAVAIL: {
2185                    NetworkRequest request = (NetworkRequest)getObject(message,
2186                            NetworkRequest.class);
2187                    NetworkCallback callbacks = null;
2188                    synchronized(mCallbackMap) {
2189                        callbacks = mCallbackMap.get(request);
2190                    }
2191                    if (callbacks != null) {
2192                        callbacks.onUnavailable();
2193                    } else {
2194                        Log.e(TAG, "callback not found for UNAVAIL message");
2195                    }
2196                    break;
2197                }
2198                case CALLBACK_CAP_CHANGED: {
2199                    NetworkRequest request = (NetworkRequest)getObject(message,
2200                            NetworkRequest.class);
2201                    NetworkCallback callbacks = getCallbacks(request);
2202                    if (callbacks != null) {
2203                        Network network = (Network)getObject(message, Network.class);
2204                        NetworkCapabilities cap = (NetworkCapabilities)getObject(message,
2205                                NetworkCapabilities.class);
2206
2207                        callbacks.onCapabilitiesChanged(network, cap);
2208                    } else {
2209                        Log.e(TAG, "callback not found for CAP_CHANGED message");
2210                    }
2211                    break;
2212                }
2213                case CALLBACK_IP_CHANGED: {
2214                    NetworkRequest request = (NetworkRequest)getObject(message,
2215                            NetworkRequest.class);
2216                    NetworkCallback callbacks = getCallbacks(request);
2217                    if (callbacks != null) {
2218                        Network network = (Network)getObject(message, Network.class);
2219                        LinkProperties lp = (LinkProperties)getObject(message,
2220                                LinkProperties.class);
2221
2222                        callbacks.onLinkPropertiesChanged(network, lp);
2223                    } else {
2224                        Log.e(TAG, "callback not found for IP_CHANGED message");
2225                    }
2226                    break;
2227                }
2228                case CALLBACK_RELEASED: {
2229                    NetworkRequest req = (NetworkRequest)getObject(message, NetworkRequest.class);
2230                    NetworkCallback callbacks = null;
2231                    synchronized(mCallbackMap) {
2232                        callbacks = mCallbackMap.remove(req);
2233                    }
2234                    if (callbacks != null) {
2235                        synchronized(mRefCount) {
2236                            if (mRefCount.decrementAndGet() == 0) {
2237                                getLooper().quit();
2238                            }
2239                        }
2240                    } else {
2241                        Log.e(TAG, "callback not found for CANCELED message");
2242                    }
2243                    break;
2244                }
2245                case CALLBACK_EXIT: {
2246                    Log.d(TAG, "Listener quiting");
2247                    getLooper().quit();
2248                    break;
2249                }
2250                case EXPIRE_LEGACY_REQUEST: {
2251                    expireRequest((NetworkCapabilities)message.obj, message.arg1);
2252                    break;
2253                }
2254            }
2255        }
2256
2257        private Object getObject(Message msg, Class c) {
2258            return msg.getData().getParcelable(c.getSimpleName());
2259        }
2260        private NetworkCallback getCallbacks(NetworkRequest req) {
2261            synchronized(mCallbackMap) {
2262                return mCallbackMap.get(req);
2263            }
2264        }
2265    }
2266
2267    private void incCallbackHandlerRefCount() {
2268        synchronized(sCallbackRefCount) {
2269            if (sCallbackRefCount.incrementAndGet() == 1) {
2270                // TODO - switch this over to a ManagerThread or expire it when done
2271                HandlerThread callbackThread = new HandlerThread("ConnectivityManager");
2272                callbackThread.start();
2273                sCallbackHandler = new CallbackHandler(callbackThread.getLooper(),
2274                        sNetworkCallback, sCallbackRefCount, this);
2275            }
2276        }
2277    }
2278
2279    private void decCallbackHandlerRefCount() {
2280        synchronized(sCallbackRefCount) {
2281            if (sCallbackRefCount.decrementAndGet() == 0) {
2282                sCallbackHandler.obtainMessage(CALLBACK_EXIT).sendToTarget();
2283                sCallbackHandler = null;
2284            }
2285        }
2286    }
2287
2288    static final HashMap<NetworkRequest, NetworkCallback> sNetworkCallback =
2289            new HashMap<NetworkRequest, NetworkCallback>();
2290    static final AtomicInteger sCallbackRefCount = new AtomicInteger(0);
2291    static CallbackHandler sCallbackHandler = null;
2292
2293    private final static int LISTEN  = 1;
2294    private final static int REQUEST = 2;
2295
2296    private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
2297            NetworkCallback networkCallback, int timeoutSec, int action,
2298            int legacyType) {
2299        if (networkCallback == null) {
2300            throw new IllegalArgumentException("null NetworkCallback");
2301        }
2302        if (need == null) throw new IllegalArgumentException("null NetworkCapabilities");
2303        try {
2304            incCallbackHandlerRefCount();
2305            synchronized(sNetworkCallback) {
2306                if (action == LISTEN) {
2307                    networkCallback.networkRequest = mService.listenForNetwork(need,
2308                            new Messenger(sCallbackHandler), new Binder());
2309                } else {
2310                    networkCallback.networkRequest = mService.requestNetwork(need,
2311                            new Messenger(sCallbackHandler), timeoutSec, new Binder(), legacyType);
2312                }
2313                if (networkCallback.networkRequest != null) {
2314                    sNetworkCallback.put(networkCallback.networkRequest, networkCallback);
2315                }
2316            }
2317        } catch (RemoteException e) {}
2318        if (networkCallback.networkRequest == null) decCallbackHandlerRefCount();
2319        return networkCallback.networkRequest;
2320    }
2321
2322    /**
2323     * Request a network to satisfy a set of {@link NetworkCapabilities}.
2324     *
2325     * This {@link NetworkRequest} will live until released via
2326     * {@link #unregisterNetworkCallback} or the calling application exits.
2327     * Status of the request can be followed by listening to the various
2328     * callbacks described in {@link NetworkCallback}.  The {@link Network}
2329     * can be used to direct traffic to the network.
2330     *
2331     * @param request {@link NetworkRequest} describing this request.
2332     * @param networkCallback The {@link NetworkCallback} to be utilized for this
2333     *                        request.  Note the callback must not be shared - they
2334     *                        uniquely specify this request.
2335     */
2336    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) {
2337        sendRequestForNetwork(request.networkCapabilities, networkCallback, 0,
2338                REQUEST, inferLegacyTypeForNetworkCapabilities(request.networkCapabilities));
2339    }
2340
2341    /**
2342     * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
2343     * by a timeout.
2344     *
2345     * This function behaves identically to the non-timedout version, but if a suitable
2346     * network is not found within the given time (in milliseconds) the
2347     * {@link NetworkCallback#unavailable} callback is called.  The request must
2348     * still be released normally by calling {@link releaseNetworkRequest}.
2349     * @param request {@link NetworkRequest} describing this request.
2350     * @param networkCallback The callbacks to be utilized for this request.  Note
2351     *                        the callbacks must not be shared - they uniquely specify
2352     *                        this request.
2353     * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
2354     *                  before {@link NetworkCallback#unavailable} is called.
2355     * @hide
2356     */
2357    public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
2358            int timeoutMs) {
2359        sendRequestForNetwork(request.networkCapabilities, networkCallback, timeoutMs,
2360                REQUEST, inferLegacyTypeForNetworkCapabilities(request.networkCapabilities));
2361    }
2362
2363    /**
2364     * The maximum number of milliseconds the framework will look for a suitable network
2365     * during a timeout-equiped call to {@link requestNetwork}.
2366     * {@hide}
2367     */
2368    public final static int MAX_NETWORK_REQUEST_TIMEOUT_MS = 100 * 60 * 1000;
2369
2370    /**
2371     * The lookup key for a {@link Network} object included with the intent after
2372     * successfully finding a network for the applications request.  Retrieve it with
2373     * {@link android.content.Intent#getParcelableExtra(String)}.
2374     */
2375    public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
2376
2377    /**
2378     * The lookup key for a {@link NetworkRequest} object included with the intent after
2379     * successfully finding a network for the applications request.  Retrieve it with
2380     * {@link android.content.Intent#getParcelableExtra(String)}.
2381     */
2382    public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
2383
2384
2385    /**
2386     * Request a network to satisfy a set of {@link NetworkCapabilities}.
2387     *
2388     * This function behaves identically to the version that takes a NetworkCallback, but instead
2389     * of {@link NetworkCallback} a {@link PendingIntent} is used.  This means
2390     * the request may outlive the calling application and get called back when a suitable
2391     * network is found.
2392     * <p>
2393     * The operation is an Intent broadcast that goes to a broadcast receiver that
2394     * you registered with {@link Context#registerReceiver} or through the
2395     * &lt;receiver&gt; tag in an AndroidManifest.xml file
2396     * <p>
2397     * The operation Intent is delivered with two extras, a {@link Network} typed
2398     * extra called {@link #EXTRA_NETWORK} and a {@link NetworkRequest}
2399     * typed extra called {@link #EXTRA_NETWORK_REQUEST} containing
2400     * the original requests parameters.  It is important to create a new,
2401     * {@link NetworkCallback} based request before completing the processing of the
2402     * Intent to reserve the network or it will be released shortly after the Intent
2403     * is processed.
2404     * <p>
2405     * If there is already an request for this Intent registered (with the equality of
2406     * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
2407     * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
2408     * <p>
2409     * The request may be released normally by calling
2410     * {@link #releaseNetworkRequest(android.app.PendingIntent)}.
2411     *
2412     * @param request {@link NetworkRequest} describing this request.
2413     * @param operation Action to perform when the network is available (corresponds
2414     *                  to the {@link NetworkCallback#onAvailable} call.  Typically
2415     *                  comes from {@link PendingIntent#getBroadcast}. Cannot be null.
2416     */
2417    public void requestNetwork(NetworkRequest request, PendingIntent operation) {
2418        checkPendingIntent(operation);
2419        try {
2420            mService.pendingRequestForNetwork(request.networkCapabilities, operation);
2421        } catch (RemoteException e) {}
2422    }
2423
2424    /**
2425     * Removes a request made via {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)}
2426     * <p>
2427     * This method has the same behavior as {@link #unregisterNetworkCallback} with respect to
2428     * releasing network resources and disconnecting.
2429     *
2430     * @param operation A PendingIntent equal (as defined by {@link Intent#filterEquals}) to the
2431     *                  PendingIntent passed to
2432     *                  {@link #requestNetwork(NetworkRequest, android.app.PendingIntent)} with the
2433     *                  corresponding NetworkRequest you'd like to remove. Cannot be null.
2434     */
2435    public void releaseNetworkRequest(PendingIntent operation) {
2436        checkPendingIntent(operation);
2437        try {
2438            mService.releasePendingNetworkRequest(operation);
2439        } catch (RemoteException e) {}
2440    }
2441
2442    private void checkPendingIntent(PendingIntent intent) {
2443        if (intent == null) {
2444            throw new IllegalArgumentException("PendingIntent cannot be null.");
2445        }
2446    }
2447
2448    /**
2449     * Registers to receive notifications about all networks which satisfy the given
2450     * {@link NetworkRequest}.  The callbacks will continue to be called until
2451     * either the application exits or {@link #unregisterNetworkCallback} is called
2452     *
2453     * @param request {@link NetworkRequest} describing this request.
2454     * @param networkCallback The {@link NetworkCallback} that the system will call as suitable
2455     *                        networks change state.
2456     */
2457    public void registerNetworkCallback(NetworkRequest request, NetworkCallback networkCallback) {
2458        sendRequestForNetwork(request.networkCapabilities, networkCallback, 0, LISTEN, TYPE_NONE);
2459    }
2460
2461    /**
2462     * Unregisters callbacks about and possibly releases networks originating from
2463     * {@link #requestNetwork} and {@link #registerNetworkCallback} calls.  If the
2464     * given {@code NetworkCallback} had previously been used with {@code #requestNetwork},
2465     * any networks that had been connected to only to satisfy that request will be
2466     * disconnected.
2467     *
2468     * @param networkCallback The {@link NetworkCallback} used when making the request.
2469     */
2470    public void unregisterNetworkCallback(NetworkCallback networkCallback) {
2471        if (networkCallback == null || networkCallback.networkRequest == null ||
2472                networkCallback.networkRequest.requestId == REQUEST_ID_UNSET) {
2473            throw new IllegalArgumentException("Invalid NetworkCallback");
2474        }
2475        try {
2476            mService.releaseNetworkRequest(networkCallback.networkRequest);
2477        } catch (RemoteException e) {}
2478    }
2479
2480    /**
2481     * Binds the current process to {@code network}.  All Sockets created in the future
2482     * (and not explicitly bound via a bound SocketFactory from
2483     * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
2484     * {@code network}.  All host name resolutions will be limited to {@code network} as well.
2485     * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
2486     * work and all host name resolutions will fail.  This is by design so an application doesn't
2487     * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
2488     * To clear binding pass {@code null} for {@code network}.  Using individually bound
2489     * Sockets created by Network.getSocketFactory().createSocket() and
2490     * performing network-specific host name resolutions via
2491     * {@link Network#getAllByName Network.getAllByName} is preferred to calling
2492     * {@code setProcessDefaultNetwork}.
2493     *
2494     * @param network The {@link Network} to bind the current process to, or {@code null} to clear
2495     *                the current binding.
2496     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
2497     */
2498    public static boolean setProcessDefaultNetwork(Network network) {
2499        int netId = (network == null) ? NETID_UNSET : network.netId;
2500        if (netId == NetworkUtils.getNetworkBoundToProcess()) {
2501            return true;
2502        }
2503        if (NetworkUtils.bindProcessToNetwork(netId)) {
2504            // Set HTTP proxy system properties to match network.
2505            // TODO: Deprecate this static method and replace it with a non-static version.
2506            Proxy.setHttpProxySystemProperty(getInstance().getDefaultProxy());
2507            // Must flush DNS cache as new network may have different DNS resolutions.
2508            InetAddress.clearDnsCache();
2509            // Must flush socket pool as idle sockets will be bound to previous network and may
2510            // cause subsequent fetches to be performed on old network.
2511            NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
2512            return true;
2513        } else {
2514            return false;
2515        }
2516    }
2517
2518    /**
2519     * Returns the {@link Network} currently bound to this process via
2520     * {@link #setProcessDefaultNetwork}, or {@code null} if no {@link Network} is explicitly bound.
2521     *
2522     * @return {@code Network} to which this process is bound, or {@code null}.
2523     */
2524    public static Network getProcessDefaultNetwork() {
2525        int netId = NetworkUtils.getNetworkBoundToProcess();
2526        if (netId == NETID_UNSET) return null;
2527        return new Network(netId);
2528    }
2529
2530    /**
2531     * Binds host resolutions performed by this process to {@code network}.
2532     * {@link #setProcessDefaultNetwork} takes precedence over this setting.
2533     *
2534     * @param network The {@link Network} to bind host resolutions from the current process to, or
2535     *                {@code null} to clear the current binding.
2536     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
2537     * @hide
2538     * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}.
2539     */
2540    public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
2541        return NetworkUtils.bindProcessToNetworkForHostResolution(
2542                network == null ? NETID_UNSET : network.netId);
2543    }
2544}
2545