1 /* 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 17 package android.net; 18 19 import android.annotation.IntDef; 20 import android.annotation.IntRange; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.SuppressLint; 24 import android.annotation.SystemApi; 25 import android.annotation.TestApi; 26 import android.compat.annotation.UnsupportedAppUsage; 27 import android.content.Context; 28 import android.os.Build; 29 import android.os.Bundle; 30 import android.os.ConditionVariable; 31 import android.os.Handler; 32 import android.os.Looper; 33 import android.os.Message; 34 import android.os.RemoteException; 35 import android.telephony.data.EpsBearerQosSessionAttributes; 36 import android.telephony.data.NrQosSessionAttributes; 37 import android.util.Log; 38 39 import com.android.internal.annotations.VisibleForTesting; 40 41 import java.lang.annotation.Retention; 42 import java.lang.annotation.RetentionPolicy; 43 import java.time.Duration; 44 import java.util.ArrayList; 45 import java.util.List; 46 import java.util.Objects; 47 import java.util.concurrent.atomic.AtomicBoolean; 48 49 /** 50 * A utility class for handling for communicating between bearer-specific 51 * code and ConnectivityService. 52 * 53 * An agent manages the life cycle of a network. A network starts its 54 * life cycle when {@link register} is called on NetworkAgent. The network 55 * is then connecting. When full L3 connectivity has been established, 56 * the agent should call {@link markConnected} to inform the system that 57 * this network is ready to use. When the network disconnects its life 58 * ends and the agent should call {@link unregister}, at which point the 59 * system will clean up and free resources. 60 * Any reconnection becomes a new logical network, so after a network 61 * is disconnected the agent cannot be used any more. Network providers 62 * should create a new NetworkAgent instance to handle new connections. 63 * 64 * A bearer may have more than one NetworkAgent if it can simultaneously 65 * support separate networks (IMS / Internet / MMS Apns on cellular, or 66 * perhaps connections with different SSID or P2P for Wi-Fi). 67 * 68 * This class supports methods to start and stop sending keepalive packets. 69 * Keepalive packets are typically sent at periodic intervals over a network 70 * with NAT when there is no other traffic to avoid the network forcefully 71 * closing the connection. NetworkAgents that manage technologies that 72 * have hardware support for keepalive should implement the related 73 * methods to save battery life. NetworkAgent that cannot get support 74 * without waking up the CPU should not, as this would be prohibitive in 75 * terms of battery - these agents should simply not override the related 76 * methods, which results in the implementation returning 77 * {@link SocketKeepalive.ERROR_UNSUPPORTED} as appropriate. 78 * 79 * Keepalive packets need to be sent at relatively frequent intervals 80 * (a few seconds to a few minutes). As the contents of keepalive packets 81 * depend on the current network status, hardware needs to be configured 82 * to send them and has a limited amount of memory to do so. The HAL 83 * formalizes this as slots that an implementation can configure to send 84 * the correct packets. Devices typically have a small number of slots 85 * per radio technology, and the specific number of slots for each 86 * technology is specified in configuration files. 87 * See {@link SocketKeepalive} for details. 88 * 89 * @hide 90 */ 91 @SystemApi 92 public abstract class NetworkAgent { 93 /** 94 * The {@link Network} corresponding to this object. 95 */ 96 @Nullable 97 private volatile Network mNetwork; 98 99 @Nullable 100 private volatile INetworkAgentRegistry mRegistry; 101 102 private interface RegistryAction { execute(@onNull INetworkAgentRegistry registry)103 void execute(@NonNull INetworkAgentRegistry registry) throws RemoteException; 104 } 105 106 private final Handler mHandler; 107 private final String LOG_TAG; 108 private static final boolean DBG = true; 109 private static final boolean VDBG = false; 110 /** @hide */ 111 @TestApi 112 public static final int MIN_LINGER_TIMER_MS = 2000; 113 private final ArrayList<RegistryAction> mPreConnectedQueue = new ArrayList<>(); 114 private volatile long mLastBwRefreshTime = 0; 115 private static final long BW_REFRESH_MIN_WIN_MS = 500; 116 private boolean mBandwidthUpdateScheduled = false; 117 private AtomicBoolean mBandwidthUpdatePending = new AtomicBoolean(false); 118 @NonNull 119 private NetworkInfo mNetworkInfo; 120 @NonNull 121 private final Object mRegisterLock = new Object(); 122 123 /** 124 * The ID of the {@link NetworkProvider} that created this object, or 125 * {@link NetworkProvider#ID_NONE} if unknown. 126 * @hide 127 */ 128 public final int providerId; 129 130 // ConnectivityService parses message constants from itself and NetworkAgent with MessageUtils 131 // for debugging purposes, and crashes if some messages have the same values. 132 // TODO: have ConnectivityService store message names in different maps and remove this base 133 private static final int BASE = 200; 134 135 /** 136 * Sent by ConnectivityService to the NetworkAgent to inform it of 137 * suspected connectivity problems on its network. The NetworkAgent 138 * should take steps to verify and correct connectivity. 139 * @hide 140 */ 141 public static final int CMD_SUSPECT_BAD = BASE; 142 143 /** 144 * Sent by the NetworkAgent (note the EVENT vs CMD prefix) to 145 * ConnectivityService to pass the current NetworkInfo (connection state). 146 * Sent when the NetworkInfo changes, mainly due to change of state. 147 * obj = NetworkInfo 148 * @hide 149 */ 150 public static final int EVENT_NETWORK_INFO_CHANGED = BASE + 1; 151 152 /** 153 * Sent by the NetworkAgent to ConnectivityService to pass the current 154 * NetworkCapabilities. 155 * obj = NetworkCapabilities 156 * @hide 157 */ 158 public static final int EVENT_NETWORK_CAPABILITIES_CHANGED = BASE + 2; 159 160 /** 161 * Sent by the NetworkAgent to ConnectivityService to pass the current 162 * NetworkProperties. 163 * obj = NetworkProperties 164 * @hide 165 */ 166 public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3; 167 168 /** 169 * Centralize the place where base network score, and network score scaling, will be 170 * stored, so as we can consistently compare apple and oranges, or wifi, ethernet and LTE 171 * @hide 172 */ 173 public static final int WIFI_BASE_SCORE = 60; 174 175 /** 176 * Sent by the NetworkAgent to ConnectivityService to pass the current 177 * network score. 178 * arg1 = network score int 179 * @hide 180 */ 181 public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4; 182 183 /** 184 * Sent by the NetworkAgent to ConnectivityService to pass the current 185 * list of underlying networks. 186 * obj = array of Network objects 187 * @hide 188 */ 189 public static final int EVENT_UNDERLYING_NETWORKS_CHANGED = BASE + 5; 190 191 /** 192 * Sent by the NetworkAgent to ConnectivityService to pass the current value of the teardown 193 * delay. 194 * arg1 = teardown delay in milliseconds 195 * @hide 196 */ 197 public static final int EVENT_TEARDOWN_DELAY_CHANGED = BASE + 6; 198 199 /** 200 * The maximum value for the teardown delay, in milliseconds. 201 * @hide 202 */ 203 public static final int MAX_TEARDOWN_DELAY_MS = 5000; 204 205 /** 206 * Sent by ConnectivityService to the NetworkAgent to inform the agent of the 207 * networks status - whether we could use the network or could not, due to 208 * either a bad network configuration (no internet link) or captive portal. 209 * 210 * arg1 = either {@code VALID_NETWORK} or {@code INVALID_NETWORK} 211 * obj = Bundle containing map from {@code REDIRECT_URL_KEY} to {@code String} 212 * representing URL that Internet probe was redirect to, if it was redirected, 213 * or mapping to {@code null} otherwise. 214 * @hide 215 */ 216 public static final int CMD_REPORT_NETWORK_STATUS = BASE + 7; 217 218 /** 219 * Network validation suceeded. 220 * Corresponds to {@link NetworkCapabilities.NET_CAPABILITY_VALIDATED}. 221 */ 222 public static final int VALIDATION_STATUS_VALID = 1; 223 224 /** 225 * Network validation was attempted and failed. This may be received more than once as 226 * subsequent validation attempts are made. 227 */ 228 public static final int VALIDATION_STATUS_NOT_VALID = 2; 229 230 /** @hide */ 231 @Retention(RetentionPolicy.SOURCE) 232 @IntDef(prefix = { "VALIDATION_STATUS_" }, value = { 233 VALIDATION_STATUS_VALID, 234 VALIDATION_STATUS_NOT_VALID 235 }) 236 public @interface ValidationStatus {} 237 238 // TODO: remove. 239 /** @hide */ 240 public static final int VALID_NETWORK = 1; 241 /** @hide */ 242 public static final int INVALID_NETWORK = 2; 243 244 /** 245 * The key for the redirect URL in the Bundle argument of {@code CMD_REPORT_NETWORK_STATUS}. 246 * @hide 247 */ 248 public static final String REDIRECT_URL_KEY = "redirect URL"; 249 250 /** 251 * Sent by the NetworkAgent to ConnectivityService to indicate this network was 252 * explicitly selected. This should be sent before the NetworkInfo is marked 253 * CONNECTED so it can be given special treatment at that time. 254 * 255 * obj = boolean indicating whether to use this network even if unvalidated 256 * @hide 257 */ 258 public static final int EVENT_SET_EXPLICITLY_SELECTED = BASE + 8; 259 260 /** 261 * Sent by ConnectivityService to the NetworkAgent to inform the agent of 262 * whether the network should in the future be used even if not validated. 263 * This decision is made by the user, but it is the network transport's 264 * responsibility to remember it. 265 * 266 * arg1 = 1 if true, 0 if false 267 * @hide 268 */ 269 public static final int CMD_SAVE_ACCEPT_UNVALIDATED = BASE + 9; 270 271 /** 272 * Sent by ConnectivityService to the NetworkAgent to inform the agent to pull 273 * the underlying network connection for updated bandwidth information. 274 * @hide 275 */ 276 public static final int CMD_REQUEST_BANDWIDTH_UPDATE = BASE + 10; 277 278 /** 279 * Sent by ConnectivityService to the NetworkAgent to request that the specified packet be sent 280 * periodically on the given interval. 281 * 282 * arg1 = the hardware slot number of the keepalive to start 283 * arg2 = interval in seconds 284 * obj = KeepalivePacketData object describing the data to be sent 285 * 286 * @hide 287 */ 288 public static final int CMD_START_SOCKET_KEEPALIVE = BASE + 11; 289 290 /** 291 * Requests that the specified keepalive packet be stopped. 292 * 293 * arg1 = unused 294 * arg2 = error code (SUCCESS) 295 * obj = callback to identify the keepalive 296 * 297 * Also used internally by ConnectivityService / KeepaliveTracker, with different semantics. 298 * @hide 299 */ 300 public static final int CMD_STOP_SOCKET_KEEPALIVE = BASE + 12; 301 302 /** 303 * Sent by the NetworkAgent to ConnectivityService to provide status on a socket keepalive 304 * request. This may either be the reply to a CMD_START_SOCKET_KEEPALIVE, or an asynchronous 305 * error notification. 306 * 307 * This is also sent by KeepaliveTracker to the app's {@link SocketKeepalive}, 308 * so that the app's {@link SocketKeepalive.Callback} methods can be called. 309 * 310 * arg1 = hardware slot number of the keepalive 311 * arg2 = error code 312 * @hide 313 */ 314 public static final int EVENT_SOCKET_KEEPALIVE = BASE + 13; 315 316 /** 317 * Sent by ConnectivityService to inform this network transport of signal strength thresholds 318 * that when crossed should trigger a system wakeup and a NetworkCapabilities update. 319 * 320 * obj = int[] describing signal strength thresholds. 321 * @hide 322 */ 323 public static final int CMD_SET_SIGNAL_STRENGTH_THRESHOLDS = BASE + 14; 324 325 /** 326 * Sent by ConnectivityService to the NeworkAgent to inform the agent to avoid 327 * automatically reconnecting to this network (e.g. via autojoin). Happens 328 * when user selects "No" option on the "Stay connected?" dialog box. 329 * @hide 330 */ 331 public static final int CMD_PREVENT_AUTOMATIC_RECONNECT = BASE + 15; 332 333 /** 334 * Sent by the KeepaliveTracker to NetworkAgent to add a packet filter. 335 * 336 * For TCP keepalive offloads, keepalive packets are sent by the firmware. However, because the 337 * remote site will send ACK packets in response to the keepalive packets, the firmware also 338 * needs to be configured to properly filter the ACKs to prevent the system from waking up. 339 * This does not happen with UDP, so this message is TCP-specific. 340 * arg1 = hardware slot number of the keepalive to filter for. 341 * obj = the keepalive packet to send repeatedly. 342 * @hide 343 */ 344 public static final int CMD_ADD_KEEPALIVE_PACKET_FILTER = BASE + 16; 345 346 /** 347 * Sent by the KeepaliveTracker to NetworkAgent to remove a packet filter. See 348 * {@link #CMD_ADD_KEEPALIVE_PACKET_FILTER}. 349 * arg1 = hardware slot number of the keepalive packet filter to remove. 350 * @hide 351 */ 352 public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17; 353 354 /** 355 * Sent by ConnectivityService to the NetworkAgent to complete the bidirectional connection. 356 * obj = INetworkAgentRegistry 357 */ 358 private static final int EVENT_AGENT_CONNECTED = BASE + 18; 359 360 /** 361 * Sent by ConnectivityService to the NetworkAgent to inform the agent that it was disconnected. 362 */ 363 private static final int EVENT_AGENT_DISCONNECTED = BASE + 19; 364 365 /** 366 * Sent by QosCallbackTracker to {@link NetworkAgent} to register a new filter with 367 * callback. 368 * 369 * arg1 = QoS agent callback ID 370 * obj = {@link QosFilter} 371 * @hide 372 */ 373 public static final int CMD_REGISTER_QOS_CALLBACK = BASE + 20; 374 375 /** 376 * Sent by QosCallbackTracker to {@link NetworkAgent} to unregister a callback. 377 * 378 * arg1 = QoS agent callback ID 379 * @hide 380 */ 381 public static final int CMD_UNREGISTER_QOS_CALLBACK = BASE + 21; 382 383 /** 384 * Sent by ConnectivityService to {@link NetworkAgent} to inform the agent that its native 385 * network was created and the Network object is now valid. 386 * 387 * @hide 388 */ 389 public static final int CMD_NETWORK_CREATED = BASE + 22; 390 391 /** 392 * Sent by ConnectivityService to {@link NetworkAgent} to inform the agent that its native 393 * network was destroyed. 394 * 395 * @hide 396 */ 397 public static final int CMD_NETWORK_DESTROYED = BASE + 23; 398 399 /** 400 * Sent by the NetworkAgent to ConnectivityService to set the linger duration for this network 401 * agent. 402 * arg1 = the linger duration, represents by {@link Duration}. 403 * 404 * @hide 405 */ 406 public static final int EVENT_LINGER_DURATION_CHANGED = BASE + 24; 407 408 /** 409 * Sent by the NetworkAgent to ConnectivityService to set add a DSCP policy. 410 * 411 * @hide 412 */ 413 public static final int EVENT_ADD_DSCP_POLICY = BASE + 25; 414 415 /** 416 * Sent by the NetworkAgent to ConnectivityService to set remove a DSCP policy. 417 * 418 * @hide 419 */ 420 public static final int EVENT_REMOVE_DSCP_POLICY = BASE + 26; 421 422 /** 423 * Sent by the NetworkAgent to ConnectivityService to remove all DSCP policies. 424 * 425 * @hide 426 */ 427 public static final int EVENT_REMOVE_ALL_DSCP_POLICIES = BASE + 27; 428 429 /** 430 * Sent by ConnectivityService to {@link NetworkAgent} to inform the agent of an updated 431 * status for a DSCP policy. 432 * 433 * @hide 434 */ 435 public static final int CMD_DSCP_POLICY_STATUS = BASE + 28; 436 437 /** 438 * Sent by the NetworkAgent to ConnectivityService to notify that this network is expected to be 439 * replaced within the specified time by a similar network. 440 * arg1 = timeout in milliseconds 441 * @hide 442 */ 443 public static final int EVENT_UNREGISTER_AFTER_REPLACEMENT = BASE + 29; 444 445 /** 446 * Sent by the NetworkAgent to ConnectivityService to pass the new value of the local 447 * network agent config. 448 * obj = {@code Pair<NetworkAgentInfo, LocalNetworkConfig>} 449 * @hide 450 */ 451 public static final int EVENT_LOCAL_NETWORK_CONFIG_CHANGED = BASE + 30; 452 453 /** 454 * DSCP policy was successfully added. 455 */ 456 public static final int DSCP_POLICY_STATUS_SUCCESS = 0; 457 458 /** 459 * DSCP policy was rejected for any reason besides invalid classifier or insufficient resources. 460 */ 461 public static final int DSCP_POLICY_STATUS_REQUEST_DECLINED = 1; 462 463 /** 464 * Requested DSCP policy contained a classifier which is not supported. 465 */ 466 public static final int DSCP_POLICY_STATUS_REQUESTED_CLASSIFIER_NOT_SUPPORTED = 2; 467 468 /** 469 * Requested DSCP policy was not added due to insufficient processing resources. 470 */ 471 // TODO: should this error case be supported? 472 public static final int DSCP_POLICY_STATUS_INSUFFICIENT_PROCESSING_RESOURCES = 3; 473 474 /** 475 * DSCP policy was deleted. 476 */ 477 public static final int DSCP_POLICY_STATUS_DELETED = 4; 478 479 /** 480 * DSCP policy was not found during deletion. 481 */ 482 public static final int DSCP_POLICY_STATUS_POLICY_NOT_FOUND = 5; 483 484 /** @hide */ 485 @IntDef(prefix = "DSCP_POLICY_STATUS_", value = { 486 DSCP_POLICY_STATUS_SUCCESS, 487 DSCP_POLICY_STATUS_REQUEST_DECLINED, 488 DSCP_POLICY_STATUS_REQUESTED_CLASSIFIER_NOT_SUPPORTED, 489 DSCP_POLICY_STATUS_INSUFFICIENT_PROCESSING_RESOURCES, 490 DSCP_POLICY_STATUS_DELETED 491 }) 492 @Retention(RetentionPolicy.SOURCE) 493 public @interface DscpPolicyStatus {} 494 getLegacyNetworkInfo(final NetworkAgentConfig config)495 private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) { 496 final NetworkInfo ni = new NetworkInfo(config.legacyType, config.legacySubType, 497 config.legacyTypeName, config.legacySubTypeName); 498 ni.setIsAvailable(true); 499 ni.setDetailedState(NetworkInfo.DetailedState.CONNECTING, null /* reason */, 500 config.getLegacyExtraInfo()); 501 return ni; 502 } 503 504 // Temporary backward compatibility constructor NetworkAgent(@onNull Context context, @NonNull Looper looper, @NonNull String logTag, @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score, @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider)505 public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag, 506 @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score, 507 @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) { 508 this(context, looper, logTag, nc, lp, 509 new NetworkScore.Builder().setLegacyInt(score).build(), config, provider); 510 } 511 512 /** 513 * Create a new network agent. 514 * @param context a {@link Context} to get system services from. 515 * @param looper the {@link Looper} on which to invoke the callbacks. 516 * @param logTag the tag for logs 517 * @param nc the initial {@link NetworkCapabilities} of this network. Update with 518 * sendNetworkCapabilities. 519 * @param lp the initial {@link LinkProperties} of this network. Update with sendLinkProperties. 520 * @param score the initial score of this network. Update with sendNetworkScore. 521 * @param config an immutable {@link NetworkAgentConfig} for this agent. 522 * @param provider the {@link NetworkProvider} managing this agent. 523 */ NetworkAgent(@onNull Context context, @NonNull Looper looper, @NonNull String logTag, @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, @NonNull NetworkScore score, @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider)524 public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag, 525 @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, 526 @NonNull NetworkScore score, @NonNull NetworkAgentConfig config, 527 @Nullable NetworkProvider provider) { 528 this(context, looper, logTag, nc, lp, null /* localNetworkConfig */, score, config, 529 provider); 530 } 531 532 /** 533 * Create a new network agent. 534 * @param context a {@link Context} to get system services from. 535 * @param looper the {@link Looper} on which to invoke the callbacks. 536 * @param logTag the tag for logs 537 * @param nc the initial {@link NetworkCapabilities} of this network. Update with 538 * sendNetworkCapabilities. 539 * @param lp the initial {@link LinkProperties} of this network. Update with sendLinkProperties. 540 * @param localNetworkConfig the initial {@link LocalNetworkConfig} of this 541 * network. Update with sendLocalNetworkConfig. Must be 542 * non-null iff the nc have NET_CAPABILITY_LOCAL_NETWORK. 543 * @param score the initial score of this network. Update with sendNetworkScore. 544 * @param config an immutable {@link NetworkAgentConfig} for this agent. 545 * @param provider the {@link NetworkProvider} managing this agent. 546 * @hide 547 */ 548 // TODO : expose NetworkAgent(@onNull Context context, @NonNull Looper looper, @NonNull String logTag, @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, @Nullable LocalNetworkConfig localNetworkConfig, @NonNull NetworkScore score, @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider)549 public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag, 550 @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, 551 @Nullable LocalNetworkConfig localNetworkConfig, @NonNull NetworkScore score, 552 @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) { 553 this(looper, context, logTag, nc, lp, localNetworkConfig, score, config, 554 provider == null ? NetworkProvider.ID_NONE : provider.getProviderId(), 555 getLegacyNetworkInfo(config)); 556 } 557 558 private static class InitialConfiguration { 559 @NonNull public final Context context; 560 @NonNull public final NetworkCapabilities capabilities; 561 @NonNull public final LinkProperties properties; 562 @NonNull public final NetworkScore score; 563 @NonNull public final NetworkAgentConfig config; 564 @NonNull public final NetworkInfo info; 565 @Nullable public final LocalNetworkConfig localNetworkConfig; InitialConfiguration(@onNull Context context, @NonNull NetworkCapabilities capabilities, @NonNull LinkProperties properties, @Nullable LocalNetworkConfig localNetworkConfig, @NonNull NetworkScore score, @NonNull NetworkAgentConfig config, @NonNull NetworkInfo info)566 InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities, 567 @NonNull LinkProperties properties, 568 @Nullable LocalNetworkConfig localNetworkConfig, @NonNull NetworkScore score, 569 @NonNull NetworkAgentConfig config, @NonNull NetworkInfo info) { 570 this.context = context; 571 this.capabilities = capabilities; 572 this.properties = properties; 573 this.score = score; 574 this.config = config; 575 this.info = info; 576 this.localNetworkConfig = localNetworkConfig; 577 } 578 } 579 private volatile InitialConfiguration mInitialConfiguration; 580 NetworkAgent(@onNull Looper looper, @NonNull Context context, @NonNull String logTag, @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, @Nullable LocalNetworkConfig localNetworkConfig, @NonNull NetworkScore score, @NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni)581 private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag, 582 @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, 583 @Nullable LocalNetworkConfig localNetworkConfig, @NonNull NetworkScore score, 584 @NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni) { 585 mHandler = new NetworkAgentHandler(looper); 586 LOG_TAG = logTag; 587 mNetworkInfo = new NetworkInfo(ni); 588 this.providerId = providerId; 589 if (ni == null || nc == null || lp == null) { 590 throw new IllegalArgumentException(); 591 } 592 593 mInitialConfiguration = new InitialConfiguration(context, 594 new NetworkCapabilities(nc, NetworkCapabilities.REDACT_NONE), 595 new LinkProperties(lp), localNetworkConfig, score, config, ni); 596 } 597 598 private class NetworkAgentHandler extends Handler { NetworkAgentHandler(Looper looper)599 NetworkAgentHandler(Looper looper) { 600 super(looper); 601 } 602 603 @Override handleMessage(Message msg)604 public void handleMessage(Message msg) { 605 switch (msg.what) { 606 case EVENT_AGENT_CONNECTED: { 607 if (mRegistry != null) { 608 log("Received new connection while already connected!"); 609 } else { 610 if (VDBG) log("NetworkAgent fully connected"); 611 synchronized (mPreConnectedQueue) { 612 final INetworkAgentRegistry registry = (INetworkAgentRegistry) msg.obj; 613 mRegistry = registry; 614 for (RegistryAction a : mPreConnectedQueue) { 615 try { 616 a.execute(registry); 617 } catch (RemoteException e) { 618 Log.wtf(LOG_TAG, "Communication error with registry", e); 619 // Fall through 620 } 621 } 622 mPreConnectedQueue.clear(); 623 } 624 } 625 break; 626 } 627 case EVENT_AGENT_DISCONNECTED: { 628 if (DBG) log("NetworkAgent channel lost"); 629 // let the client know CS is done with us. 630 onNetworkUnwanted(); 631 synchronized (mPreConnectedQueue) { 632 mRegistry = null; 633 } 634 break; 635 } 636 case CMD_SUSPECT_BAD: { 637 log("Unhandled Message " + msg); 638 break; 639 } 640 case CMD_REQUEST_BANDWIDTH_UPDATE: { 641 long currentTimeMs = System.currentTimeMillis(); 642 if (VDBG) { 643 log("CMD_REQUEST_BANDWIDTH_UPDATE request received."); 644 } 645 if (currentTimeMs >= (mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS)) { 646 mBandwidthUpdateScheduled = false; 647 if (!mBandwidthUpdatePending.getAndSet(true)) { 648 onBandwidthUpdateRequested(); 649 } 650 } else { 651 // deliver the request at a later time rather than discard it completely. 652 if (!mBandwidthUpdateScheduled) { 653 long waitTime = mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS 654 - currentTimeMs + 1; 655 mBandwidthUpdateScheduled = sendEmptyMessageDelayed( 656 CMD_REQUEST_BANDWIDTH_UPDATE, waitTime); 657 } 658 } 659 break; 660 } 661 case CMD_REPORT_NETWORK_STATUS: { 662 String redirectUrl = ((Bundle) msg.obj).getString(REDIRECT_URL_KEY); 663 if (VDBG) { 664 log("CMD_REPORT_NETWORK_STATUS(" 665 + (msg.arg1 == VALID_NETWORK ? "VALID, " : "INVALID, ") 666 + redirectUrl); 667 } 668 Uri uri = null; 669 try { 670 if (null != redirectUrl) { 671 uri = Uri.parse(redirectUrl); 672 } 673 } catch (Exception e) { 674 Log.wtf(LOG_TAG, "Surprising URI : " + redirectUrl, e); 675 } 676 onValidationStatus(msg.arg1 /* status */, uri); 677 break; 678 } 679 case CMD_SAVE_ACCEPT_UNVALIDATED: { 680 onSaveAcceptUnvalidated(msg.arg1 != 0); 681 break; 682 } 683 case CMD_START_SOCKET_KEEPALIVE: { 684 onStartSocketKeepalive(msg.arg1 /* slot */, 685 Duration.ofSeconds(msg.arg2) /* interval */, 686 (KeepalivePacketData) msg.obj /* packet */); 687 break; 688 } 689 case CMD_STOP_SOCKET_KEEPALIVE: { 690 onStopSocketKeepalive(msg.arg1 /* slot */); 691 break; 692 } 693 694 case CMD_SET_SIGNAL_STRENGTH_THRESHOLDS: { 695 onSignalStrengthThresholdsUpdated((int[]) msg.obj); 696 break; 697 } 698 case CMD_PREVENT_AUTOMATIC_RECONNECT: { 699 onAutomaticReconnectDisabled(); 700 break; 701 } 702 case CMD_ADD_KEEPALIVE_PACKET_FILTER: { 703 onAddKeepalivePacketFilter(msg.arg1 /* slot */, 704 (KeepalivePacketData) msg.obj /* packet */); 705 break; 706 } 707 case CMD_REMOVE_KEEPALIVE_PACKET_FILTER: { 708 onRemoveKeepalivePacketFilter(msg.arg1 /* slot */); 709 break; 710 } 711 case CMD_REGISTER_QOS_CALLBACK: { 712 onQosCallbackRegistered( 713 msg.arg1 /* QoS callback id */, 714 (QosFilter) msg.obj /* QoS filter */); 715 break; 716 } 717 case CMD_UNREGISTER_QOS_CALLBACK: { 718 onQosCallbackUnregistered( 719 msg.arg1 /* QoS callback id */); 720 break; 721 } 722 case CMD_NETWORK_CREATED: { 723 onNetworkCreated(); 724 break; 725 } 726 case CMD_NETWORK_DESTROYED: { 727 onNetworkDestroyed(); 728 break; 729 } 730 case CMD_DSCP_POLICY_STATUS: { 731 onDscpPolicyStatusUpdated( 732 msg.arg1 /* Policy ID */, 733 msg.arg2 /* DSCP Policy Status */); 734 break; 735 } 736 } 737 } 738 } 739 740 /** 741 * Register this network agent with ConnectivityService. 742 * 743 * This method can only be called once per network agent. 744 * 745 * @return the Network associated with this network agent (which can also be obtained later 746 * by calling getNetwork() on this agent). 747 * @throws IllegalStateException thrown by the system server if this network agent is 748 * already registered. 749 */ 750 @NonNull register()751 public Network register() { 752 if (VDBG) log("Registering NetworkAgent"); 753 synchronized (mRegisterLock) { 754 if (mNetwork != null) { 755 throw new IllegalStateException("Agent already registered"); 756 } 757 final ConnectivityManager cm = (ConnectivityManager) mInitialConfiguration.context 758 .getSystemService(Context.CONNECTIVITY_SERVICE); 759 if (mInitialConfiguration.localNetworkConfig == null) { 760 // Call registerNetworkAgent without localNetworkConfig argument to pass 761 // android.net.cts.NetworkAgentTest#testAgentStartsInConnecting in old cts 762 mNetwork = cm.registerNetworkAgent(new NetworkAgentBinder(mHandler), 763 new NetworkInfo(mInitialConfiguration.info), 764 mInitialConfiguration.properties, mInitialConfiguration.capabilities, 765 mInitialConfiguration.score, mInitialConfiguration.config, providerId); 766 } else { 767 mNetwork = cm.registerNetworkAgent(new NetworkAgentBinder(mHandler), 768 new NetworkInfo(mInitialConfiguration.info), 769 mInitialConfiguration.properties, mInitialConfiguration.capabilities, 770 mInitialConfiguration.localNetworkConfig, mInitialConfiguration.score, 771 mInitialConfiguration.config, providerId); 772 } 773 mInitialConfiguration = null; // All this memory can now be GC'd 774 } 775 return mNetwork; 776 } 777 778 private static class NetworkAgentBinder extends INetworkAgent.Stub { 779 private static final String LOG_TAG = NetworkAgentBinder.class.getSimpleName(); 780 781 private final Handler mHandler; 782 NetworkAgentBinder(Handler handler)783 private NetworkAgentBinder(Handler handler) { 784 mHandler = handler; 785 } 786 787 @Override onRegistered(@onNull INetworkAgentRegistry registry)788 public void onRegistered(@NonNull INetworkAgentRegistry registry) { 789 mHandler.sendMessage(mHandler.obtainMessage(EVENT_AGENT_CONNECTED, registry)); 790 } 791 792 @Override onDisconnected()793 public void onDisconnected() { 794 mHandler.sendMessage(mHandler.obtainMessage(EVENT_AGENT_DISCONNECTED)); 795 } 796 797 @Override onBandwidthUpdateRequested()798 public void onBandwidthUpdateRequested() { 799 mHandler.sendMessage(mHandler.obtainMessage(CMD_REQUEST_BANDWIDTH_UPDATE)); 800 } 801 802 @Override onValidationStatusChanged( int validationStatus, @Nullable String captivePortalUrl)803 public void onValidationStatusChanged( 804 int validationStatus, @Nullable String captivePortalUrl) { 805 // TODO: consider using a parcelable as argument when the interface is structured 806 Bundle redirectUrlBundle = new Bundle(); 807 redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, captivePortalUrl); 808 mHandler.sendMessage(mHandler.obtainMessage(CMD_REPORT_NETWORK_STATUS, 809 validationStatus, 0, redirectUrlBundle)); 810 } 811 812 @Override onSaveAcceptUnvalidated(boolean acceptUnvalidated)813 public void onSaveAcceptUnvalidated(boolean acceptUnvalidated) { 814 mHandler.sendMessage(mHandler.obtainMessage(CMD_SAVE_ACCEPT_UNVALIDATED, 815 acceptUnvalidated ? 1 : 0, 0)); 816 } 817 818 @Override onStartNattSocketKeepalive(int slot, int intervalDurationMs, @NonNull NattKeepalivePacketData packetData)819 public void onStartNattSocketKeepalive(int slot, int intervalDurationMs, 820 @NonNull NattKeepalivePacketData packetData) { 821 mHandler.sendMessage(mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, 822 slot, intervalDurationMs, packetData)); 823 } 824 825 @Override onStartTcpSocketKeepalive(int slot, int intervalDurationMs, @NonNull TcpKeepalivePacketData packetData)826 public void onStartTcpSocketKeepalive(int slot, int intervalDurationMs, 827 @NonNull TcpKeepalivePacketData packetData) { 828 mHandler.sendMessage(mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, 829 slot, intervalDurationMs, packetData)); 830 } 831 832 @Override onStopSocketKeepalive(int slot)833 public void onStopSocketKeepalive(int slot) { 834 mHandler.sendMessage(mHandler.obtainMessage(CMD_STOP_SOCKET_KEEPALIVE, slot, 0)); 835 } 836 837 @Override onSignalStrengthThresholdsUpdated(@onNull int[] thresholds)838 public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) { 839 mHandler.sendMessage(mHandler.obtainMessage( 840 CMD_SET_SIGNAL_STRENGTH_THRESHOLDS, thresholds)); 841 } 842 843 @Override onPreventAutomaticReconnect()844 public void onPreventAutomaticReconnect() { 845 mHandler.sendMessage(mHandler.obtainMessage(CMD_PREVENT_AUTOMATIC_RECONNECT)); 846 } 847 848 @Override onAddNattKeepalivePacketFilter(int slot, @NonNull NattKeepalivePacketData packetData)849 public void onAddNattKeepalivePacketFilter(int slot, 850 @NonNull NattKeepalivePacketData packetData) { 851 mHandler.sendMessage(mHandler.obtainMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER, 852 slot, 0, packetData)); 853 } 854 855 @Override onAddTcpKeepalivePacketFilter(int slot, @NonNull TcpKeepalivePacketData packetData)856 public void onAddTcpKeepalivePacketFilter(int slot, 857 @NonNull TcpKeepalivePacketData packetData) { 858 mHandler.sendMessage(mHandler.obtainMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER, 859 slot, 0, packetData)); 860 } 861 862 @Override onRemoveKeepalivePacketFilter(int slot)863 public void onRemoveKeepalivePacketFilter(int slot) { 864 mHandler.sendMessage(mHandler.obtainMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, 865 slot, 0)); 866 } 867 868 @Override onQosFilterCallbackRegistered(final int qosCallbackId, final QosFilterParcelable qosFilterParcelable)869 public void onQosFilterCallbackRegistered(final int qosCallbackId, 870 final QosFilterParcelable qosFilterParcelable) { 871 if (qosFilterParcelable.getQosFilter() != null) { 872 mHandler.sendMessage( 873 mHandler.obtainMessage(CMD_REGISTER_QOS_CALLBACK, qosCallbackId, 0, 874 qosFilterParcelable.getQosFilter())); 875 return; 876 } 877 878 Log.wtf(LOG_TAG, "onQosFilterCallbackRegistered: qos filter is null."); 879 } 880 881 @Override onQosCallbackUnregistered(final int qosCallbackId)882 public void onQosCallbackUnregistered(final int qosCallbackId) { 883 mHandler.sendMessage(mHandler.obtainMessage( 884 CMD_UNREGISTER_QOS_CALLBACK, qosCallbackId, 0, null)); 885 } 886 887 @Override onNetworkCreated()888 public void onNetworkCreated() { 889 mHandler.sendMessage(mHandler.obtainMessage(CMD_NETWORK_CREATED)); 890 } 891 892 @Override onNetworkDestroyed()893 public void onNetworkDestroyed() { 894 mHandler.sendMessage(mHandler.obtainMessage(CMD_NETWORK_DESTROYED)); 895 } 896 897 @Override onDscpPolicyStatusUpdated(final int policyId, @DscpPolicyStatus final int status)898 public void onDscpPolicyStatusUpdated(final int policyId, 899 @DscpPolicyStatus final int status) { 900 mHandler.sendMessage(mHandler.obtainMessage( 901 CMD_DSCP_POLICY_STATUS, policyId, status)); 902 } 903 } 904 905 /** 906 * Register this network agent with a testing harness. 907 * 908 * The returned Messenger sends messages to the Handler. This allows a test to send 909 * this object {@code CMD_*} messages as if they came from ConnectivityService, which 910 * is useful for testing the behavior. 911 * 912 * @hide 913 */ registerForTest(final Network network)914 public INetworkAgent registerForTest(final Network network) { 915 log("Registering NetworkAgent for test"); 916 synchronized (mRegisterLock) { 917 mNetwork = network; 918 mInitialConfiguration = null; 919 } 920 return new NetworkAgentBinder(mHandler); 921 } 922 923 /** 924 * Waits for the handler to be idle. 925 * This is useful for testing, and has smaller scope than an accessor to mHandler. 926 * TODO : move the implementation in common library with the tests 927 * @hide 928 */ 929 @VisibleForTesting waitForIdle(final long timeoutMs)930 public boolean waitForIdle(final long timeoutMs) { 931 final ConditionVariable cv = new ConditionVariable(false); 932 mHandler.post(cv::open); 933 return cv.block(timeoutMs); 934 } 935 936 /** 937 * @return The Network associated with this agent, or null if it's not registered yet. 938 */ 939 @Nullable getNetwork()940 public Network getNetwork() { 941 return mNetwork; 942 } 943 queueOrSendMessage(@onNull RegistryAction action)944 private void queueOrSendMessage(@NonNull RegistryAction action) { 945 synchronized (mPreConnectedQueue) { 946 if (mRegistry != null) { 947 try { 948 action.execute(mRegistry); 949 } catch (RemoteException e) { 950 Log.wtf(LOG_TAG, "Error executing registry action", e); 951 // Fall through: the channel is asynchronous and does not report errors back 952 } 953 } else { 954 mPreConnectedQueue.add(action); 955 } 956 } 957 } 958 959 /** 960 * Must be called by the agent when the network's {@link LinkProperties} change. 961 * @param linkProperties the new LinkProperties. 962 */ sendLinkProperties(@onNull LinkProperties linkProperties)963 public void sendLinkProperties(@NonNull LinkProperties linkProperties) { 964 Objects.requireNonNull(linkProperties); 965 final LinkProperties lp = new LinkProperties(linkProperties); 966 queueOrSendMessage(reg -> reg.sendLinkProperties(lp)); 967 } 968 969 /** 970 * Must be called by the agent when the network's underlying networks change. 971 * 972 * <p>{@code networks} is one of the following: 973 * <ul> 974 * <li><strong>a non-empty array</strong>: an array of one or more {@link Network}s, in 975 * decreasing preference order. For example, if this VPN uses both wifi and mobile (cellular) 976 * networks to carry app traffic, but prefers or uses wifi more than mobile, wifi should appear 977 * first in the array.</li> 978 * <li><strong>an empty array</strong>: a zero-element array, meaning that the VPN has no 979 * underlying network connection, and thus, app traffic will not be sent or received.</li> 980 * <li><strong>null</strong>: (default) signifies that the VPN uses whatever is the system's 981 * default network. I.e., it doesn't use the {@code bindSocket} or {@code bindDatagramSocket} 982 * APIs mentioned above to send traffic over specific channels.</li> 983 * </ul> 984 * 985 * @param underlyingNetworks the new list of underlying networks. 986 * @see {@link VpnService.Builder#setUnderlyingNetworks(Network[])} 987 */ setUnderlyingNetworks( @uppressLint"NullableCollection") @ullable List<Network> underlyingNetworks)988 public void setUnderlyingNetworks( 989 @SuppressLint("NullableCollection") @Nullable List<Network> underlyingNetworks) { 990 final ArrayList<Network> underlyingArray = (underlyingNetworks != null) 991 ? new ArrayList<>(underlyingNetworks) : null; 992 queueOrSendMessage(reg -> reg.sendUnderlyingNetworks(underlyingArray)); 993 } 994 995 /** 996 * Inform ConnectivityService that this agent has now connected. 997 * Call {@link #unregister} to disconnect. 998 */ markConnected()999 public void markConnected() { 1000 mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null /* reason */, 1001 mNetworkInfo.getExtraInfo()); 1002 queueOrSendNetworkInfo(mNetworkInfo); 1003 } 1004 1005 /** 1006 * Unregister this network agent. 1007 * 1008 * This signals the network has disconnected and ends its lifecycle. After this is called, 1009 * the network is torn down and this agent can no longer be used. 1010 */ unregister()1011 public void unregister() { 1012 // When unregistering an agent nobody should use the extrainfo (or reason) any more. 1013 mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null /* reason */, 1014 null /* extraInfo */); 1015 queueOrSendNetworkInfo(mNetworkInfo); 1016 } 1017 1018 /** 1019 * Sets the value of the teardown delay. 1020 * 1021 * The teardown delay is the time between when the network disconnects and when the native 1022 * network corresponding to this {@code NetworkAgent} is destroyed. By default, the native 1023 * network is destroyed immediately. If {@code teardownDelayMs} is non-zero, then when this 1024 * network disconnects, the system will instead immediately mark the network as restricted 1025 * and unavailable to unprivileged apps, but will defer destroying the native network until the 1026 * teardown delay timer expires. 1027 * 1028 * The interfaces in use by this network will remain in use until the native network is 1029 * destroyed and cannot be reused until {@link #onNetworkDestroyed()} is called. 1030 * 1031 * This method may be called at any time while the network is connected. It has no effect if 1032 * the network is already disconnected and the teardown delay timer is running. 1033 * 1034 * @param teardownDelayMillis the teardown delay to set, or 0 to disable teardown delay. 1035 */ setTeardownDelayMillis( @ntRangefrom = 0, to = MAX_TEARDOWN_DELAY_MS) int teardownDelayMillis)1036 public void setTeardownDelayMillis( 1037 @IntRange(from = 0, to = MAX_TEARDOWN_DELAY_MS) int teardownDelayMillis) { 1038 queueOrSendMessage(reg -> reg.sendTeardownDelayMs(teardownDelayMillis)); 1039 } 1040 1041 /** 1042 * Indicates that this agent will likely soon be replaced by another agent for a very similar 1043 * network (e.g., same Wi-Fi SSID). 1044 * 1045 * If the network is not currently satisfying any {@link NetworkRequest}s, it will be torn down. 1046 * If it is satisfying requests, then the native network corresponding to the agent will be 1047 * destroyed immediately, but the agent will remain registered and will continue to satisfy 1048 * requests until {@link #unregister} is called, the network is replaced by an equivalent or 1049 * better network, or the specified timeout expires. During this time: 1050 * 1051 * <ul> 1052 * <li>The agent may not send any further updates, for example by calling methods 1053 * such as {@link #sendNetworkCapabilities}, {@link #sendLinkProperties}, 1054 * {@link #sendNetworkScore(NetworkScore)} and so on. Any such updates will be ignored. 1055 * <li>The network will remain connected and continue to satisfy any requests that it would 1056 * otherwise satisfy (including, possibly, the default request). 1057 * <li>The validation state of the network will not change, and calls to 1058 * {@link ConnectivityManager#reportNetworkConnectivity(Network, boolean)} will be ignored. 1059 * </ul> 1060 * 1061 * Once this method is called, it is not possible to restore the agent to a functioning state. 1062 * If a replacement network becomes available, then a new agent must be registered. When that 1063 * replacement network is fully capable of replacing this network (including, possibly, being 1064 * validated), this agent will no longer be needed and will be torn down. Otherwise, this agent 1065 * can be disconnected by calling {@link #unregister}. If {@link #unregister} is not called, 1066 * this agent will automatically be unregistered when the specified timeout expires. Any 1067 * teardown delay previously set using{@link #setTeardownDelayMillis} is ignored. 1068 * 1069 * <p>This method has no effect if {@link #markConnected} has not yet been called. 1070 * <p>This method may only be called once. 1071 * 1072 * @param timeoutMillis the timeout after which this network will be unregistered even if 1073 * {@link #unregister} was not called. 1074 */ unregisterAfterReplacement( @ntRangefrom = 0, to = MAX_TEARDOWN_DELAY_MS) int timeoutMillis)1075 public void unregisterAfterReplacement( 1076 @IntRange(from = 0, to = MAX_TEARDOWN_DELAY_MS) int timeoutMillis) { 1077 queueOrSendMessage(reg -> reg.sendUnregisterAfterReplacement(timeoutMillis)); 1078 } 1079 1080 /** 1081 * Change the legacy subtype of this network agent. 1082 * 1083 * This is only for backward compatibility and should not be used by non-legacy network agents, 1084 * or agents that did not use to set a subtype. As such, only TYPE_MOBILE type agents can use 1085 * this and others will be thrown an exception if they try. 1086 * 1087 * @deprecated this is for backward compatibility only. 1088 * @param legacySubtype the legacy subtype. 1089 * @hide 1090 */ 1091 @Deprecated 1092 @SystemApi setLegacySubtype(final int legacySubtype, @NonNull final String legacySubtypeName)1093 public void setLegacySubtype(final int legacySubtype, @NonNull final String legacySubtypeName) { 1094 mNetworkInfo.setSubtype(legacySubtype, legacySubtypeName); 1095 queueOrSendNetworkInfo(mNetworkInfo); 1096 } 1097 1098 /** 1099 * Set the ExtraInfo of this network agent. 1100 * 1101 * This sets the ExtraInfo field inside the NetworkInfo returned by legacy public API and the 1102 * broadcasts about the corresponding Network. 1103 * This is only for backward compatibility and should not be used by non-legacy network agents, 1104 * who will be thrown an exception if they try. The extra info should only be : 1105 * <ul> 1106 * <li>For cellular agents, the APN name.</li> 1107 * <li>For ethernet agents, the interface name.</li> 1108 * </ul> 1109 * 1110 * @deprecated this is for backward compatibility only. 1111 * @param extraInfo the ExtraInfo. 1112 * @hide 1113 */ 1114 @Deprecated setLegacyExtraInfo(@ullable final String extraInfo)1115 public void setLegacyExtraInfo(@Nullable final String extraInfo) { 1116 mNetworkInfo.setExtraInfo(extraInfo); 1117 queueOrSendNetworkInfo(mNetworkInfo); 1118 } 1119 1120 /** 1121 * Must be called by the agent when it has a new NetworkInfo object. 1122 * @hide TODO: expose something better. 1123 */ 1124 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) sendNetworkInfo(NetworkInfo networkInfo)1125 public final void sendNetworkInfo(NetworkInfo networkInfo) { 1126 queueOrSendNetworkInfo(networkInfo); 1127 } 1128 queueOrSendNetworkInfo(NetworkInfo networkInfo)1129 private void queueOrSendNetworkInfo(NetworkInfo networkInfo) { 1130 final NetworkInfo ni = new NetworkInfo(networkInfo); 1131 queueOrSendMessage(reg -> reg.sendNetworkInfo(ni)); 1132 } 1133 1134 /** 1135 * Must be called by the agent when the network's {@link NetworkCapabilities} change. 1136 * @param networkCapabilities the new NetworkCapabilities. 1137 */ sendNetworkCapabilities(@onNull NetworkCapabilities networkCapabilities)1138 public void sendNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) { 1139 Objects.requireNonNull(networkCapabilities); 1140 mBandwidthUpdatePending.set(false); 1141 mLastBwRefreshTime = System.currentTimeMillis(); 1142 final NetworkCapabilities nc = 1143 new NetworkCapabilities(networkCapabilities, NetworkCapabilities.REDACT_NONE); 1144 queueOrSendMessage(reg -> reg.sendNetworkCapabilities(nc)); 1145 } 1146 1147 /** 1148 * Must be called by the agent when the network's {@link LocalNetworkConfig} changes. 1149 * @param config the new LocalNetworkConfig 1150 * @hide 1151 */ sendLocalNetworkConfig(@onNull LocalNetworkConfig config)1152 public void sendLocalNetworkConfig(@NonNull LocalNetworkConfig config) { 1153 Objects.requireNonNull(config); 1154 // If the agent doesn't have NET_CAPABILITY_LOCAL_NETWORK, this will be ignored by 1155 // ConnectivityService with a Log.wtf. 1156 queueOrSendMessage(reg -> reg.sendLocalNetworkConfig(config)); 1157 } 1158 1159 /** 1160 * Must be called by the agent to update the score of this network. 1161 * 1162 * @param score the new score. 1163 */ sendNetworkScore(@onNull NetworkScore score)1164 public void sendNetworkScore(@NonNull NetworkScore score) { 1165 Objects.requireNonNull(score); 1166 queueOrSendMessage(reg -> reg.sendScore(score)); 1167 } 1168 1169 /** 1170 * Must be called by the agent to update the score of this network. 1171 * 1172 * @param score the new score, between 0 and 99. 1173 * deprecated use sendNetworkScore(NetworkScore) TODO : remove in S. 1174 */ sendNetworkScore(@ntRangefrom = 0, to = 99) int score)1175 public void sendNetworkScore(@IntRange(from = 0, to = 99) int score) { 1176 sendNetworkScore(new NetworkScore.Builder().setLegacyInt(score).build()); 1177 } 1178 1179 /** 1180 * Must be called by the agent to indicate this network was manually selected by the user. 1181 * This should be called before the NetworkInfo is marked CONNECTED so that this 1182 * Network can be given special treatment at that time. If {@code acceptUnvalidated} is 1183 * {@code true}, then the system will switch to this network. If it is {@code false} and the 1184 * network cannot be validated, the system will ask the user whether to switch to this network. 1185 * If the user confirms and selects "don't ask again", then the system will call 1186 * {@link #saveAcceptUnvalidated} to persist the user's choice. Thus, if the transport ever 1187 * calls this method with {@code acceptUnvalidated} set to {@code false}, it must also implement 1188 * {@link #saveAcceptUnvalidated} to respect the user's choice. 1189 * @hide should move to NetworkAgentConfig. 1190 */ explicitlySelected(boolean acceptUnvalidated)1191 public void explicitlySelected(boolean acceptUnvalidated) { 1192 explicitlySelected(true /* explicitlySelected */, acceptUnvalidated); 1193 } 1194 1195 /** 1196 * Must be called by the agent to indicate whether the network was manually selected by the 1197 * user. This should be called before the network becomes connected, so it can be given 1198 * special treatment when it does. 1199 * 1200 * If {@code explicitlySelected} is {@code true}, and {@code acceptUnvalidated} is {@code true}, 1201 * then the system will switch to this network. If {@code explicitlySelected} is {@code true} 1202 * and {@code acceptUnvalidated} is {@code false}, and the network cannot be validated, the 1203 * system will ask the user whether to switch to this network. If the user confirms and selects 1204 * "don't ask again", then the system will call {@link #saveAcceptUnvalidated} to persist the 1205 * user's choice. Thus, if the transport ever calls this method with {@code explicitlySelected} 1206 * set to {@code true} and {@code acceptUnvalidated} set to {@code false}, it must also 1207 * implement {@link #saveAcceptUnvalidated} to respect the user's choice. 1208 * 1209 * If {@code explicitlySelected} is {@code false} and {@code acceptUnvalidated} is 1210 * {@code true}, the system will interpret this as the user having accepted partial connectivity 1211 * on this network. Thus, the system will switch to the network and consider it validated even 1212 * if it only provides partial connectivity, but the network is not otherwise treated specially. 1213 * @hide should move to NetworkAgentConfig. 1214 */ explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated)1215 public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) { 1216 queueOrSendMessage(reg -> reg.sendExplicitlySelected( 1217 explicitlySelected, acceptUnvalidated)); 1218 } 1219 1220 /** 1221 * Called when ConnectivityService has indicated they no longer want this network. 1222 * The parent factory should (previously) have received indication of the change 1223 * as well, either canceling NetworkRequests or altering their score such that this 1224 * network won't be immediately requested again. 1225 */ onNetworkUnwanted()1226 public void onNetworkUnwanted() { 1227 unwanted(); 1228 } 1229 /** @hide TODO delete once subclasses have moved to onNetworkUnwanted. */ unwanted()1230 protected void unwanted() { 1231 } 1232 1233 /** 1234 * Called when ConnectivityService request a bandwidth update. The parent factory 1235 * shall try to overwrite this method and produce a bandwidth update if capable. 1236 * @hide 1237 */ 1238 @SystemApi onBandwidthUpdateRequested()1239 public void onBandwidthUpdateRequested() { 1240 pollLceData(); 1241 } 1242 /** @hide TODO delete once subclasses have moved to onBandwidthUpdateRequested. */ pollLceData()1243 protected void pollLceData() { 1244 } 1245 1246 /** 1247 * Called when the system determines the usefulness of this network. 1248 * 1249 * The system attempts to validate Internet connectivity on networks that provide the 1250 * {@link NetworkCapabilities#NET_CAPABILITY_INTERNET} capability. 1251 * 1252 * Currently there are two possible values: 1253 * {@code VALIDATION_STATUS_VALID} if Internet connectivity was validated, 1254 * {@code VALIDATION_STATUS_NOT_VALID} if Internet connectivity was not validated. 1255 * 1256 * This is guaranteed to be called again when the network status changes, but the system 1257 * may also call this multiple times even if the status does not change. 1258 * 1259 * @param status one of {@code VALIDATION_STATUS_VALID} or {@code VALIDATION_STATUS_NOT_VALID}. 1260 * @param redirectUri If Internet connectivity is being redirected (e.g., on a captive portal), 1261 * this is the destination the probes are being redirected to, otherwise {@code null}. 1262 */ onValidationStatus(@alidationStatus int status, @Nullable Uri redirectUri)1263 public void onValidationStatus(@ValidationStatus int status, @Nullable Uri redirectUri) { 1264 networkStatus(status, null == redirectUri ? "" : redirectUri.toString()); 1265 } 1266 /** @hide TODO delete once subclasses have moved to onValidationStatus */ networkStatus(int status, String redirectUrl)1267 protected void networkStatus(int status, String redirectUrl) { 1268 } 1269 1270 1271 /** 1272 * Called when the user asks to remember the choice to use this network even if unvalidated. 1273 * The transport is responsible for remembering the choice, and the next time the user connects 1274 * to the network, should explicitlySelected with {@code acceptUnvalidated} set to {@code true}. 1275 * This method will only be called if {@link #explicitlySelected} was called with 1276 * {@code acceptUnvalidated} set to {@code false}. 1277 * @param accept whether the user wants to use the network even if unvalidated. 1278 */ onSaveAcceptUnvalidated(boolean accept)1279 public void onSaveAcceptUnvalidated(boolean accept) { 1280 saveAcceptUnvalidated(accept); 1281 } 1282 /** @hide TODO delete once subclasses have moved to onSaveAcceptUnvalidated */ saveAcceptUnvalidated(boolean accept)1283 protected void saveAcceptUnvalidated(boolean accept) { 1284 } 1285 1286 /** 1287 * Called when ConnectivityService has successfully created this NetworkAgent's native network. 1288 */ onNetworkCreated()1289 public void onNetworkCreated() {} 1290 1291 1292 /** 1293 * Called when ConnectivityService has successfully destroy this NetworkAgent's native network. 1294 */ onNetworkDestroyed()1295 public void onNetworkDestroyed() {} 1296 1297 /** 1298 * Called when when the DSCP Policy status has changed. 1299 */ onDscpPolicyStatusUpdated(int policyId, @DscpPolicyStatus int status)1300 public void onDscpPolicyStatusUpdated(int policyId, @DscpPolicyStatus int status) {} 1301 1302 /** 1303 * Requests that the network hardware send the specified packet at the specified interval. 1304 * 1305 * @param slot the hardware slot on which to start the keepalive. 1306 * @param interval the interval between packets, between 10 and 3600. Note that this API 1307 * does not support sub-second precision and will round off the request. 1308 * @param packet the packet to send. 1309 */ 1310 // seconds is from SocketKeepalive.MIN_INTERVAL_SEC to MAX_INTERVAL_SEC, but these should 1311 // not be exposed as constants because they may change in the future (API guideline 4.8) 1312 // and should have getters if exposed at all. Getters can't be used in the annotation, 1313 // so the values unfortunately need to be copied. onStartSocketKeepalive(int slot, @NonNull Duration interval, @NonNull KeepalivePacketData packet)1314 public void onStartSocketKeepalive(int slot, @NonNull Duration interval, 1315 @NonNull KeepalivePacketData packet) { 1316 final long intervalSeconds = interval.getSeconds(); 1317 if (intervalSeconds < SocketKeepalive.MIN_INTERVAL_SEC 1318 || intervalSeconds > SocketKeepalive.MAX_INTERVAL_SEC) { 1319 throw new IllegalArgumentException("Interval needs to be comprised between " 1320 + SocketKeepalive.MIN_INTERVAL_SEC + " and " + SocketKeepalive.MAX_INTERVAL_SEC 1321 + " but was " + intervalSeconds); 1322 } 1323 final Message msg = mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, slot, 1324 (int) intervalSeconds, packet); 1325 startSocketKeepalive(msg); 1326 msg.recycle(); 1327 } 1328 /** @hide TODO delete once subclasses have moved to onStartSocketKeepalive */ startSocketKeepalive(Message msg)1329 protected void startSocketKeepalive(Message msg) { 1330 onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); 1331 } 1332 1333 /** 1334 * Requests that the network hardware stop a previously-started keepalive. 1335 * 1336 * @param slot the hardware slot on which to stop the keepalive. 1337 */ onStopSocketKeepalive(int slot)1338 public void onStopSocketKeepalive(int slot) { 1339 Message msg = mHandler.obtainMessage(CMD_STOP_SOCKET_KEEPALIVE, slot, 0, null); 1340 stopSocketKeepalive(msg); 1341 msg.recycle(); 1342 } 1343 /** @hide TODO delete once subclasses have moved to onStopSocketKeepalive */ stopSocketKeepalive(Message msg)1344 protected void stopSocketKeepalive(Message msg) { 1345 onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); 1346 } 1347 1348 /** 1349 * Must be called by the agent when a socket keepalive event occurs. 1350 * 1351 * @param slot the hardware slot on which the event occurred. 1352 * @param event the event that occurred, as one of the SocketKeepalive.ERROR_* 1353 * or SocketKeepalive.SUCCESS constants. 1354 */ sendSocketKeepaliveEvent(int slot, @SocketKeepalive.KeepaliveEvent int event)1355 public final void sendSocketKeepaliveEvent(int slot, 1356 @SocketKeepalive.KeepaliveEvent int event) { 1357 queueOrSendMessage(reg -> reg.sendSocketKeepaliveEvent(slot, event)); 1358 } 1359 /** @hide TODO delete once callers have moved to sendSocketKeepaliveEvent */ onSocketKeepaliveEvent(int slot, int reason)1360 public void onSocketKeepaliveEvent(int slot, int reason) { 1361 sendSocketKeepaliveEvent(slot, reason); 1362 } 1363 1364 /** 1365 * Called by ConnectivityService to add specific packet filter to network hardware to block 1366 * replies (e.g., TCP ACKs) matching the sent keepalive packets. Implementations that support 1367 * this feature must override this method. 1368 * 1369 * @param slot the hardware slot on which the keepalive should be sent. 1370 * @param packet the packet that is being sent. 1371 */ onAddKeepalivePacketFilter(int slot, @NonNull KeepalivePacketData packet)1372 public void onAddKeepalivePacketFilter(int slot, @NonNull KeepalivePacketData packet) { 1373 Message msg = mHandler.obtainMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER, slot, 0, packet); 1374 addKeepalivePacketFilter(msg); 1375 msg.recycle(); 1376 } 1377 /** @hide TODO delete once subclasses have moved to onAddKeepalivePacketFilter */ addKeepalivePacketFilter(Message msg)1378 protected void addKeepalivePacketFilter(Message msg) { 1379 } 1380 1381 /** 1382 * Called by ConnectivityService to remove a packet filter installed with 1383 * {@link #addKeepalivePacketFilter(Message)}. Implementations that support this feature 1384 * must override this method. 1385 * 1386 * @param slot the hardware slot on which the keepalive is being sent. 1387 */ onRemoveKeepalivePacketFilter(int slot)1388 public void onRemoveKeepalivePacketFilter(int slot) { 1389 Message msg = mHandler.obtainMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, slot, 0, null); 1390 removeKeepalivePacketFilter(msg); 1391 msg.recycle(); 1392 } 1393 /** @hide TODO delete once subclasses have moved to onRemoveKeepalivePacketFilter */ removeKeepalivePacketFilter(Message msg)1394 protected void removeKeepalivePacketFilter(Message msg) { 1395 } 1396 1397 /** 1398 * Called by ConnectivityService to inform this network agent of signal strength thresholds 1399 * that when crossed should trigger a system wakeup and a NetworkCapabilities update. 1400 * 1401 * When the system updates the list of thresholds that should wake up the CPU for a 1402 * given agent it will call this method on the agent. The agent that implement this 1403 * should implement it in hardware so as to ensure the CPU will be woken up on breach. 1404 * Agents are expected to react to a breach by sending an updated NetworkCapabilities 1405 * object with the appropriate signal strength to sendNetworkCapabilities. 1406 * 1407 * The specific units are bearer-dependent. See details on the units and requests in 1408 * {@link NetworkCapabilities.Builder#setSignalStrength}. 1409 * 1410 * @param thresholds the array of thresholds that should trigger wakeups. 1411 */ onSignalStrengthThresholdsUpdated(@onNull int[] thresholds)1412 public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) { 1413 setSignalStrengthThresholds(thresholds); 1414 } 1415 /** @hide TODO delete once subclasses have moved to onSetSignalStrengthThresholds */ setSignalStrengthThresholds(int[] thresholds)1416 protected void setSignalStrengthThresholds(int[] thresholds) { 1417 } 1418 1419 /** 1420 * Called when the user asks to not stay connected to this network because it was found to not 1421 * provide Internet access. Usually followed by call to {@code unwanted}. The transport is 1422 * responsible for making sure the device does not automatically reconnect to the same network 1423 * after the {@code unwanted} call. 1424 */ onAutomaticReconnectDisabled()1425 public void onAutomaticReconnectDisabled() { 1426 preventAutomaticReconnect(); 1427 } 1428 /** @hide TODO delete once subclasses have moved to onAutomaticReconnectDisabled */ preventAutomaticReconnect()1429 protected void preventAutomaticReconnect() { 1430 } 1431 1432 /** 1433 * Called when a qos callback is registered with a filter. 1434 * @param qosCallbackId the id for the callback registered 1435 * @param filter the filter being registered 1436 */ onQosCallbackRegistered(final int qosCallbackId, final @NonNull QosFilter filter)1437 public void onQosCallbackRegistered(final int qosCallbackId, final @NonNull QosFilter filter) { 1438 } 1439 1440 /** 1441 * Called when a qos callback is registered with a filter. 1442 * <p/> 1443 * Any QoS events that are sent with the same callback id after this method is called 1444 * are a no-op. 1445 * 1446 * @param qosCallbackId the id for the callback being unregistered 1447 */ onQosCallbackUnregistered(final int qosCallbackId)1448 public void onQosCallbackUnregistered(final int qosCallbackId) { 1449 } 1450 1451 1452 /** 1453 * Sends the attributes of Qos Session back to the Application 1454 * 1455 * @param qosCallbackId the callback id that the session belongs to 1456 * @param sessionId the unique session id across all Qos Sessions 1457 * @param attributes the attributes of the Qos Session 1458 */ sendQosSessionAvailable(final int qosCallbackId, final int sessionId, @NonNull final QosSessionAttributes attributes)1459 public final void sendQosSessionAvailable(final int qosCallbackId, final int sessionId, 1460 @NonNull final QosSessionAttributes attributes) { 1461 Objects.requireNonNull(attributes, "The attributes must be non-null"); 1462 if (attributes instanceof EpsBearerQosSessionAttributes) { 1463 queueOrSendMessage(ra -> ra.sendEpsQosSessionAvailable(qosCallbackId, 1464 new QosSession(sessionId, QosSession.TYPE_EPS_BEARER), 1465 (EpsBearerQosSessionAttributes)attributes)); 1466 } else if (attributes instanceof NrQosSessionAttributes) { 1467 queueOrSendMessage(ra -> ra.sendNrQosSessionAvailable(qosCallbackId, 1468 new QosSession(sessionId, QosSession.TYPE_NR_BEARER), 1469 (NrQosSessionAttributes)attributes)); 1470 } 1471 } 1472 1473 /** 1474 * Sends event that the Qos Session was lost. 1475 * 1476 * @param qosCallbackId the callback id that the session belongs to 1477 * @param sessionId the unique session id across all Qos Sessions 1478 * @param qosSessionType the session type {@code QosSesson#QosSessionType} 1479 */ sendQosSessionLost(final int qosCallbackId, final int sessionId, final int qosSessionType)1480 public final void sendQosSessionLost(final int qosCallbackId, 1481 final int sessionId, final int qosSessionType) { 1482 queueOrSendMessage(ra -> ra.sendQosSessionLost(qosCallbackId, 1483 new QosSession(sessionId, qosSessionType))); 1484 } 1485 1486 /** 1487 * Sends the exception type back to the application. 1488 * 1489 * The NetworkAgent should not send anymore messages with this id. 1490 * 1491 * @param qosCallbackId the callback id this exception belongs to 1492 * @param exceptionType the type of exception 1493 */ sendQosCallbackError(final int qosCallbackId, @QosCallbackException.ExceptionType final int exceptionType)1494 public final void sendQosCallbackError(final int qosCallbackId, 1495 @QosCallbackException.ExceptionType final int exceptionType) { 1496 queueOrSendMessage(ra -> ra.sendQosCallbackError(qosCallbackId, exceptionType)); 1497 } 1498 1499 /** 1500 * Set the linger duration for this network agent. 1501 * @param duration the delay between the moment the network becomes unneeded and the 1502 * moment the network is disconnected or moved into the background. 1503 * Note that If this duration has greater than millisecond precision, then 1504 * the internal implementation will drop any excess precision. 1505 */ setLingerDuration(@onNull final Duration duration)1506 public void setLingerDuration(@NonNull final Duration duration) { 1507 Objects.requireNonNull(duration); 1508 final long durationMs = duration.toMillis(); 1509 if (durationMs < MIN_LINGER_TIMER_MS || durationMs > Integer.MAX_VALUE) { 1510 throw new IllegalArgumentException("Duration must be within [" 1511 + MIN_LINGER_TIMER_MS + "," + Integer.MAX_VALUE + "]ms"); 1512 } 1513 queueOrSendMessage(ra -> ra.sendLingerDuration((int) durationMs)); 1514 } 1515 1516 /** 1517 * Add a DSCP Policy. 1518 * @param policy the DSCP policy to be added. 1519 */ sendAddDscpPolicy(@onNull final DscpPolicy policy)1520 public void sendAddDscpPolicy(@NonNull final DscpPolicy policy) { 1521 Objects.requireNonNull(policy); 1522 queueOrSendMessage(ra -> ra.sendAddDscpPolicy(policy)); 1523 } 1524 1525 /** 1526 * Remove the specified DSCP policy. 1527 * @param policyId the ID corresponding to a specific DSCP Policy. 1528 */ sendRemoveDscpPolicy(final int policyId)1529 public void sendRemoveDscpPolicy(final int policyId) { 1530 queueOrSendMessage(ra -> ra.sendRemoveDscpPolicy(policyId)); 1531 } 1532 1533 /** 1534 * Remove all the DSCP policies on this network. 1535 */ sendRemoveAllDscpPolicies()1536 public void sendRemoveAllDscpPolicies() { 1537 queueOrSendMessage(ra -> ra.sendRemoveAllDscpPolicies()); 1538 } 1539 1540 /** @hide */ log(final String s)1541 protected void log(final String s) { 1542 Log.d(LOG_TAG, "NetworkAgent: " + s); 1543 } 1544 } 1545