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