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