blob: 65e772cb5ebb961cb1756cc09ef4a284c8b5e25c [file] [log] [blame]
Robert Greenwalt7b816022014-04-18 15:25:25 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net;
18
Chalard Jeanf1dec612020-03-24 23:16:35 +090019import android.annotation.IntDef;
20import android.annotation.IntRange;
lucaslinc2bac512019-11-07 16:47:56 +080021import android.annotation.NonNull;
Lorenzo Colitti631f33a2020-01-15 00:13:37 +090022import android.annotation.Nullable;
23import android.annotation.SystemApi;
Artur Satayev33f92172019-12-10 17:47:52 +000024import android.compat.annotation.UnsupportedAppUsage;
Robert Greenwalt7b816022014-04-18 15:25:25 -070025import android.content.Context;
Mathew Inwood31755f92018-12-20 13:53:36 +000026import android.os.Build;
Erik Kline9d598e12015-07-13 16:37:51 +090027import android.os.Bundle;
Chalard Jean0348de62020-04-13 16:09:41 +000028import android.os.ConditionVariable;
Robert Greenwalt7b816022014-04-18 15:25:25 -070029import android.os.Handler;
30import android.os.Looper;
31import android.os.Message;
32import android.os.Messenger;
Robert Greenwalt7b816022014-04-18 15:25:25 -070033import android.util.Log;
Robert Greenwalt7b816022014-04-18 15:25:25 -070034
Chalard Jean0348de62020-04-13 16:09:41 +000035import com.android.internal.annotations.VisibleForTesting;
Robert Greenwalt7b816022014-04-18 15:25:25 -070036import com.android.internal.util.AsyncChannel;
37import com.android.internal.util.Protocol;
38
Chalard Jeanf1dec612020-03-24 23:16:35 +090039import java.lang.annotation.Retention;
40import java.lang.annotation.RetentionPolicy;
Chalard Jeanb0e1e7e2020-03-27 15:00:38 +090041import java.time.Duration;
Robert Greenwalt3192dec2014-05-27 13:20:24 -070042import java.util.ArrayList;
Chalard Jean339ba3f2020-01-15 04:38:56 +090043import java.util.Objects;
fenglu95ce8032015-05-01 17:04:36 -070044import java.util.concurrent.atomic.AtomicBoolean;
Robert Greenwalt7b816022014-04-18 15:25:25 -070045
46/**
Chalard Jeanf1dec612020-03-24 23:16:35 +090047 * A utility class for handling for communicating between bearer-specific
Robert Greenwalt3192dec2014-05-27 13:20:24 -070048 * code and ConnectivityService.
Robert Greenwalt7b816022014-04-18 15:25:25 -070049 *
Chalard Jeanf1dec612020-03-24 23:16:35 +090050 * An agent manages the life cycle of a network. A network starts its
51 * life cycle when {@link register} is called on NetworkAgent. The network
52 * is then connecting. When full L3 connectivity has been established,
Chalard Jeanb0e1e7e2020-03-27 15:00:38 +090053 * the agent shoud call {@link markConnected} to inform the system that
Chalard Jeanf1dec612020-03-24 23:16:35 +090054 * this network is ready to use. When the network disconnects its life
55 * ends and the agent should call {@link unregister}, at which point the
56 * system will clean up and free resources.
57 * Any reconnection becomes a new logical network, so after a network
58 * is disconnected the agent cannot be used any more. Network providers
59 * should create a new NetworkAgent instance to handle new connections.
60 *
Robert Greenwalt7b816022014-04-18 15:25:25 -070061 * A bearer may have more than one NetworkAgent if it can simultaneously
62 * support separate networks (IMS / Internet / MMS Apns on cellular, or
Robert Greenwalt3192dec2014-05-27 13:20:24 -070063 * perhaps connections with different SSID or P2P for Wi-Fi).
Robert Greenwalt7b816022014-04-18 15:25:25 -070064 *
Chalard Jeanf1dec612020-03-24 23:16:35 +090065 * This class supports methods to start and stop sending keepalive packets.
66 * Keepalive packets are typically sent at periodic intervals over a network
67 * with NAT when there is no other traffic to avoid the network forcefully
68 * closing the connection. NetworkAgents that manage technologies that
69 * have hardware support for keepalive should implement the related
70 * methods to save battery life. NetworkAgent that cannot get support
71 * without waking up the CPU should not, as this would be prohibitive in
72 * terms of battery - these agents should simply not override the related
73 * methods, which results in the implementation returning
74 * {@link SocketKeepalive.ERROR_UNSUPPORTED} as appropriate.
75 *
76 * Keepalive packets need to be sent at relatively frequent intervals
77 * (a few seconds to a few minutes). As the contents of keepalive packets
78 * depend on the current network status, hardware needs to be configured
79 * to send them and has a limited amount of memory to do so. The HAL
80 * formalizes this as slots that an implementation can configure to send
81 * the correct packets. Devices typically have a small number of slots
82 * per radio technology, and the specific number of slots for each
83 * technology is specified in configuration files.
84 * {@see SocketKeepalive} for details.
85 *
Robert Greenwalt7b816022014-04-18 15:25:25 -070086 * @hide
87 */
Lorenzo Colitti631f33a2020-01-15 00:13:37 +090088@SystemApi
Lorenzo Colitti782b48d52020-01-12 20:27:32 +090089public abstract class NetworkAgent {
Lorenzo Colitti631f33a2020-01-15 00:13:37 +090090 /**
91 * The {@link Network} corresponding to this object.
92 */
Chalard Jean29c6e0c2020-01-16 17:13:26 +090093 @Nullable
94 private volatile Network mNetwork;
Paul Jensen31a94f42015-02-13 14:18:39 -050095
Chalard Jean339ba3f2020-01-15 04:38:56 +090096 // Whether this NetworkAgent is using the legacy (never unhidden) API. The difference is
97 // that the legacy API uses NetworkInfo to convey the state, while the current API is
98 // exposing methods to manage it and generate it internally instead.
99 // TODO : remove this as soon as all agents have been converted.
100 private final boolean mIsLegacy;
101
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900102 private final Handler mHandler;
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700103 private volatile AsyncChannel mAsyncChannel;
Robert Greenwalt7b816022014-04-18 15:25:25 -0700104 private final String LOG_TAG;
105 private static final boolean DBG = true;
Robert Greenwaltfc0c6892014-08-27 14:34:02 -0700106 private static final boolean VDBG = false;
Chalard Jeanf1dec612020-03-24 23:16:35 +0900107 private final ArrayList<Message> mPreConnectedQueue = new ArrayList<Message>();
fenglub15e72b2015-03-20 11:29:56 -0700108 private volatile long mLastBwRefreshTime = 0;
109 private static final long BW_REFRESH_MIN_WIN_MS = 500;
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900110 private boolean mBandwidthUpdateScheduled = false;
111 private AtomicBoolean mBandwidthUpdatePending = new AtomicBoolean(false);
Chalard Jean339ba3f2020-01-15 04:38:56 +0900112 // Not used by legacy agents. Non-legacy agents use this to convert the NetworkAgent system API
113 // into the internal API of ConnectivityService.
114 @NonNull
115 private NetworkInfo mNetworkInfo;
Chalard Jeanf1dec612020-03-24 23:16:35 +0900116 @NonNull
117 private final Object mRegisterLock = new Object();
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900118
119 /**
120 * The ID of the {@link NetworkProvider} that created this object, or
121 * {@link NetworkProvider#ID_NONE} if unknown.
Aaron Huangf68546e2020-03-12 17:52:33 +0800122 * @hide
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900123 */
124 public final int providerId;
Robert Greenwalt7b816022014-04-18 15:25:25 -0700125
126 private static final int BASE = Protocol.BASE_NETWORK_AGENT;
127
128 /**
Robert Greenwalt7b816022014-04-18 15:25:25 -0700129 * Sent by ConnectivityService to the NetworkAgent to inform it of
130 * suspected connectivity problems on its network. The NetworkAgent
131 * should take steps to verify and correct connectivity.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900132 * @hide
Robert Greenwalt7b816022014-04-18 15:25:25 -0700133 */
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700134 public static final int CMD_SUSPECT_BAD = BASE;
Robert Greenwalt7b816022014-04-18 15:25:25 -0700135
136 /**
137 * Sent by the NetworkAgent (note the EVENT vs CMD prefix) to
138 * ConnectivityService to pass the current NetworkInfo (connection state).
139 * Sent when the NetworkInfo changes, mainly due to change of state.
140 * obj = NetworkInfo
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900141 * @hide
Robert Greenwalt7b816022014-04-18 15:25:25 -0700142 */
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700143 public static final int EVENT_NETWORK_INFO_CHANGED = BASE + 1;
Robert Greenwalt7b816022014-04-18 15:25:25 -0700144
145 /**
146 * Sent by the NetworkAgent to ConnectivityService to pass the current
147 * NetworkCapabilties.
148 * obj = NetworkCapabilities
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900149 * @hide
Robert Greenwalt7b816022014-04-18 15:25:25 -0700150 */
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700151 public static final int EVENT_NETWORK_CAPABILITIES_CHANGED = BASE + 2;
Robert Greenwalt7b816022014-04-18 15:25:25 -0700152
153 /**
154 * Sent by the NetworkAgent to ConnectivityService to pass the current
155 * NetworkProperties.
156 * obj = NetworkProperties
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900157 * @hide
Robert Greenwalt7b816022014-04-18 15:25:25 -0700158 */
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700159 public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3;
Robert Greenwalt7b816022014-04-18 15:25:25 -0700160
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900161 /**
Chalard Jeana11593c2020-02-21 19:37:21 +0900162 * Centralize the place where base network score, and network score scaling, will be
163 * stored, so as we can consistently compare apple and oranges, or wifi, ethernet and LTE
164 * @hide
165 */
166 public static final int WIFI_BASE_SCORE = 60;
167
168 /**
Robert Greenwalt7b816022014-04-18 15:25:25 -0700169 * Sent by the NetworkAgent to ConnectivityService to pass the current
170 * network score.
Automerger Merge Worker3d40f5782020-03-08 06:07:47 +0000171 * arg1 = network score int
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900172 * @hide
Robert Greenwalt7b816022014-04-18 15:25:25 -0700173 */
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700174 public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4;
Robert Greenwalt7b816022014-04-18 15:25:25 -0700175
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400176 /**
Lorenzo Colittie03c3c72015-04-03 16:38:52 +0900177 * Sent by ConnectivityService to the NetworkAgent to inform the agent of the
Robert Greenwalt49f63fb2014-09-13 12:04:12 -0700178 * networks status - whether we could use the network or could not, due to
179 * either a bad network configuration (no internet link) or captive portal.
180 *
181 * arg1 = either {@code VALID_NETWORK} or {@code INVALID_NETWORK}
Paul Jensen232437312016-04-06 09:51:26 -0400182 * obj = Bundle containing map from {@code REDIRECT_URL_KEY} to {@code String}
183 * representing URL that Internet probe was redirect to, if it was redirected,
184 * or mapping to {@code null} otherwise.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900185 * @hide
Robert Greenwalt49f63fb2014-09-13 12:04:12 -0700186 */
Lorenzo Colitti60446162014-09-20 00:14:31 +0900187 public static final int CMD_REPORT_NETWORK_STATUS = BASE + 7;
Robert Greenwalt49f63fb2014-09-13 12:04:12 -0700188
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900189
190 /**
191 * Network validation suceeded.
192 * Corresponds to {@link NetworkCapabilities.NET_CAPABILITY_VALIDATED}.
193 */
194 public static final int VALIDATION_STATUS_VALID = 1;
195
196 /**
197 * Network validation was attempted and failed. This may be received more than once as
198 * subsequent validation attempts are made.
199 */
200 public static final int VALIDATION_STATUS_NOT_VALID = 2;
201
Chalard Jeanf1dec612020-03-24 23:16:35 +0900202 /** @hide */
203 @Retention(RetentionPolicy.SOURCE)
204 @IntDef(prefix = { "VALIDATION_STATUS_" }, value = {
205 VALIDATION_STATUS_VALID,
206 VALIDATION_STATUS_NOT_VALID
207 })
208 public @interface ValidationStatus {}
209
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900210 // TODO: remove.
211 /** @hide */
Robert Greenwalt49f63fb2014-09-13 12:04:12 -0700212 public static final int VALID_NETWORK = 1;
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900213 /** @hide */
Robert Greenwalt49f63fb2014-09-13 12:04:12 -0700214 public static final int INVALID_NETWORK = 2;
215
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900216 /**
217 * The key for the redirect URL in the Bundle argument of {@code CMD_REPORT_NETWORK_STATUS}.
218 * @hide
219 */
Paul Jensen232437312016-04-06 09:51:26 -0400220 public static String REDIRECT_URL_KEY = "redirect URL";
221
Robert Greenwalte73cc462014-09-07 16:50:01 -0700222 /**
223 * Sent by the NetworkAgent to ConnectivityService to indicate this network was
224 * explicitly selected. This should be sent before the NetworkInfo is marked
225 * CONNECTED so it can be given special treatment at that time.
Lorenzo Colittie03c3c72015-04-03 16:38:52 +0900226 *
227 * obj = boolean indicating whether to use this network even if unvalidated
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900228 * @hide
Robert Greenwalte73cc462014-09-07 16:50:01 -0700229 */
Lorenzo Colitti60446162014-09-20 00:14:31 +0900230 public static final int EVENT_SET_EXPLICITLY_SELECTED = BASE + 8;
Robert Greenwalte73cc462014-09-07 16:50:01 -0700231
Lorenzo Colittie03c3c72015-04-03 16:38:52 +0900232 /**
233 * Sent by ConnectivityService to the NetworkAgent to inform the agent of
234 * whether the network should in the future be used even if not validated.
235 * This decision is made by the user, but it is the network transport's
236 * responsibility to remember it.
237 *
238 * arg1 = 1 if true, 0 if false
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900239 * @hide
Lorenzo Colittie03c3c72015-04-03 16:38:52 +0900240 */
241 public static final int CMD_SAVE_ACCEPT_UNVALIDATED = BASE + 9;
242
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900243 /**
244 * Sent by ConnectivityService to the NetworkAgent to inform the agent to pull
fenglub15e72b2015-03-20 11:29:56 -0700245 * the underlying network connection for updated bandwidth information.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900246 * @hide
fenglub15e72b2015-03-20 11:29:56 -0700247 */
248 public static final int CMD_REQUEST_BANDWIDTH_UPDATE = BASE + 10;
249
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900250 /**
251 * Sent by ConnectivityService to the NetworkAgent to request that the specified packet be sent
252 * periodically on the given interval.
253 *
Chalard Jeanf1dec612020-03-24 23:16:35 +0900254 * arg1 = the hardware slot number of the keepalive to start
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900255 * arg2 = interval in seconds
256 * obj = KeepalivePacketData object describing the data to be sent
257 *
258 * Also used internally by ConnectivityService / KeepaliveTracker, with different semantics.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900259 * @hide
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900260 */
junyulaie4135282019-01-03 18:50:15 +0800261 public static final int CMD_START_SOCKET_KEEPALIVE = BASE + 11;
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900262
263 /**
264 * Requests that the specified keepalive packet be stopped.
265 *
Chalard Jeanf1dec612020-03-24 23:16:35 +0900266 * arg1 = hardware slot number of the keepalive to stop.
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900267 *
268 * Also used internally by ConnectivityService / KeepaliveTracker, with different semantics.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900269 * @hide
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900270 */
junyulaie4135282019-01-03 18:50:15 +0800271 public static final int CMD_STOP_SOCKET_KEEPALIVE = BASE + 12;
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900272
273 /**
junyulaie4135282019-01-03 18:50:15 +0800274 * Sent by the NetworkAgent to ConnectivityService to provide status on a socket keepalive
275 * request. This may either be the reply to a CMD_START_SOCKET_KEEPALIVE, or an asynchronous
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900276 * error notification.
277 *
junyulaie4135282019-01-03 18:50:15 +0800278 * This is also sent by KeepaliveTracker to the app's {@link SocketKeepalive},
279 * so that the app's {@link SocketKeepalive.Callback} methods can be called.
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900280 *
Chalard Jeanf1dec612020-03-24 23:16:35 +0900281 * arg1 = hardware slot number of the keepalive
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900282 * arg2 = error code
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900283 * @hide
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900284 */
junyulaie4135282019-01-03 18:50:15 +0800285 public static final int EVENT_SOCKET_KEEPALIVE = BASE + 13;
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900286
junyulai76baf5f2019-05-17 22:13:02 +0800287 /**
288 * Sent by ConnectivityService to inform this network transport of signal strength thresholds
289 * that when crossed should trigger a system wakeup and a NetworkCapabilities update.
290 *
291 * obj = int[] describing signal strength thresholds.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900292 * @hide
junyulai76baf5f2019-05-17 22:13:02 +0800293 */
294 public static final int CMD_SET_SIGNAL_STRENGTH_THRESHOLDS = BASE + 14;
295
296 /**
297 * Sent by ConnectivityService to the NeworkAgent to inform the agent to avoid
298 * automatically reconnecting to this network (e.g. via autojoin). Happens
299 * when user selects "No" option on the "Stay connected?" dialog box.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900300 * @hide
junyulai76baf5f2019-05-17 22:13:02 +0800301 */
302 public static final int CMD_PREVENT_AUTOMATIC_RECONNECT = BASE + 15;
303
junyulai352dc2f2019-01-08 20:04:33 +0800304 /**
305 * Sent by the KeepaliveTracker to NetworkAgent to add a packet filter.
306 *
307 * For TCP keepalive offloads, keepalive packets are sent by the firmware. However, because the
308 * remote site will send ACK packets in response to the keepalive packets, the firmware also
309 * needs to be configured to properly filter the ACKs to prevent the system from waking up.
310 * This does not happen with UDP, so this message is TCP-specific.
Chalard Jeanf1dec612020-03-24 23:16:35 +0900311 * arg1 = hardware slot number of the keepalive to filter for.
junyulai352dc2f2019-01-08 20:04:33 +0800312 * obj = the keepalive packet to send repeatedly.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900313 * @hide
junyulai352dc2f2019-01-08 20:04:33 +0800314 */
315 public static final int CMD_ADD_KEEPALIVE_PACKET_FILTER = BASE + 16;
316
317 /**
318 * Sent by the KeepaliveTracker to NetworkAgent to remove a packet filter. See
319 * {@link #CMD_ADD_KEEPALIVE_PACKET_FILTER}.
Chalard Jeanf1dec612020-03-24 23:16:35 +0900320 * arg1 = hardware slot number of the keepalive packet filter to remove.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900321 * @hide
junyulai352dc2f2019-01-08 20:04:33 +0800322 */
323 public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17;
324
Chalard Jean3b680ae2020-01-15 04:01:53 +0900325 /** @hide TODO: remove and replace usage with the public constructor. */
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700326 public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
327 NetworkCapabilities nc, LinkProperties lp, int score) {
Lorenzo Colitti6654b082020-01-10 00:40:28 +0900328 this(looper, context, logTag, ni, nc, lp, score, null, NetworkProvider.ID_NONE);
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900329 // Register done by the constructor called in the previous line
Chalard Jean08577fc2018-05-02 21:14:54 +0900330 }
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900331
Chalard Jean3b680ae2020-01-15 04:01:53 +0900332 /** @hide TODO: remove and replace usage with the public constructor. */
Chalard Jean08577fc2018-05-02 21:14:54 +0900333 public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
Lorenzo Colittid9696562020-01-12 22:28:37 +0900334 NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config) {
335 this(looper, context, logTag, ni, nc, lp, score, config, NetworkProvider.ID_NONE);
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900336 // Register done by the constructor called in the previous line
Sreeram Ramachandran8cd33ed2014-07-23 15:23:15 -0700337 }
338
Chalard Jean3b680ae2020-01-15 04:01:53 +0900339 /** @hide TODO: remove and replace usage with the public constructor. */
Sreeram Ramachandran8cd33ed2014-07-23 15:23:15 -0700340 public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
Lorenzo Colitti6654b082020-01-10 00:40:28 +0900341 NetworkCapabilities nc, LinkProperties lp, int score, int providerId) {
342 this(looper, context, logTag, ni, nc, lp, score, null, providerId);
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900343 // Register done by the constructor called in the previous line
Chalard Jean08577fc2018-05-02 21:14:54 +0900344 }
345
Chalard Jean3b680ae2020-01-15 04:01:53 +0900346 /** @hide TODO: remove and replace usage with the public constructor. */
Chalard Jean08577fc2018-05-02 21:14:54 +0900347 public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
Lorenzo Colittid9696562020-01-12 22:28:37 +0900348 NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config,
Lorenzo Colitti6654b082020-01-10 00:40:28 +0900349 int providerId) {
Chalard Jeana11593c2020-02-21 19:37:21 +0900350 this(looper, context, logTag, nc, lp, score, config, providerId, ni, true /* legacy */);
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900351 register();
Chalard Jean3b680ae2020-01-15 04:01:53 +0900352 }
353
354 private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) {
355 // The subtype can be changed with (TODO) setLegacySubtype, but it starts
356 // with the type and an empty description.
Lorenzo Colitti0a39e0e2020-01-23 09:33:48 +0900357 final NetworkInfo ni = new NetworkInfo(config.legacyType, config.legacyType,
358 config.legacyTypeName, "");
359 ni.setIsAvailable(true);
360 return ni;
Chalard Jean3b680ae2020-01-15 04:01:53 +0900361 }
362
363 /**
364 * Create a new network agent.
365 * @param context a {@link Context} to get system services from.
366 * @param looper the {@link Looper} on which to invoke the callbacks.
367 * @param logTag the tag for logs
368 * @param nc the initial {@link NetworkCapabilities} of this network. Update with
369 * sendNetworkCapabilities.
370 * @param lp the initial {@link LinkProperties} of this network. Update with sendLinkProperties.
371 * @param score the initial score of this network. Update with sendNetworkScore.
372 * @param config an immutable {@link NetworkAgentConfig} for this agent.
373 * @param provider the {@link NetworkProvider} managing this agent.
374 */
375 public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag,
Chalard Jeana11593c2020-02-21 19:37:21 +0900376 @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
377 @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) {
Chalard Jean3b680ae2020-01-15 04:01:53 +0900378 this(looper, context, logTag, nc, lp, score, config,
379 provider == null ? NetworkProvider.ID_NONE : provider.getProviderId(),
Chalard Jean339ba3f2020-01-15 04:38:56 +0900380 getLegacyNetworkInfo(config), false /* legacy */);
Chalard Jean3b680ae2020-01-15 04:01:53 +0900381 }
382
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900383 private static class InitialConfiguration {
384 public final Context context;
385 public final NetworkCapabilities capabilities;
386 public final LinkProperties properties;
Chalard Jeana11593c2020-02-21 19:37:21 +0900387 public final int score;
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900388 public final NetworkAgentConfig config;
389 public final NetworkInfo info;
390 InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities,
Chalard Jeana11593c2020-02-21 19:37:21 +0900391 @NonNull LinkProperties properties, int score, @NonNull NetworkAgentConfig config,
392 @NonNull NetworkInfo info) {
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900393 this.context = context;
394 this.capabilities = capabilities;
395 this.properties = properties;
396 this.score = score;
397 this.config = config;
398 this.info = info;
399 }
400 }
401 private volatile InitialConfiguration mInitialConfiguration;
402
403 private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag,
Chalard Jeana11593c2020-02-21 19:37:21 +0900404 @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900405 @NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni,
406 boolean legacy) {
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900407 mHandler = new NetworkAgentHandler(looper);
Robert Greenwalt7b816022014-04-18 15:25:25 -0700408 LOG_TAG = logTag;
Chalard Jean339ba3f2020-01-15 04:38:56 +0900409 mIsLegacy = legacy;
410 mNetworkInfo = new NetworkInfo(ni);
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900411 this.providerId = providerId;
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700412 if (ni == null || nc == null || lp == null) {
413 throw new IllegalArgumentException();
Robert Greenwalt7b816022014-04-18 15:25:25 -0700414 }
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700415
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900416 mInitialConfiguration = new InitialConfiguration(context, new NetworkCapabilities(nc),
417 new LinkProperties(lp), score, config, ni);
Robert Greenwalt7b816022014-04-18 15:25:25 -0700418 }
419
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900420 private class NetworkAgentHandler extends Handler {
421 NetworkAgentHandler(Looper looper) {
422 super(looper);
423 }
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900424
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900425 @Override
426 public void handleMessage(Message msg) {
427 switch (msg.what) {
428 case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
429 if (mAsyncChannel != null) {
430 log("Received new connection while already connected!");
431 } else {
432 if (VDBG) log("NetworkAgent fully connected");
433 AsyncChannel ac = new AsyncChannel();
434 ac.connected(null, this, msg.replyTo);
435 ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
436 AsyncChannel.STATUS_SUCCESSFUL);
437 synchronized (mPreConnectedQueue) {
438 mAsyncChannel = ac;
439 for (Message m : mPreConnectedQueue) {
440 ac.sendMessage(m);
441 }
442 mPreConnectedQueue.clear();
443 }
444 }
445 break;
Erik Kline9d598e12015-07-13 16:37:51 +0900446 }
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900447 case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
448 if (VDBG) log("CMD_CHANNEL_DISCONNECT");
449 if (mAsyncChannel != null) mAsyncChannel.disconnect();
450 break;
451 }
452 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
453 if (DBG) log("NetworkAgent channel lost");
454 // let the client know CS is done with us.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900455 onNetworkUnwanted();
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900456 synchronized (mPreConnectedQueue) {
457 mAsyncChannel = null;
458 }
459 break;
460 }
461 case CMD_SUSPECT_BAD: {
462 log("Unhandled Message " + msg);
463 break;
464 }
465 case CMD_REQUEST_BANDWIDTH_UPDATE: {
466 long currentTimeMs = System.currentTimeMillis();
467 if (VDBG) {
468 log("CMD_REQUEST_BANDWIDTH_UPDATE request received.");
469 }
470 if (currentTimeMs >= (mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS)) {
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900471 mBandwidthUpdateScheduled = false;
472 if (!mBandwidthUpdatePending.getAndSet(true)) {
473 onBandwidthUpdateRequested();
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900474 }
475 } else {
476 // deliver the request at a later time rather than discard it completely.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900477 if (!mBandwidthUpdateScheduled) {
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900478 long waitTime = mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS
479 - currentTimeMs + 1;
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900480 mBandwidthUpdateScheduled = sendEmptyMessageDelayed(
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900481 CMD_REQUEST_BANDWIDTH_UPDATE, waitTime);
482 }
483 }
484 break;
485 }
486 case CMD_REPORT_NETWORK_STATUS: {
487 String redirectUrl = ((Bundle) msg.obj).getString(REDIRECT_URL_KEY);
488 if (VDBG) {
489 log("CMD_REPORT_NETWORK_STATUS("
490 + (msg.arg1 == VALID_NETWORK ? "VALID, " : "INVALID, ")
491 + redirectUrl);
492 }
Chalard Jeanf1dec612020-03-24 23:16:35 +0900493 Uri uri = null;
494 try {
495 if (null != redirectUrl) {
496 uri = Uri.parse(redirectUrl);
497 }
498 } catch (Exception e) {
499 Log.wtf(LOG_TAG, "Surprising URI : " + redirectUrl, e);
500 }
501 onValidationStatus(msg.arg1 /* status */, uri);
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900502 break;
503 }
504 case CMD_SAVE_ACCEPT_UNVALIDATED: {
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900505 onSaveAcceptUnvalidated(msg.arg1 != 0);
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900506 break;
507 }
508 case CMD_START_SOCKET_KEEPALIVE: {
Chalard Jeanb0e1e7e2020-03-27 15:00:38 +0900509 onStartSocketKeepalive(msg.arg1 /* slot */,
510 Duration.ofSeconds(msg.arg2) /* interval */,
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900511 (KeepalivePacketData) msg.obj /* packet */);
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900512 break;
513 }
514 case CMD_STOP_SOCKET_KEEPALIVE: {
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900515 onStopSocketKeepalive(msg.arg1 /* slot */);
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900516 break;
517 }
518
519 case CMD_SET_SIGNAL_STRENGTH_THRESHOLDS: {
520 ArrayList<Integer> thresholds =
521 ((Bundle) msg.obj).getIntegerArrayList("thresholds");
522 // TODO: Change signal strength thresholds API to use an ArrayList<Integer>
523 // rather than convert to int[].
524 int[] intThresholds = new int[(thresholds != null) ? thresholds.size() : 0];
525 for (int i = 0; i < intThresholds.length; i++) {
526 intThresholds[i] = thresholds.get(i);
527 }
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900528 onSignalStrengthThresholdsUpdated(intThresholds);
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900529 break;
530 }
531 case CMD_PREVENT_AUTOMATIC_RECONNECT: {
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900532 onAutomaticReconnectDisabled();
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900533 break;
534 }
535 case CMD_ADD_KEEPALIVE_PACKET_FILTER: {
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900536 onAddKeepalivePacketFilter(msg.arg1 /* slot */,
537 (KeepalivePacketData) msg.obj /* packet */);
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900538 break;
539 }
540 case CMD_REMOVE_KEEPALIVE_PACKET_FILTER: {
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900541 onRemoveKeepalivePacketFilter(msg.arg1 /* slot */);
Lorenzo Colitti782b48d52020-01-12 20:27:32 +0900542 break;
543 }
junyulai352dc2f2019-01-08 20:04:33 +0800544 }
Robert Greenwalt7b816022014-04-18 15:25:25 -0700545 }
546 }
547
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900548 /**
549 * Register this network agent with ConnectivityService.
Chalard Jeanf1dec612020-03-24 23:16:35 +0900550 *
551 * This method can only be called once per network agent.
552 *
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900553 * @return the Network associated with this network agent (which can also be obtained later
554 * by calling getNetwork() on this agent).
Chalard Jeanf1dec612020-03-24 23:16:35 +0900555 * @throws IllegalStateException thrown by the system server if this network agent is
556 * already registered.
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900557 */
558 @NonNull
559 public Network register() {
560 if (VDBG) log("Registering NetworkAgent");
Chalard Jeanf1dec612020-03-24 23:16:35 +0900561 synchronized (mRegisterLock) {
562 if (mNetwork != null) {
563 throw new IllegalStateException("Agent already registered");
564 }
Treehugger Robotb2f183c2020-04-07 06:59:06 +0000565 final ConnectivityManager cm = (ConnectivityManager) mInitialConfiguration.context
566 .getSystemService(Context.CONNECTIVITY_SERVICE);
Chalard Jeanf1dec612020-03-24 23:16:35 +0900567 mNetwork = cm.registerNetworkAgent(new Messenger(mHandler),
568 new NetworkInfo(mInitialConfiguration.info),
569 mInitialConfiguration.properties, mInitialConfiguration.capabilities,
570 mInitialConfiguration.score, mInitialConfiguration.config, providerId);
571 mInitialConfiguration = null; // All this memory can now be GC'd
572 }
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900573 return mNetwork;
574 }
575
576 /**
Chalard Jean0348de62020-04-13 16:09:41 +0000577 * Register this network agent with a testing harness.
578 *
579 * The returned Messenger sends messages to the Handler. This allows a test to send
580 * this object {@code CMD_*} messages as if they came from ConnectivityService, which
581 * is useful for testing the behavior.
582 *
583 * @hide
584 */
585 public Messenger registerForTest(final Network network) {
586 log("Registering NetworkAgent for test");
587 synchronized (mRegisterLock) {
588 mNetwork = network;
589 mInitialConfiguration = null;
590 }
591 return new Messenger(mHandler);
592 }
593
594 /**
595 * Waits for the handler to be idle.
596 * This is useful for testing, and has smaller scope than an accessor to mHandler.
597 * TODO : move the implementation in common library with the tests
598 * @hide
599 */
600 @VisibleForTesting
601 public boolean waitForIdle(final long timeoutMs) {
602 final ConditionVariable cv = new ConditionVariable(false);
603 mHandler.post(cv::open);
604 return cv.block(timeoutMs);
605 }
606
607 /**
Chalard Jean29c6e0c2020-01-16 17:13:26 +0900608 * @return The Network associated with this agent, or null if it's not registered yet.
609 */
610 @Nullable
611 public Network getNetwork() {
612 return mNetwork;
613 }
614
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700615 private void queueOrSendMessage(int what, Object obj) {
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900616 queueOrSendMessage(what, 0, 0, obj);
617 }
618
619 private void queueOrSendMessage(int what, int arg1, int arg2) {
620 queueOrSendMessage(what, arg1, arg2, null);
621 }
622
623 private void queueOrSendMessage(int what, int arg1, int arg2, Object obj) {
624 Message msg = Message.obtain();
625 msg.what = what;
626 msg.arg1 = arg1;
627 msg.arg2 = arg2;
628 msg.obj = obj;
629 queueOrSendMessage(msg);
630 }
631
632 private void queueOrSendMessage(Message msg) {
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700633 synchronized (mPreConnectedQueue) {
634 if (mAsyncChannel != null) {
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900635 mAsyncChannel.sendMessage(msg);
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700636 } else {
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700637 mPreConnectedQueue.add(msg);
Lorenzo Colitti9a6a11a2014-05-24 02:25:55 +0900638 }
Robert Greenwalt7b816022014-04-18 15:25:25 -0700639 }
640 }
641
Robert Greenwalt7b816022014-04-18 15:25:25 -0700642 /**
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900643 * Must be called by the agent when the network's {@link LinkProperties} change.
644 * @param linkProperties the new LinkProperties.
Robert Greenwalt7b816022014-04-18 15:25:25 -0700645 */
Chalard Jeanf1dec612020-03-24 23:16:35 +0900646 public final void sendLinkProperties(@NonNull LinkProperties linkProperties) {
Chalard Jean339ba3f2020-01-15 04:38:56 +0900647 Objects.requireNonNull(linkProperties);
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700648 queueOrSendMessage(EVENT_NETWORK_PROPERTIES_CHANGED, new LinkProperties(linkProperties));
Robert Greenwalt7b816022014-04-18 15:25:25 -0700649 }
650
651 /**
Chalard Jean339ba3f2020-01-15 04:38:56 +0900652 * Inform ConnectivityService that this agent has now connected.
Chalard Jeanf1dec612020-03-24 23:16:35 +0900653 * Call {@link #unregister} to disconnect.
Chalard Jean339ba3f2020-01-15 04:38:56 +0900654 */
Chalard Jeanb0e1e7e2020-03-27 15:00:38 +0900655 public void markConnected() {
Chalard Jean339ba3f2020-01-15 04:38:56 +0900656 if (mIsLegacy) {
657 throw new UnsupportedOperationException(
Chalard Jeanb0e1e7e2020-03-27 15:00:38 +0900658 "Legacy agents can't call markConnected.");
Chalard Jean339ba3f2020-01-15 04:38:56 +0900659 }
Chalard Jeanee171ca2020-04-06 07:25:10 +0000660 // |reason| cannot be used by the non-legacy agents
661 mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null /* reason */,
662 mNetworkInfo.getExtraInfo());
Chalard Jean339ba3f2020-01-15 04:38:56 +0900663 queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
664 }
665
666 /**
667 * Unregister this network agent.
668 *
669 * This signals the network has disconnected and ends its lifecycle. After this is called,
670 * the network is torn down and this agent can no longer be used.
671 */
672 public void unregister() {
673 if (mIsLegacy) {
Chalard Jeanf1dec612020-03-24 23:16:35 +0900674 throw new UnsupportedOperationException("Legacy agents can't call unregister.");
Chalard Jean339ba3f2020-01-15 04:38:56 +0900675 }
Chalard Jeanee171ca2020-04-06 07:25:10 +0000676 // When unregistering an agent nobody should use the extrainfo (or reason) any more.
677 mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null /* reason */,
678 null /* extraInfo */);
Chalard Jean339ba3f2020-01-15 04:38:56 +0900679 queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
680 }
681
682 /**
683 * Change the legacy subtype of this network agent.
684 *
685 * This is only for backward compatibility and should not be used by non-legacy network agents,
686 * or agents that did not use to set a subtype. As such, only TYPE_MOBILE type agents can use
687 * this and others will be thrown an exception if they try.
688 *
689 * @deprecated this is for backward compatibility only.
690 * @param legacySubtype the legacy subtype.
Aaron Huangf68546e2020-03-12 17:52:33 +0800691 * @hide
Chalard Jean339ba3f2020-01-15 04:38:56 +0900692 */
693 @Deprecated
694 public void setLegacySubtype(final int legacySubtype, @NonNull final String legacySubtypeName) {
695 if (mIsLegacy) {
696 throw new UnsupportedOperationException("Legacy agents can't call setLegacySubtype.");
697 }
698 mNetworkInfo.setSubtype(legacySubtype, legacySubtypeName);
699 queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
700 }
701
702 /**
703 * Set the ExtraInfo of this network agent.
704 *
705 * This sets the ExtraInfo field inside the NetworkInfo returned by legacy public API and the
706 * broadcasts about the corresponding Network.
707 * This is only for backward compatibility and should not be used by non-legacy network agents,
708 * who will be thrown an exception if they try. The extra info should only be :
709 * <ul>
710 * <li>For cellular agents, the APN name.</li>
711 * <li>For ethernet agents, the interface name.</li>
712 * </ul>
713 *
714 * @deprecated this is for backward compatibility only.
715 * @param extraInfo the ExtraInfo.
Aaron Huangf68546e2020-03-12 17:52:33 +0800716 * @hide
Chalard Jean339ba3f2020-01-15 04:38:56 +0900717 */
718 @Deprecated
719 public void setLegacyExtraInfo(@Nullable final String extraInfo) {
720 if (mIsLegacy) {
721 throw new UnsupportedOperationException("Legacy agents can't call setLegacyExtraInfo.");
722 }
723 mNetworkInfo.setExtraInfo(extraInfo);
724 queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
725 }
726
727 /**
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900728 * Must be called by the agent when it has a new NetworkInfo object.
729 * @hide TODO: expose something better.
Robert Greenwalt7b816022014-04-18 15:25:25 -0700730 */
Mathew Inwood31755f92018-12-20 13:53:36 +0000731 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Chalard Jeanf1dec612020-03-24 23:16:35 +0900732 public final void sendNetworkInfo(NetworkInfo networkInfo) {
Chalard Jean339ba3f2020-01-15 04:38:56 +0900733 if (!mIsLegacy) {
734 throw new UnsupportedOperationException("Only legacy agents can call sendNetworkInfo.");
735 }
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700736 queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, new NetworkInfo(networkInfo));
Robert Greenwalt7b816022014-04-18 15:25:25 -0700737 }
738
739 /**
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900740 * Must be called by the agent when the network's {@link NetworkCapabilities} change.
741 * @param networkCapabilities the new NetworkCapabilities.
Robert Greenwalt7b816022014-04-18 15:25:25 -0700742 */
Chalard Jeanf1dec612020-03-24 23:16:35 +0900743 public final void sendNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) {
Chalard Jean339ba3f2020-01-15 04:38:56 +0900744 Objects.requireNonNull(networkCapabilities);
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900745 mBandwidthUpdatePending.set(false);
fenglub15e72b2015-03-20 11:29:56 -0700746 mLastBwRefreshTime = System.currentTimeMillis();
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700747 queueOrSendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED,
748 new NetworkCapabilities(networkCapabilities));
Robert Greenwalt7b816022014-04-18 15:25:25 -0700749 }
750
751 /**
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900752 * Must be called by the agent to update the score of this network.
Chalard Jeanf1dec612020-03-24 23:16:35 +0900753 *
754 * @param score the new score, between 0 and 99.
Robert Greenwalt7b816022014-04-18 15:25:25 -0700755 */
Chalard Jeanf1dec612020-03-24 23:16:35 +0900756 public final void sendNetworkScore(@IntRange(from = 0, to = 99) int score) {
Chalard Jeana11593c2020-02-21 19:37:21 +0900757 if (score < 0) {
758 throw new IllegalArgumentException("Score must be >= 0");
759 }
Automerger Merge Worker3d40f5782020-03-08 06:07:47 +0000760 queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, score, 0);
Robert Greenwalt7b816022014-04-18 15:25:25 -0700761 }
762
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700763 /**
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900764 * Must be called by the agent to indicate this network was manually selected by the user.
Robert Greenwalte73cc462014-09-07 16:50:01 -0700765 * This should be called before the NetworkInfo is marked CONNECTED so that this
Lorenzo Colittie03c3c72015-04-03 16:38:52 +0900766 * Network can be given special treatment at that time. If {@code acceptUnvalidated} is
767 * {@code true}, then the system will switch to this network. If it is {@code false} and the
768 * network cannot be validated, the system will ask the user whether to switch to this network.
769 * If the user confirms and selects "don't ask again", then the system will call
770 * {@link #saveAcceptUnvalidated} to persist the user's choice. Thus, if the transport ever
771 * calls this method with {@code acceptUnvalidated} set to {@code false}, it must also implement
772 * {@link #saveAcceptUnvalidated} to respect the user's choice.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900773 * @hide should move to NetworkAgentConfig.
Robert Greenwalte73cc462014-09-07 16:50:01 -0700774 */
Lorenzo Colittie03c3c72015-04-03 16:38:52 +0900775 public void explicitlySelected(boolean acceptUnvalidated) {
Lorenzo Colitti0e33bd12019-06-04 14:37:26 +0900776 explicitlySelected(true /* explicitlySelected */, acceptUnvalidated);
777 }
778
779 /**
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900780 * Must be called by the agent to indicate whether the network was manually selected by the
781 * user. This should be called before the network becomes connected, so it can be given
782 * special treatment when it does.
Lorenzo Colittib5ad6132019-06-04 22:15:33 +0900783 *
784 * If {@code explicitlySelected} is {@code true}, and {@code acceptUnvalidated} is {@code true},
785 * then the system will switch to this network. If {@code explicitlySelected} is {@code true}
786 * and {@code acceptUnvalidated} is {@code false}, and the network cannot be validated, the
787 * system will ask the user whether to switch to this network. If the user confirms and selects
788 * "don't ask again", then the system will call {@link #saveAcceptUnvalidated} to persist the
789 * user's choice. Thus, if the transport ever calls this method with {@code explicitlySelected}
790 * set to {@code true} and {@code acceptUnvalidated} set to {@code false}, it must also
791 * implement {@link #saveAcceptUnvalidated} to respect the user's choice.
792 *
793 * If {@code explicitlySelected} is {@code false} and {@code acceptUnvalidated} is
794 * {@code true}, the system will interpret this as the user having accepted partial connectivity
795 * on this network. Thus, the system will switch to the network and consider it validated even
796 * if it only provides partial connectivity, but the network is not otherwise treated specially.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900797 * @hide should move to NetworkAgentConfig.
Lorenzo Colitti0e33bd12019-06-04 14:37:26 +0900798 */
799 public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) {
800 queueOrSendMessage(EVENT_SET_EXPLICITLY_SELECTED,
801 explicitlySelected ? 1 : 0,
802 acceptUnvalidated ? 1 : 0);
Robert Greenwalte73cc462014-09-07 16:50:01 -0700803 }
804
805 /**
Robert Greenwalt3192dec2014-05-27 13:20:24 -0700806 * Called when ConnectivityService has indicated they no longer want this network.
807 * The parent factory should (previously) have received indication of the change
808 * as well, either canceling NetworkRequests or altering their score such that this
809 * network won't be immediately requested again.
810 */
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900811 public void onNetworkUnwanted() {
812 unwanted();
813 }
814 /** @hide TODO delete once subclasses have moved to onNetworkUnwanted. */
815 protected void unwanted() {
816 }
Robert Greenwalt7b816022014-04-18 15:25:25 -0700817
Robert Greenwalt49f63fb2014-09-13 12:04:12 -0700818 /**
fenglub15e72b2015-03-20 11:29:56 -0700819 * Called when ConnectivityService request a bandwidth update. The parent factory
820 * shall try to overwrite this method and produce a bandwidth update if capable.
Aaron Huangf68546e2020-03-12 17:52:33 +0800821 * @hide
fenglub15e72b2015-03-20 11:29:56 -0700822 */
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900823 public void onBandwidthUpdateRequested() {
824 pollLceData();
825 }
826 /** @hide TODO delete once subclasses have moved to onBandwidthUpdateRequested. */
fenglub15e72b2015-03-20 11:29:56 -0700827 protected void pollLceData() {
828 }
829
830 /**
Robert Greenwalt49f63fb2014-09-13 12:04:12 -0700831 * Called when the system determines the usefulness of this network.
832 *
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900833 * The system attempts to validate Internet connectivity on networks that provide the
markchien06b9dfb2020-01-15 20:41:31 +0800834 * {@link NetworkCapabilities#NET_CAPABILITY_INTERNET} capability.
Robert Greenwalt49f63fb2014-09-13 12:04:12 -0700835 *
836 * Currently there are two possible values:
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900837 * {@code VALIDATION_STATUS_VALID} if Internet connectivity was validated,
838 * {@code VALIDATION_STATUS_NOT_VALID} if Internet connectivity was not validated.
Robert Greenwalt49f63fb2014-09-13 12:04:12 -0700839 *
Chalard Jeanb0e1e7e2020-03-27 15:00:38 +0900840 * This is guaranteed to be called again when the network status changes, but the system
841 * may also call this multiple times even if the status does not change.
Paul Jensen232437312016-04-06 09:51:26 -0400842 *
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900843 * @param status one of {@code VALIDATION_STATUS_VALID} or {@code VALIDATION_STATUS_NOT_VALID}.
Chalard Jeanf1dec612020-03-24 23:16:35 +0900844 * @param redirectUri If Internet connectivity is being redirected (e.g., on a captive portal),
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900845 * this is the destination the probes are being redirected to, otherwise {@code null}.
Robert Greenwalt49f63fb2014-09-13 12:04:12 -0700846 */
Chalard Jeanf1dec612020-03-24 23:16:35 +0900847 public void onValidationStatus(@ValidationStatus int status, @Nullable Uri redirectUri) {
Treehugger Robot67ac7ab2020-04-10 19:11:51 +0000848 networkStatus(status, null == redirectUri ? "" : redirectUri.toString());
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900849 }
850 /** @hide TODO delete once subclasses have moved to onValidationStatus */
Paul Jensen232437312016-04-06 09:51:26 -0400851 protected void networkStatus(int status, String redirectUrl) {
Robert Greenwalt49f63fb2014-09-13 12:04:12 -0700852 }
853
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900854
Lorenzo Colittie03c3c72015-04-03 16:38:52 +0900855 /**
856 * Called when the user asks to remember the choice to use this network even if unvalidated.
857 * The transport is responsible for remembering the choice, and the next time the user connects
858 * to the network, should explicitlySelected with {@code acceptUnvalidated} set to {@code true}.
859 * This method will only be called if {@link #explicitlySelected} was called with
860 * {@code acceptUnvalidated} set to {@code false}.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900861 * @param accept whether the user wants to use the network even if unvalidated.
Lorenzo Colittie03c3c72015-04-03 16:38:52 +0900862 */
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900863 public void onSaveAcceptUnvalidated(boolean accept) {
864 saveAcceptUnvalidated(accept);
865 }
866 /** @hide TODO delete once subclasses have moved to onSaveAcceptUnvalidated */
Lorenzo Colittie03c3c72015-04-03 16:38:52 +0900867 protected void saveAcceptUnvalidated(boolean accept) {
868 }
869
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900870 /**
871 * Requests that the network hardware send the specified packet at the specified interval.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900872 *
873 * @param slot the hardware slot on which to start the keepalive.
Chalard Jeanb0e1e7e2020-03-27 15:00:38 +0900874 * @param interval the interval between packets, between 10 and 3600. Note that this API
875 * does not support sub-second precision and will round off the request.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900876 * @param packet the packet to send.
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900877 */
Chalard Jeanf1dec612020-03-24 23:16:35 +0900878 // seconds is from SocketKeepalive.MIN_INTERVAL_SEC to MAX_INTERVAL_SEC, but these should
879 // not be exposed as constants because they may change in the future (API guideline 4.8)
880 // and should have getters if exposed at all. Getters can't be used in the annotation,
881 // so the values unfortunately need to be copied.
Chalard Jeanb0e1e7e2020-03-27 15:00:38 +0900882 public void onStartSocketKeepalive(int slot, @NonNull Duration interval,
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900883 @NonNull KeepalivePacketData packet) {
Chalard Jeanb0e1e7e2020-03-27 15:00:38 +0900884 final long intervalSeconds = interval.getSeconds();
885 if (intervalSeconds < SocketKeepalive.MIN_INTERVAL_SEC
886 || intervalSeconds > SocketKeepalive.MAX_INTERVAL_SEC) {
887 throw new IllegalArgumentException("Interval needs to be comprised between "
888 + SocketKeepalive.MIN_INTERVAL_SEC + " and " + SocketKeepalive.MAX_INTERVAL_SEC
889 + " but was " + intervalSeconds);
890 }
891 final Message msg = mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, slot,
892 (int) intervalSeconds, packet);
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900893 startSocketKeepalive(msg);
894 msg.recycle();
895 }
896 /** @hide TODO delete once subclasses have moved to onStartSocketKeepalive */
junyulaie4135282019-01-03 18:50:15 +0800897 protected void startSocketKeepalive(Message msg) {
junyulai0c666972019-03-04 22:45:36 +0800898 onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900899 }
900
901 /**
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900902 * Requests that the network hardware stop a previously-started keepalive.
903 *
904 * @param slot the hardware slot on which to stop the keepalive.
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900905 */
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900906 public void onStopSocketKeepalive(int slot) {
907 Message msg = mHandler.obtainMessage(CMD_STOP_SOCKET_KEEPALIVE, slot, 0, null);
908 stopSocketKeepalive(msg);
909 msg.recycle();
910 }
911 /** @hide TODO delete once subclasses have moved to onStopSocketKeepalive */
junyulaie4135282019-01-03 18:50:15 +0800912 protected void stopSocketKeepalive(Message msg) {
junyulai0c666972019-03-04 22:45:36 +0800913 onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900914 }
915
916 /**
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900917 * Must be called by the agent when a socket keepalive event occurs.
918 *
919 * @param slot the hardware slot on which the event occurred.
Chalard Jeanf1dec612020-03-24 23:16:35 +0900920 * @param event the event that occurred, as one of the SocketKeepalive.ERROR_*
921 * or SocketKeepalive.SUCCESS constants.
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900922 */
Chalard Jeanf1dec612020-03-24 23:16:35 +0900923 public final void sendSocketKeepaliveEvent(int slot,
924 @SocketKeepalive.KeepaliveEvent int event) {
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900925 queueOrSendMessage(EVENT_SOCKET_KEEPALIVE, slot, event);
926 }
927 /** @hide TODO delete once callers have moved to sendSocketKeepaliveEvent */
junyulaie4135282019-01-03 18:50:15 +0800928 public void onSocketKeepaliveEvent(int slot, int reason) {
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900929 sendSocketKeepaliveEvent(slot, reason);
Lorenzo Colitti8bf977d2015-06-15 14:29:22 +0900930 }
931
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900932 /**
junyulai352dc2f2019-01-08 20:04:33 +0800933 * Called by ConnectivityService to add specific packet filter to network hardware to block
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900934 * replies (e.g., TCP ACKs) matching the sent keepalive packets. Implementations that support
935 * this feature must override this method.
936 *
937 * @param slot the hardware slot on which the keepalive should be sent.
938 * @param packet the packet that is being sent.
junyulai352dc2f2019-01-08 20:04:33 +0800939 */
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900940 public void onAddKeepalivePacketFilter(int slot, @NonNull KeepalivePacketData packet) {
941 Message msg = mHandler.obtainMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER, slot, 0, packet);
942 addKeepalivePacketFilter(msg);
943 msg.recycle();
944 }
945 /** @hide TODO delete once subclasses have moved to onAddKeepalivePacketFilter */
junyulai352dc2f2019-01-08 20:04:33 +0800946 protected void addKeepalivePacketFilter(Message msg) {
junyulai352dc2f2019-01-08 20:04:33 +0800947 }
948
949 /**
950 * Called by ConnectivityService to remove a packet filter installed with
951 * {@link #addKeepalivePacketFilter(Message)}. Implementations that support this feature
952 * must override this method.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900953 *
954 * @param slot the hardware slot on which the keepalive is being sent.
junyulai352dc2f2019-01-08 20:04:33 +0800955 */
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900956 public void onRemoveKeepalivePacketFilter(int slot) {
957 Message msg = mHandler.obtainMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, slot, 0, null);
958 removeKeepalivePacketFilter(msg);
959 msg.recycle();
960 }
961 /** @hide TODO delete once subclasses have moved to onRemoveKeepalivePacketFilter */
junyulai352dc2f2019-01-08 20:04:33 +0800962 protected void removeKeepalivePacketFilter(Message msg) {
junyulai352dc2f2019-01-08 20:04:33 +0800963 }
964
965 /**
Chalard Jeanf1dec612020-03-24 23:16:35 +0900966 * Called by ConnectivityService to inform this network agent of signal strength thresholds
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900967 * that when crossed should trigger a system wakeup and a NetworkCapabilities update.
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900968 *
Chalard Jeanf1dec612020-03-24 23:16:35 +0900969 * When the system updates the list of thresholds that should wake up the CPU for a
970 * given agent it will call this method on the agent. The agent that implement this
971 * should implement it in hardware so as to ensure the CPU will be woken up on breach.
972 * Agents are expected to react to a breach by sending an updated NetworkCapabilities
973 * object with the appropriate signal strength to sendNetworkCapabilities.
974 *
975 * The specific units are bearer-dependent. See details on the units and requests in
976 * {@link NetworkCapabilities.Builder#setSignalStrength}.
977 *
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900978 * @param thresholds the array of thresholds that should trigger wakeups.
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900979 */
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900980 public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) {
981 setSignalStrengthThresholds(thresholds);
982 }
983 /** @hide TODO delete once subclasses have moved to onSetSignalStrengthThresholds */
Lorenzo Colittic3f21f32015-07-06 23:50:27 +0900984 protected void setSignalStrengthThresholds(int[] thresholds) {
985 }
986
Paul Jensenbf109912015-07-29 11:31:53 -0400987 /**
Paul Jensenf95d2202015-07-13 15:19:51 -0400988 * Called when the user asks to not stay connected to this network because it was found to not
989 * provide Internet access. Usually followed by call to {@code unwanted}. The transport is
990 * responsible for making sure the device does not automatically reconnect to the same network
991 * after the {@code unwanted} call.
992 */
Lorenzo Colitti631f33a2020-01-15 00:13:37 +0900993 public void onAutomaticReconnectDisabled() {
994 preventAutomaticReconnect();
995 }
996 /** @hide TODO delete once subclasses have moved to onAutomaticReconnectDisabled */
Paul Jensenf95d2202015-07-13 15:19:51 -0400997 protected void preventAutomaticReconnect() {
998 }
999
Lorenzo Colitti631f33a2020-01-15 00:13:37 +09001000 /** @hide */
Robert Greenwalt7b816022014-04-18 15:25:25 -07001001 protected void log(String s) {
1002 Log.d(LOG_TAG, "NetworkAgent: " + s);
1003 }
1004}