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 com.android.server.connectivity; 18 19 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport; 20 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 21 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 22 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; 23 import static android.net.NetworkCapabilities.TRANSPORT_TEST; 24 import static android.net.NetworkCapabilities.transportNamesOf; 25 26 import android.annotation.NonNull; 27 import android.annotation.Nullable; 28 import android.content.Context; 29 import android.net.CaptivePortalData; 30 import android.net.DscpPolicy; 31 import android.net.IDnsResolver; 32 import android.net.INetd; 33 import android.net.INetworkAgent; 34 import android.net.INetworkAgentRegistry; 35 import android.net.INetworkMonitor; 36 import android.net.LinkProperties; 37 import android.net.NattKeepalivePacketData; 38 import android.net.Network; 39 import android.net.NetworkAgent; 40 import android.net.NetworkAgentConfig; 41 import android.net.NetworkCapabilities; 42 import android.net.NetworkInfo; 43 import android.net.NetworkMonitorManager; 44 import android.net.NetworkRequest; 45 import android.net.NetworkScore; 46 import android.net.NetworkStateSnapshot; 47 import android.net.QosCallbackException; 48 import android.net.QosFilter; 49 import android.net.QosFilterParcelable; 50 import android.net.QosSession; 51 import android.net.TcpKeepalivePacketData; 52 import android.os.Handler; 53 import android.os.IBinder; 54 import android.os.RemoteException; 55 import android.os.SystemClock; 56 import android.telephony.data.EpsBearerQosSessionAttributes; 57 import android.telephony.data.NrQosSessionAttributes; 58 import android.util.ArraySet; 59 import android.util.Log; 60 import android.util.Pair; 61 import android.util.SparseArray; 62 63 import com.android.internal.util.IndentingPrintWriter; 64 import com.android.internal.util.WakeupMessage; 65 import com.android.modules.utils.build.SdkLevel; 66 import com.android.server.ConnectivityService; 67 68 import java.io.PrintWriter; 69 import java.util.ArrayList; 70 import java.util.Arrays; 71 import java.util.List; 72 import java.util.NoSuchElementException; 73 import java.util.Objects; 74 import java.util.SortedSet; 75 import java.util.TreeSet; 76 77 /** 78 * A bag class used by ConnectivityService for holding a collection of most recent 79 * information published by a particular NetworkAgent as well as the 80 * AsyncChannel/messenger for reaching that NetworkAgent and lists of NetworkRequests 81 * interested in using it. Default sort order is descending by score. 82 */ 83 // States of a network: 84 // -------------------- 85 // 1. registered, uncreated, disconnected, unvalidated 86 // This state is entered when a NetworkFactory registers a NetworkAgent in any state except 87 // the CONNECTED state. 88 // 2. registered, uncreated, connecting, unvalidated 89 // This state is entered when a registered NetworkAgent for a VPN network transitions to the 90 // CONNECTING state (TODO: go through this state for every network, not just VPNs). 91 // ConnectivityService will tell netd to create the network early in order to add extra UID 92 // routing rules referencing the netID. These rules need to be in place before the network is 93 // connected to avoid racing against client apps trying to connect to a half-setup network. 94 // 3. registered, uncreated, connected, unvalidated 95 // This state is entered when a registered NetworkAgent transitions to the CONNECTED state. 96 // ConnectivityService will tell netd to create the network if it was not already created, and 97 // immediately transition to state #4. 98 // 4. registered, created, connected, unvalidated 99 // If this network can satisfy the default NetworkRequest, then NetworkMonitor will 100 // probe for Internet connectivity. 101 // If this network cannot satisfy the default NetworkRequest, it will immediately be 102 // transitioned to state #5. 103 // A network may remain in this state if NetworkMonitor fails to find Internet connectivity, 104 // for example: 105 // a. a captive portal is present, or 106 // b. a WiFi router whose Internet backhaul is down, or 107 // c. a wireless connection stops transfering packets temporarily (e.g. device is in elevator 108 // or tunnel) but does not disconnect from the AP/cell tower, or 109 // d. a stand-alone device offering a WiFi AP without an uplink for configuration purposes. 110 // 5. registered, created, connected, validated 111 // 6. registered, created, connected, (validated or unvalidated), destroyed 112 // This is an optional state where the underlying native network is destroyed but the network is 113 // still connected for scoring purposes, so can satisfy requests, including the default request. 114 // It is used when the transport layer wants to replace a network with another network (e.g., 115 // when Wi-Fi has roamed to a different BSSID that is part of a different L3 network) and does 116 // not want the device to switch to another network until the replacement connects and validates. 117 // 118 // The device's default network connection: 119 // ---------------------------------------- 120 // Networks in states #4 and #5 may be used as a device's default network connection if they 121 // satisfy the default NetworkRequest. 122 // A network, that satisfies the default NetworkRequest, in state #5 should always be chosen 123 // in favor of a network, that satisfies the default NetworkRequest, in state #4. 124 // When deciding between two networks, that both satisfy the default NetworkRequest, to select 125 // for the default network connection, the one with the higher score should be chosen. 126 // 127 // When a network disconnects: 128 // --------------------------- 129 // If a network's transport disappears, for example: 130 // a. WiFi turned off, or 131 // b. cellular data turned off, or 132 // c. airplane mode is turned on, or 133 // d. a wireless connection disconnects from AP/cell tower entirely (e.g. device is out of range 134 // of AP for an extended period of time, or switches to another AP without roaming) 135 // then that network can transition from any state (#1-#5) to unregistered. This happens by 136 // the transport disconnecting their NetworkAgent's AsyncChannel with ConnectivityManager. 137 // ConnectivityService also tells netd to destroy the network. 138 // 139 // When ConnectivityService disconnects a network: 140 // ----------------------------------------------- 141 // If a network is just connected, ConnectivityService will think it will be used soon, but might 142 // not be used. Thus, a 5s timer will be held to prevent the network being torn down immediately. 143 // This "nascent" state is implemented by the "lingering" logic below without relating to any 144 // request, and is used in some cases where network requests race with network establishment. The 145 // nascent state ends when the 5-second timer fires, or as soon as the network satisfies a 146 // request, whichever is earlier. In this state, the network is considered in the background. 147 // 148 // If a network has no chance of satisfying any requests (even if it were to become validated 149 // and enter state #5), ConnectivityService will disconnect the NetworkAgent's AsyncChannel. 150 // 151 // If the network was satisfying a foreground NetworkRequest (i.e. had been the highest scoring that 152 // satisfied the NetworkRequest's constraints), but is no longer the highest scoring network for any 153 // foreground NetworkRequest, then there will be a 30s pause to allow network communication to be 154 // wrapped up rather than abruptly terminated. During this pause the network is said to be 155 // "lingering". During this pause if the network begins satisfying a foreground NetworkRequest, 156 // ConnectivityService will cancel the future disconnection of the NetworkAgent's AsyncChannel, and 157 // the network is no longer considered "lingering". After the linger timer expires, if the network 158 // is satisfying one or more background NetworkRequests it is kept up in the background. If it is 159 // not, ConnectivityService disconnects the NetworkAgent's AsyncChannel. 160 public class NetworkAgentInfo implements Comparable<NetworkAgentInfo>, NetworkRanker.Scoreable { 161 162 @NonNull public NetworkInfo networkInfo; 163 // This Network object should always be used if possible, so as to encourage reuse of the 164 // enclosed socket factory and connection pool. Avoid creating other Network objects. 165 // This Network object is always valid. 166 @NonNull public final Network network; 167 @NonNull public LinkProperties linkProperties; 168 // This should only be modified by ConnectivityService, via setNetworkCapabilities(). 169 // TODO: make this private with a getter. 170 @NonNull public NetworkCapabilities networkCapabilities; 171 @NonNull public final NetworkAgentConfig networkAgentConfig; 172 173 // Underlying networks declared by the agent. 174 // The networks in this list might be declared by a VPN using setUnderlyingNetworks and are 175 // not guaranteed to be current or correct, or even to exist. 176 // 177 // This array is read and iterated on multiple threads with no locking so its contents must 178 // never be modified. When the list of networks changes, replace with a new array, on the 179 // handler thread. 180 public @Nullable volatile Network[] declaredUnderlyingNetworks; 181 182 // The capabilities originally announced by the NetworkAgent, regardless of any capabilities 183 // that were added or removed due to this network's underlying networks. 184 // Only set if #propagateUnderlyingCapabilities is true. 185 public @Nullable NetworkCapabilities declaredCapabilities; 186 187 // Indicates if netd has been told to create this Network. From this point on the appropriate 188 // routing rules are setup and routes are added so packets can begin flowing over the Network. 189 // This is a sticky bit; once set it is never cleared. 190 public boolean created; 191 // Set to true after the first time this network is marked as CONNECTED. Once set, the network 192 // shows up in API calls, is able to satisfy NetworkRequests and can become the default network. 193 // This is a sticky bit; once set it is never cleared. 194 public boolean everConnected; 195 // Whether this network has been destroyed and is being kept temporarily until it is replaced. 196 public boolean destroyed; 197 // To check how long it has been since last roam. 198 public long lastRoamTimestamp; 199 200 // Set to true if this Network successfully passed validation or if it did not satisfy the 201 // default NetworkRequest in which case validation will not be attempted. 202 // This is a sticky bit; once set it is never cleared even if future validation attempts fail. 203 public boolean everValidated; 204 205 // The result of the last validation attempt on this network (true if validated, false if not). 206 public boolean lastValidated; 207 208 // If true, becoming unvalidated will lower the network's score. This is only meaningful if the 209 // system is configured not to do this for certain networks, e.g., if the 210 // config_networkAvoidBadWifi option is set to 0 and the user has not overridden that via 211 // Settings.Global.NETWORK_AVOID_BAD_WIFI. 212 public boolean avoidUnvalidated; 213 214 // Whether a captive portal was ever detected on this network. 215 // This is a sticky bit; once set it is never cleared. 216 public boolean everCaptivePortalDetected; 217 218 // Whether a captive portal was found during the last network validation attempt. 219 public boolean lastCaptivePortalDetected; 220 221 // Set to true when partial connectivity was detected. 222 public boolean partialConnectivity; 223 224 // Delay between when the network is disconnected and when the native network is destroyed. 225 public int teardownDelayMs; 226 227 // Captive portal info of the network from RFC8908, if any. 228 // Obtained by ConnectivityService and merged into NetworkAgent-provided information. 229 public CaptivePortalData capportApiData; 230 231 // The UID of the remote entity that created this Network. 232 public final int creatorUid; 233 234 // Network agent portal info of the network, if any. This information is provided from 235 // non-RFC8908 sources, such as Wi-Fi Passpoint, which can provide information such as Venue 236 // URL, Terms & Conditions URL, and network friendly name. 237 public CaptivePortalData networkAgentPortalData; 238 239 // Networks are lingered when they become unneeded as a result of their NetworkRequests being 240 // satisfied by a higher-scoring network. so as to allow communication to wrap up before the 241 // network is taken down. This usually only happens to the default network. Lingering ends with 242 // either the linger timeout expiring and the network being taken down, or the network 243 // satisfying a request again. 244 public static class InactivityTimer implements Comparable<InactivityTimer> { 245 public final int requestId; 246 public final long expiryMs; 247 InactivityTimer(int requestId, long expiryMs)248 public InactivityTimer(int requestId, long expiryMs) { 249 this.requestId = requestId; 250 this.expiryMs = expiryMs; 251 } equals(Object o)252 public boolean equals(Object o) { 253 if (!(o instanceof InactivityTimer)) return false; 254 InactivityTimer other = (InactivityTimer) o; 255 return (requestId == other.requestId) && (expiryMs == other.expiryMs); 256 } hashCode()257 public int hashCode() { 258 return Objects.hash(requestId, expiryMs); 259 } compareTo(InactivityTimer other)260 public int compareTo(InactivityTimer other) { 261 return (expiryMs != other.expiryMs) ? 262 Long.compare(expiryMs, other.expiryMs) : 263 Integer.compare(requestId, other.requestId); 264 } toString()265 public String toString() { 266 return String.format("%s, expires %dms", requestId, 267 expiryMs - SystemClock.elapsedRealtime()); 268 } 269 } 270 271 /** 272 * Inform ConnectivityService that the network LINGER period has 273 * expired. 274 * obj = this NetworkAgentInfo 275 */ 276 public static final int EVENT_NETWORK_LINGER_COMPLETE = 1001; 277 278 /** 279 * Inform ConnectivityService that the agent is half-connected. 280 * arg1 = ARG_AGENT_SUCCESS or ARG_AGENT_FAILURE 281 * obj = NetworkAgentInfo 282 * @hide 283 */ 284 public static final int EVENT_AGENT_REGISTERED = 1002; 285 286 /** 287 * Inform ConnectivityService that the agent was disconnected. 288 * obj = NetworkAgentInfo 289 * @hide 290 */ 291 public static final int EVENT_AGENT_DISCONNECTED = 1003; 292 293 /** 294 * Argument for EVENT_AGENT_HALF_CONNECTED indicating failure. 295 */ 296 public static final int ARG_AGENT_FAILURE = 0; 297 298 /** 299 * Argument for EVENT_AGENT_HALF_CONNECTED indicating success. 300 */ 301 public static final int ARG_AGENT_SUCCESS = 1; 302 303 // How long this network should linger for. 304 private int mLingerDurationMs; 305 306 // All inactivity timers for this network, sorted by expiry time. A timer is added whenever 307 // a request is moved to a network with a better score, regardless of whether the network is or 308 // was lingering or not. An inactivity timer is also added when a network connects 309 // without immediately satisfying any requests. 310 // TODO: determine if we can replace this with a smaller or unsorted data structure. (e.g., 311 // SparseLongArray) combined with the timestamp of when the last timer is scheduled to fire. 312 private final SortedSet<InactivityTimer> mInactivityTimers = new TreeSet<>(); 313 314 // For fast lookups. Indexes into mInactivityTimers by request ID. 315 private final SparseArray<InactivityTimer> mInactivityTimerForRequest = new SparseArray<>(); 316 317 // Inactivity expiry timer. Armed whenever mInactivityTimers is non-empty, regardless of 318 // whether the network is inactive or not. Always set to the expiry of the mInactivityTimers 319 // that expires last. When the timer fires, all inactivity state is cleared, and if the network 320 // has no requests, it is torn down. 321 private WakeupMessage mInactivityMessage; 322 323 // Inactivity expiry. Holds the expiry time of the inactivity timer, or 0 if the timer is not 324 // armed. 325 private long mInactivityExpiryMs; 326 327 // Whether the network is inactive or not. Must be maintained separately from the above because 328 // it depends on the state of other networks and requests, which only ConnectivityService knows. 329 // (Example: we don't linger a network if it would become the best for a NetworkRequest if it 330 // validated). 331 private boolean mInactive; 332 333 // This represents the quality of the network. As opposed to NetworkScore, FullScore includes 334 // the ConnectivityService-managed bits. 335 private FullScore mScore; 336 337 // The list of NetworkRequests being satisfied by this Network. 338 private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>(); 339 340 // How many of the satisfied requests are actual requests and not listens. 341 private int mNumRequestNetworkRequests = 0; 342 343 // How many of the satisfied requests are of type BACKGROUND_REQUEST. 344 private int mNumBackgroundNetworkRequests = 0; 345 346 // The last ConnectivityReport made available for this network. This value is only null before a 347 // report is generated. Once non-null, it will never be null again. 348 @Nullable private ConnectivityReport mConnectivityReport; 349 350 public final INetworkAgent networkAgent; 351 // Only accessed from ConnectivityService handler thread 352 private final AgentDeathMonitor mDeathMonitor = new AgentDeathMonitor(); 353 354 public final int factorySerialNumber; 355 356 // Used by ConnectivityService to keep track of 464xlat. 357 public final Nat464Xlat clatd; 358 359 // Set after asynchronous creation of the NetworkMonitor. 360 private volatile NetworkMonitorManager mNetworkMonitor; 361 362 private static final String TAG = ConnectivityService.class.getSimpleName(); 363 private static final boolean VDBG = false; 364 private final ConnectivityService mConnService; 365 private final Context mContext; 366 private final Handler mHandler; 367 private final QosCallbackTracker mQosCallbackTracker; 368 NetworkAgentInfo(INetworkAgent na, Network net, NetworkInfo info, @NonNull LinkProperties lp, @NonNull NetworkCapabilities nc, @NonNull NetworkScore score, Context context, Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd, IDnsResolver dnsResolver, int factorySerialNumber, int creatorUid, int lingerDurationMs, QosCallbackTracker qosCallbackTracker, ConnectivityService.Dependencies deps)369 public NetworkAgentInfo(INetworkAgent na, Network net, NetworkInfo info, 370 @NonNull LinkProperties lp, @NonNull NetworkCapabilities nc, 371 @NonNull NetworkScore score, Context context, 372 Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd, 373 IDnsResolver dnsResolver, int factorySerialNumber, int creatorUid, 374 int lingerDurationMs, QosCallbackTracker qosCallbackTracker, 375 ConnectivityService.Dependencies deps) { 376 Objects.requireNonNull(net); 377 Objects.requireNonNull(info); 378 Objects.requireNonNull(lp); 379 Objects.requireNonNull(nc); 380 Objects.requireNonNull(context); 381 Objects.requireNonNull(config); 382 Objects.requireNonNull(qosCallbackTracker); 383 networkAgent = na; 384 network = net; 385 networkInfo = info; 386 linkProperties = lp; 387 networkCapabilities = nc; 388 networkAgentConfig = config; 389 mConnService = connService; 390 setScore(score); // uses members connService, networkCapabilities and networkAgentConfig 391 clatd = new Nat464Xlat(this, netd, dnsResolver, deps); 392 mContext = context; 393 mHandler = handler; 394 this.factorySerialNumber = factorySerialNumber; 395 this.creatorUid = creatorUid; 396 mLingerDurationMs = lingerDurationMs; 397 mQosCallbackTracker = qosCallbackTracker; 398 declaredUnderlyingNetworks = (nc.getUnderlyingNetworks() != null) 399 ? nc.getUnderlyingNetworks().toArray(new Network[0]) 400 : null; 401 } 402 403 private class AgentDeathMonitor implements IBinder.DeathRecipient { 404 @Override binderDied()405 public void binderDied() { 406 notifyDisconnected(); 407 } 408 } 409 410 /** 411 * Notify the NetworkAgent that it was registered, and should be unregistered if it dies. 412 * 413 * Must be called from the ConnectivityService handler thread. A NetworkAgent can only be 414 * registered once. 415 */ notifyRegistered()416 public void notifyRegistered() { 417 try { 418 networkAgent.asBinder().linkToDeath(mDeathMonitor, 0); 419 networkAgent.onRegistered(new NetworkAgentMessageHandler(mHandler)); 420 } catch (RemoteException e) { 421 Log.e(TAG, "Error registering NetworkAgent", e); 422 maybeUnlinkDeathMonitor(); 423 mHandler.obtainMessage(EVENT_AGENT_REGISTERED, ARG_AGENT_FAILURE, 0, this) 424 .sendToTarget(); 425 return; 426 } 427 428 mHandler.obtainMessage(EVENT_AGENT_REGISTERED, ARG_AGENT_SUCCESS, 0, this).sendToTarget(); 429 } 430 431 /** 432 * Disconnect the NetworkAgent. Must be called from the ConnectivityService handler thread. 433 */ disconnect()434 public void disconnect() { 435 try { 436 networkAgent.onDisconnected(); 437 } catch (RemoteException e) { 438 Log.i(TAG, "Error disconnecting NetworkAgent", e); 439 // Fall through: it's fine if the remote has died 440 } 441 442 notifyDisconnected(); 443 maybeUnlinkDeathMonitor(); 444 } 445 maybeUnlinkDeathMonitor()446 private void maybeUnlinkDeathMonitor() { 447 try { 448 networkAgent.asBinder().unlinkToDeath(mDeathMonitor, 0); 449 } catch (NoSuchElementException e) { 450 // Was not linked: ignore 451 } 452 } 453 notifyDisconnected()454 private void notifyDisconnected() { 455 // Note this may be called multiple times if ConnectivityService disconnects while the 456 // NetworkAgent also dies. ConnectivityService ignores disconnects of already disconnected 457 // agents. 458 mHandler.obtainMessage(EVENT_AGENT_DISCONNECTED, this).sendToTarget(); 459 } 460 461 /** 462 * Notify the NetworkAgent that bandwidth update was requested. 463 */ onBandwidthUpdateRequested()464 public void onBandwidthUpdateRequested() { 465 try { 466 networkAgent.onBandwidthUpdateRequested(); 467 } catch (RemoteException e) { 468 Log.e(TAG, "Error sending bandwidth update request event", e); 469 } 470 } 471 472 /** 473 * Notify the NetworkAgent that validation status has changed. 474 */ onValidationStatusChanged(int validationStatus, @Nullable String captivePortalUrl)475 public void onValidationStatusChanged(int validationStatus, @Nullable String captivePortalUrl) { 476 try { 477 networkAgent.onValidationStatusChanged(validationStatus, captivePortalUrl); 478 } catch (RemoteException e) { 479 Log.e(TAG, "Error sending validation status change event", e); 480 } 481 } 482 483 /** 484 * Notify the NetworkAgent that the acceptUnvalidated setting should be saved. 485 */ onSaveAcceptUnvalidated(boolean acceptUnvalidated)486 public void onSaveAcceptUnvalidated(boolean acceptUnvalidated) { 487 try { 488 networkAgent.onSaveAcceptUnvalidated(acceptUnvalidated); 489 } catch (RemoteException e) { 490 Log.e(TAG, "Error sending accept unvalidated event", e); 491 } 492 } 493 494 /** 495 * Notify the NetworkAgent that NATT socket keepalive should be started. 496 */ onStartNattSocketKeepalive(int slot, int intervalDurationMs, @NonNull NattKeepalivePacketData packetData)497 public void onStartNattSocketKeepalive(int slot, int intervalDurationMs, 498 @NonNull NattKeepalivePacketData packetData) { 499 try { 500 networkAgent.onStartNattSocketKeepalive(slot, intervalDurationMs, packetData); 501 } catch (RemoteException e) { 502 Log.e(TAG, "Error sending NATT socket keepalive start event", e); 503 } 504 } 505 506 /** 507 * Notify the NetworkAgent that TCP socket keepalive should be started. 508 */ onStartTcpSocketKeepalive(int slot, int intervalDurationMs, @NonNull TcpKeepalivePacketData packetData)509 public void onStartTcpSocketKeepalive(int slot, int intervalDurationMs, 510 @NonNull TcpKeepalivePacketData packetData) { 511 try { 512 networkAgent.onStartTcpSocketKeepalive(slot, intervalDurationMs, packetData); 513 } catch (RemoteException e) { 514 Log.e(TAG, "Error sending TCP socket keepalive start event", e); 515 } 516 } 517 518 /** 519 * Notify the NetworkAgent that socket keepalive should be stopped. 520 */ onStopSocketKeepalive(int slot)521 public void onStopSocketKeepalive(int slot) { 522 try { 523 networkAgent.onStopSocketKeepalive(slot); 524 } catch (RemoteException e) { 525 Log.e(TAG, "Error sending TCP socket keepalive stop event", e); 526 } 527 } 528 529 /** 530 * Notify the NetworkAgent that signal strength thresholds should be updated. 531 */ onSignalStrengthThresholdsUpdated(@onNull int[] thresholds)532 public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) { 533 try { 534 networkAgent.onSignalStrengthThresholdsUpdated(thresholds); 535 } catch (RemoteException e) { 536 Log.e(TAG, "Error sending signal strength thresholds event", e); 537 } 538 } 539 540 /** 541 * Notify the NetworkAgent that automatic reconnect should be prevented. 542 */ onPreventAutomaticReconnect()543 public void onPreventAutomaticReconnect() { 544 try { 545 networkAgent.onPreventAutomaticReconnect(); 546 } catch (RemoteException e) { 547 Log.e(TAG, "Error sending prevent automatic reconnect event", e); 548 } 549 } 550 551 /** 552 * Notify the NetworkAgent that a NATT keepalive packet filter should be added. 553 */ onAddNattKeepalivePacketFilter(int slot, @NonNull NattKeepalivePacketData packetData)554 public void onAddNattKeepalivePacketFilter(int slot, 555 @NonNull NattKeepalivePacketData packetData) { 556 try { 557 networkAgent.onAddNattKeepalivePacketFilter(slot, packetData); 558 } catch (RemoteException e) { 559 Log.e(TAG, "Error sending add NATT keepalive packet filter event", e); 560 } 561 } 562 563 /** 564 * Notify the NetworkAgent that a TCP keepalive packet filter should be added. 565 */ onAddTcpKeepalivePacketFilter(int slot, @NonNull TcpKeepalivePacketData packetData)566 public void onAddTcpKeepalivePacketFilter(int slot, 567 @NonNull TcpKeepalivePacketData packetData) { 568 try { 569 networkAgent.onAddTcpKeepalivePacketFilter(slot, packetData); 570 } catch (RemoteException e) { 571 Log.e(TAG, "Error sending add TCP keepalive packet filter event", e); 572 } 573 } 574 575 /** 576 * Notify the NetworkAgent that a keepalive packet filter should be removed. 577 */ onRemoveKeepalivePacketFilter(int slot)578 public void onRemoveKeepalivePacketFilter(int slot) { 579 try { 580 networkAgent.onRemoveKeepalivePacketFilter(slot); 581 } catch (RemoteException e) { 582 Log.e(TAG, "Error sending remove keepalive packet filter event", e); 583 } 584 } 585 586 /** 587 * Notify the NetworkAgent that the qos filter should be registered against the given qos 588 * callback id. 589 */ onQosFilterCallbackRegistered(final int qosCallbackId, final QosFilter qosFilter)590 public void onQosFilterCallbackRegistered(final int qosCallbackId, 591 final QosFilter qosFilter) { 592 try { 593 networkAgent.onQosFilterCallbackRegistered(qosCallbackId, 594 new QosFilterParcelable(qosFilter)); 595 } catch (final RemoteException e) { 596 Log.e(TAG, "Error registering a qos callback id against a qos filter", e); 597 } 598 } 599 600 /** 601 * Notify the NetworkAgent that the given qos callback id should be unregistered. 602 */ onQosCallbackUnregistered(final int qosCallbackId)603 public void onQosCallbackUnregistered(final int qosCallbackId) { 604 try { 605 networkAgent.onQosCallbackUnregistered(qosCallbackId); 606 } catch (RemoteException e) { 607 Log.e(TAG, "Error unregistering a qos callback id", e); 608 } 609 } 610 611 /** 612 * Notify the NetworkAgent that the network is successfully connected. 613 */ onNetworkCreated()614 public void onNetworkCreated() { 615 try { 616 networkAgent.onNetworkCreated(); 617 } catch (RemoteException e) { 618 Log.e(TAG, "Error sending network created event", e); 619 } 620 } 621 622 /** 623 * Notify the NetworkAgent that the native network has been destroyed. 624 */ onNetworkDestroyed()625 public void onNetworkDestroyed() { 626 try { 627 networkAgent.onNetworkDestroyed(); 628 } catch (RemoteException e) { 629 Log.e(TAG, "Error sending network destroyed event", e); 630 } 631 } 632 633 // TODO: consider moving out of NetworkAgentInfo into its own class 634 private class NetworkAgentMessageHandler extends INetworkAgentRegistry.Stub { 635 private final Handler mHandler; 636 NetworkAgentMessageHandler(Handler handler)637 private NetworkAgentMessageHandler(Handler handler) { 638 mHandler = handler; 639 } 640 641 @Override sendNetworkCapabilities(@onNull NetworkCapabilities nc)642 public void sendNetworkCapabilities(@NonNull NetworkCapabilities nc) { 643 Objects.requireNonNull(nc); 644 mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED, 645 new Pair<>(NetworkAgentInfo.this, nc)).sendToTarget(); 646 } 647 648 @Override sendLinkProperties(@onNull LinkProperties lp)649 public void sendLinkProperties(@NonNull LinkProperties lp) { 650 Objects.requireNonNull(lp); 651 mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED, 652 new Pair<>(NetworkAgentInfo.this, lp)).sendToTarget(); 653 } 654 655 @Override sendNetworkInfo(@onNull NetworkInfo info)656 public void sendNetworkInfo(@NonNull NetworkInfo info) { 657 Objects.requireNonNull(info); 658 mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_INFO_CHANGED, 659 new Pair<>(NetworkAgentInfo.this, info)).sendToTarget(); 660 } 661 662 @Override sendScore(@onNull final NetworkScore score)663 public void sendScore(@NonNull final NetworkScore score) { 664 mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_SCORE_CHANGED, 665 new Pair<>(NetworkAgentInfo.this, score)).sendToTarget(); 666 } 667 668 @Override sendExplicitlySelected(boolean explicitlySelected, boolean acceptPartial)669 public void sendExplicitlySelected(boolean explicitlySelected, boolean acceptPartial) { 670 mHandler.obtainMessage(NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED, 671 explicitlySelected ? 1 : 0, acceptPartial ? 1 : 0, 672 new Pair<>(NetworkAgentInfo.this, null)).sendToTarget(); 673 } 674 675 @Override sendSocketKeepaliveEvent(int slot, int reason)676 public void sendSocketKeepaliveEvent(int slot, int reason) { 677 mHandler.obtainMessage(NetworkAgent.EVENT_SOCKET_KEEPALIVE, 678 slot, reason, new Pair<>(NetworkAgentInfo.this, null)).sendToTarget(); 679 } 680 681 @Override sendUnderlyingNetworks(@ullable List<Network> networks)682 public void sendUnderlyingNetworks(@Nullable List<Network> networks) { 683 mHandler.obtainMessage(NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED, 684 new Pair<>(NetworkAgentInfo.this, networks)).sendToTarget(); 685 } 686 687 @Override sendEpsQosSessionAvailable(final int qosCallbackId, final QosSession session, final EpsBearerQosSessionAttributes attributes)688 public void sendEpsQosSessionAvailable(final int qosCallbackId, final QosSession session, 689 final EpsBearerQosSessionAttributes attributes) { 690 mQosCallbackTracker.sendEventEpsQosSessionAvailable(qosCallbackId, session, attributes); 691 } 692 693 @Override sendNrQosSessionAvailable(final int qosCallbackId, final QosSession session, final NrQosSessionAttributes attributes)694 public void sendNrQosSessionAvailable(final int qosCallbackId, final QosSession session, 695 final NrQosSessionAttributes attributes) { 696 mQosCallbackTracker.sendEventNrQosSessionAvailable(qosCallbackId, session, attributes); 697 } 698 699 @Override sendQosSessionLost(final int qosCallbackId, final QosSession session)700 public void sendQosSessionLost(final int qosCallbackId, final QosSession session) { 701 mQosCallbackTracker.sendEventQosSessionLost(qosCallbackId, session); 702 } 703 704 @Override sendQosCallbackError(final int qosCallbackId, @QosCallbackException.ExceptionType final int exceptionType)705 public void sendQosCallbackError(final int qosCallbackId, 706 @QosCallbackException.ExceptionType final int exceptionType) { 707 mQosCallbackTracker.sendEventQosCallbackError(qosCallbackId, exceptionType); 708 } 709 710 @Override sendTeardownDelayMs(int teardownDelayMs)711 public void sendTeardownDelayMs(int teardownDelayMs) { 712 mHandler.obtainMessage(NetworkAgent.EVENT_TEARDOWN_DELAY_CHANGED, 713 teardownDelayMs, 0, new Pair<>(NetworkAgentInfo.this, null)).sendToTarget(); 714 } 715 716 @Override sendLingerDuration(final int durationMs)717 public void sendLingerDuration(final int durationMs) { 718 mHandler.obtainMessage(NetworkAgent.EVENT_LINGER_DURATION_CHANGED, 719 new Pair<>(NetworkAgentInfo.this, durationMs)).sendToTarget(); 720 } 721 722 @Override sendAddDscpPolicy(final DscpPolicy policy)723 public void sendAddDscpPolicy(final DscpPolicy policy) { 724 mHandler.obtainMessage(NetworkAgent.EVENT_ADD_DSCP_POLICY, 725 new Pair<>(NetworkAgentInfo.this, policy)).sendToTarget(); 726 } 727 728 @Override sendRemoveDscpPolicy(final int policyId)729 public void sendRemoveDscpPolicy(final int policyId) { 730 mHandler.obtainMessage(NetworkAgent.EVENT_REMOVE_DSCP_POLICY, 731 new Pair<>(NetworkAgentInfo.this, policyId)).sendToTarget(); 732 } 733 734 @Override sendRemoveAllDscpPolicies()735 public void sendRemoveAllDscpPolicies() { 736 mHandler.obtainMessage(NetworkAgent.EVENT_REMOVE_ALL_DSCP_POLICIES, 737 new Pair<>(NetworkAgentInfo.this, null)).sendToTarget(); 738 } 739 740 @Override sendUnregisterAfterReplacement(final int timeoutMillis)741 public void sendUnregisterAfterReplacement(final int timeoutMillis) { 742 mHandler.obtainMessage(NetworkAgent.EVENT_UNREGISTER_AFTER_REPLACEMENT, 743 new Pair<>(NetworkAgentInfo.this, timeoutMillis)).sendToTarget(); 744 } 745 } 746 747 /** 748 * Inform NetworkAgentInfo that a new NetworkMonitor was created. 749 */ onNetworkMonitorCreated(INetworkMonitor networkMonitor)750 public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) { 751 mNetworkMonitor = new NetworkMonitorManager(networkMonitor); 752 } 753 754 /** 755 * Set the NetworkCapabilities on this NetworkAgentInfo. Also attempts to notify NetworkMonitor 756 * of the new capabilities, if NetworkMonitor has been created. 757 * 758 * <p>If {@link NetworkMonitor#notifyNetworkCapabilitiesChanged(NetworkCapabilities)} fails, 759 * the exception is logged but not reported to callers. 760 * 761 * @return the old capabilities of this network. 762 */ getAndSetNetworkCapabilities( @onNull final NetworkCapabilities nc)763 @NonNull public synchronized NetworkCapabilities getAndSetNetworkCapabilities( 764 @NonNull final NetworkCapabilities nc) { 765 final NetworkCapabilities oldNc = networkCapabilities; 766 networkCapabilities = nc; 767 mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig, everValidatedForYield(), 768 yieldToBadWiFi(), destroyed); 769 final NetworkMonitorManager nm = mNetworkMonitor; 770 if (nm != null) { 771 nm.notifyNetworkCapabilitiesChanged(nc); 772 } 773 return oldNc; 774 } 775 yieldToBadWiFi()776 private boolean yieldToBadWiFi() { 777 // Only cellular networks yield to bad wifi 778 return networkCapabilities.hasTransport(TRANSPORT_CELLULAR) && !mConnService.avoidBadWifi(); 779 } 780 connService()781 public ConnectivityService connService() { 782 return mConnService; 783 } 784 netAgentConfig()785 public NetworkAgentConfig netAgentConfig() { 786 return networkAgentConfig; 787 } 788 handler()789 public Handler handler() { 790 return mHandler; 791 } 792 network()793 public Network network() { 794 return network; 795 } 796 797 /** 798 * Get the NetworkMonitorManager in this NetworkAgentInfo. 799 * 800 * <p>This will be null before {@link #onNetworkMonitorCreated(INetworkMonitor)} is called. 801 */ networkMonitor()802 public NetworkMonitorManager networkMonitor() { 803 return mNetworkMonitor; 804 } 805 806 // Functions for manipulating the requests satisfied by this network. 807 // 808 // These functions must only called on ConnectivityService's main thread. 809 810 private static final boolean ADD = true; 811 private static final boolean REMOVE = false; 812 updateRequestCounts(boolean add, NetworkRequest request)813 private void updateRequestCounts(boolean add, NetworkRequest request) { 814 int delta = add ? +1 : -1; 815 switch (request.type) { 816 case REQUEST: 817 mNumRequestNetworkRequests += delta; 818 break; 819 820 case BACKGROUND_REQUEST: 821 mNumRequestNetworkRequests += delta; 822 mNumBackgroundNetworkRequests += delta; 823 break; 824 825 case LISTEN: 826 case LISTEN_FOR_BEST: 827 case TRACK_DEFAULT: 828 case TRACK_SYSTEM_DEFAULT: 829 break; 830 831 case NONE: 832 default: 833 Log.wtf(TAG, "Unhandled request type " + request.type); 834 break; 835 } 836 } 837 838 /** 839 * Add {@code networkRequest} to this network as it's satisfied by this network. 840 * @return true if {@code networkRequest} was added or false if {@code networkRequest} was 841 * already present. 842 */ addRequest(NetworkRequest networkRequest)843 public boolean addRequest(NetworkRequest networkRequest) { 844 NetworkRequest existing = mNetworkRequests.get(networkRequest.requestId); 845 if (existing == networkRequest) return false; 846 if (existing != null) { 847 // Should only happen if the requestId wraps. If that happens lots of other things will 848 // be broken as well. 849 Log.wtf(TAG, String.format("Duplicate requestId for %s and %s on %s", 850 networkRequest, existing, toShortString())); 851 updateRequestCounts(REMOVE, existing); 852 } 853 mNetworkRequests.put(networkRequest.requestId, networkRequest); 854 updateRequestCounts(ADD, networkRequest); 855 return true; 856 } 857 858 /** 859 * Remove the specified request from this network. 860 */ removeRequest(int requestId)861 public void removeRequest(int requestId) { 862 NetworkRequest existing = mNetworkRequests.get(requestId); 863 if (existing == null) return; 864 updateRequestCounts(REMOVE, existing); 865 mNetworkRequests.remove(requestId); 866 if (existing.isRequest()) { 867 unlingerRequest(existing.requestId); 868 } 869 } 870 871 /** 872 * Returns whether this network is currently satisfying the request with the specified ID. 873 */ isSatisfyingRequest(int id)874 public boolean isSatisfyingRequest(int id) { 875 return mNetworkRequests.get(id) != null; 876 } 877 878 /** 879 * Returns the request at the specified position in the list of requests satisfied by this 880 * network. 881 */ requestAt(int index)882 public NetworkRequest requestAt(int index) { 883 return mNetworkRequests.valueAt(index); 884 } 885 886 /** 887 * Returns the number of requests currently satisfied by this network for which 888 * {@link android.net.NetworkRequest#isRequest} returns {@code true}. 889 */ numRequestNetworkRequests()890 public int numRequestNetworkRequests() { 891 return mNumRequestNetworkRequests; 892 } 893 894 /** 895 * Returns the number of requests currently satisfied by this network of type 896 * {@link android.net.NetworkRequest.Type#BACKGROUND_REQUEST}. 897 */ numBackgroundNetworkRequests()898 public int numBackgroundNetworkRequests() { 899 return mNumBackgroundNetworkRequests; 900 } 901 902 /** 903 * Returns the number of foreground requests currently satisfied by this network. 904 */ numForegroundNetworkRequests()905 public int numForegroundNetworkRequests() { 906 return mNumRequestNetworkRequests - mNumBackgroundNetworkRequests; 907 } 908 909 /** 910 * Returns the number of requests of any type currently satisfied by this network. 911 */ numNetworkRequests()912 public int numNetworkRequests() { 913 return mNetworkRequests.size(); 914 } 915 916 /** 917 * Returns whether the network is a background network. A network is a background network if it 918 * does not have the NET_CAPABILITY_FOREGROUND capability, which implies it is satisfying no 919 * foreground request, is not lingering (i.e. kept for a while after being outscored), and is 920 * not a speculative network (i.e. kept pending validation when validation would have it 921 * outscore another foreground network). That implies it is being kept up by some background 922 * request (otherwise it would be torn down), maybe the mobile always-on request. 923 */ isBackgroundNetwork()924 public boolean isBackgroundNetwork() { 925 return !isVPN() && numForegroundNetworkRequests() == 0 && mNumBackgroundNetworkRequests > 0 926 && !isLingering(); 927 } 928 929 // Does this network satisfy request? satisfies(NetworkRequest request)930 public boolean satisfies(NetworkRequest request) { 931 return created && 932 request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities); 933 } 934 satisfiesImmutableCapabilitiesOf(NetworkRequest request)935 public boolean satisfiesImmutableCapabilitiesOf(NetworkRequest request) { 936 return created && 937 request.networkCapabilities.satisfiedByImmutableNetworkCapabilities( 938 networkCapabilities); 939 } 940 941 /** Whether this network is a VPN. */ isVPN()942 public boolean isVPN() { 943 return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN); 944 } 945 946 /** 947 * Whether this network should propagate the capabilities from its underlying networks. 948 * Currently only true for VPNs. 949 */ propagateUnderlyingCapabilities()950 public boolean propagateUnderlyingCapabilities() { 951 return isVPN(); 952 } 953 954 // Caller must not mutate. This method is called frequently and making a defensive copy 955 // would be too expensive. This is used by NetworkRanker.Scoreable, so it can be compared 956 // against other scoreables. getCapsNoCopy()957 @Override public NetworkCapabilities getCapsNoCopy() { 958 return networkCapabilities; 959 } 960 961 // NetworkRanker.Scoreable getScore()962 @Override public FullScore getScore() { 963 return mScore; 964 } 965 966 // Get the current score for this Network. This may be modified from what the 967 // NetworkAgent sent, as it has modifiers applied to it. getCurrentScore()968 public int getCurrentScore() { 969 return mScore.getLegacyInt(); 970 } 971 972 // Get the current score for this Network as if it was validated. This may be modified from 973 // what the NetworkAgent sent, as it has modifiers applied to it. getCurrentScoreAsValidated()974 public int getCurrentScoreAsValidated() { 975 return mScore.getLegacyIntAsValidated(); 976 } 977 978 /** 979 * Mix-in the ConnectivityService-managed bits in the score. 980 */ setScore(final NetworkScore score)981 public void setScore(final NetworkScore score) { 982 mScore = FullScore.fromNetworkScore(score, networkCapabilities, networkAgentConfig, 983 everValidatedForYield(), yieldToBadWiFi(), destroyed); 984 } 985 986 /** 987 * Update the ConnectivityService-managed bits in the score. 988 * 989 * Call this after changing any data that might affect the score (e.g., agent config). 990 */ updateScoreForNetworkAgentUpdate()991 public void updateScoreForNetworkAgentUpdate() { 992 mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig, 993 everValidatedForYield(), yieldToBadWiFi(), destroyed); 994 } 995 everValidatedForYield()996 private boolean everValidatedForYield() { 997 return everValidated && !avoidUnvalidated; 998 } 999 1000 /** 1001 * Returns a Scoreable identical to this NAI, but validated. 1002 * 1003 * This is useful to probe what scoring would be if this network validated, to know 1004 * whether to provisionally keep a network that may or may not validate. 1005 * 1006 * @return a Scoreable identical to this NAI, but validated. 1007 */ getValidatedScoreable()1008 public NetworkRanker.Scoreable getValidatedScoreable() { 1009 return new NetworkRanker.Scoreable() { 1010 @Override public FullScore getScore() { 1011 return mScore.asValidated(); 1012 } 1013 1014 @Override public NetworkCapabilities getCapsNoCopy() { 1015 return networkCapabilities; 1016 } 1017 }; 1018 } 1019 1020 /** 1021 * Return a {@link NetworkStateSnapshot} for this network. 1022 */ 1023 @NonNull 1024 public NetworkStateSnapshot getNetworkStateSnapshot() { 1025 synchronized (this) { 1026 // Network objects are outwardly immutable so there is no point in duplicating. 1027 // Duplicating also precludes sharing socket factories and connection pools. 1028 final String subscriberId = (networkAgentConfig != null) 1029 ? networkAgentConfig.subscriberId : null; 1030 return new NetworkStateSnapshot(network, new NetworkCapabilities(networkCapabilities), 1031 new LinkProperties(linkProperties), subscriberId, networkInfo.getType()); 1032 } 1033 } 1034 1035 /** 1036 * Sets the specified requestId to linger on this network for the specified time. Called by 1037 * ConnectivityService when any request is moved to another network with a higher score, or 1038 * when a network is newly created. 1039 * 1040 * @param requestId The requestId of the request that no longer need to be served by this 1041 * network. Or {@link NetworkRequest#REQUEST_ID_NONE} if this is the 1042 * {@code InactivityTimer} for a newly created network. 1043 */ 1044 // TODO: Consider creating a dedicated function for nascent network, e.g. start/stopNascent. 1045 public void lingerRequest(int requestId, long now, long duration) { 1046 if (mInactivityTimerForRequest.get(requestId) != null) { 1047 // Cannot happen. Once a request is lingering on a particular network, we cannot 1048 // re-linger it unless that network becomes the best for that request again, in which 1049 // case we should have unlingered it. 1050 Log.wtf(TAG, toShortString() + ": request " + requestId + " already lingered"); 1051 } 1052 final long expiryMs = now + duration; 1053 InactivityTimer timer = new InactivityTimer(requestId, expiryMs); 1054 if (VDBG) Log.d(TAG, "Adding InactivityTimer " + timer + " to " + toShortString()); 1055 mInactivityTimers.add(timer); 1056 mInactivityTimerForRequest.put(requestId, timer); 1057 } 1058 1059 /** 1060 * Sets the specified requestId to linger on this network for the timeout set when 1061 * initializing or modified by {@link #setLingerDuration(int)}. Called by 1062 * ConnectivityService when any request is moved to another network with a higher score. 1063 * 1064 * @param requestId The requestId of the request that no longer need to be served by this 1065 * network. 1066 * @param now current system timestamp obtained by {@code SystemClock.elapsedRealtime}. 1067 */ 1068 public void lingerRequest(int requestId, long now) { 1069 lingerRequest(requestId, now, mLingerDurationMs); 1070 } 1071 1072 /** 1073 * Cancel lingering. Called by ConnectivityService when a request is added to this network. 1074 * Returns true if the given requestId was lingering on this network, false otherwise. 1075 */ 1076 public boolean unlingerRequest(int requestId) { 1077 InactivityTimer timer = mInactivityTimerForRequest.get(requestId); 1078 if (timer != null) { 1079 if (VDBG) { 1080 Log.d(TAG, "Removing InactivityTimer " + timer + " from " + toShortString()); 1081 } 1082 mInactivityTimers.remove(timer); 1083 mInactivityTimerForRequest.remove(requestId); 1084 return true; 1085 } 1086 return false; 1087 } 1088 1089 public long getInactivityExpiry() { 1090 return mInactivityExpiryMs; 1091 } 1092 1093 public void updateInactivityTimer() { 1094 long newExpiry = mInactivityTimers.isEmpty() ? 0 : mInactivityTimers.last().expiryMs; 1095 if (newExpiry == mInactivityExpiryMs) return; 1096 1097 // Even if we're going to reschedule the timer, cancel it first. This is because the 1098 // semantics of WakeupMessage guarantee that if cancel is called then the alarm will 1099 // never call its callback (handleLingerComplete), even if it has already fired. 1100 // WakeupMessage makes no such guarantees about rescheduling a message, so if mLingerMessage 1101 // has already been dispatched, rescheduling to some time in the future won't stop it 1102 // from calling its callback immediately. 1103 if (mInactivityMessage != null) { 1104 mInactivityMessage.cancel(); 1105 mInactivityMessage = null; 1106 } 1107 1108 if (newExpiry > 0) { 1109 // If the newExpiry timestamp is in the past, the wakeup message will fire immediately. 1110 mInactivityMessage = new WakeupMessage( 1111 mContext, mHandler, 1112 "NETWORK_LINGER_COMPLETE." + network.getNetId() /* cmdName */, 1113 EVENT_NETWORK_LINGER_COMPLETE /* cmd */, 1114 0 /* arg1 (unused) */, 0 /* arg2 (unused) */, 1115 this /* obj (NetworkAgentInfo) */); 1116 mInactivityMessage.schedule(newExpiry); 1117 } 1118 1119 mInactivityExpiryMs = newExpiry; 1120 } 1121 1122 public void setInactive() { 1123 mInactive = true; 1124 } 1125 1126 public void unsetInactive() { 1127 mInactive = false; 1128 } 1129 1130 public boolean isInactive() { 1131 return mInactive; 1132 } 1133 1134 public boolean isLingering() { 1135 return mInactive && !isNascent(); 1136 } 1137 1138 /** 1139 * Set the linger duration for this NAI. 1140 * @param durationMs The new linger duration, in milliseconds. 1141 */ 1142 public void setLingerDuration(final int durationMs) { 1143 final long diff = durationMs - mLingerDurationMs; 1144 final ArrayList<InactivityTimer> newTimers = new ArrayList<>(); 1145 for (final InactivityTimer timer : mInactivityTimers) { 1146 if (timer.requestId == NetworkRequest.REQUEST_ID_NONE) { 1147 // Don't touch nascent timer, re-add as is. 1148 newTimers.add(timer); 1149 } else { 1150 newTimers.add(new InactivityTimer(timer.requestId, timer.expiryMs + diff)); 1151 } 1152 } 1153 mInactivityTimers.clear(); 1154 mInactivityTimers.addAll(newTimers); 1155 updateInactivityTimer(); 1156 mLingerDurationMs = durationMs; 1157 } 1158 1159 /** 1160 * Return whether the network satisfies no request, but is still being kept up 1161 * because it has just connected less than 1162 * {@code ConnectivityService#DEFAULT_NASCENT_DELAY_MS}ms ago and is thus still considered 1163 * nascent. Note that nascent mechanism uses inactivity timer which isn't 1164 * associated with a request. Thus, use {@link NetworkRequest#REQUEST_ID_NONE} to identify it. 1165 * 1166 */ 1167 public boolean isNascent() { 1168 return mInactive && mInactivityTimers.size() == 1 1169 && mInactivityTimers.first().requestId == NetworkRequest.REQUEST_ID_NONE; 1170 } 1171 1172 public void clearInactivityState() { 1173 if (mInactivityMessage != null) { 1174 mInactivityMessage.cancel(); 1175 mInactivityMessage = null; 1176 } 1177 mInactivityTimers.clear(); 1178 mInactivityTimerForRequest.clear(); 1179 // Sets mInactivityExpiryMs, cancels and nulls out mInactivityMessage. 1180 updateInactivityTimer(); 1181 mInactive = false; 1182 } 1183 1184 public void dumpInactivityTimers(PrintWriter pw) { 1185 for (InactivityTimer timer : mInactivityTimers) { 1186 pw.println(timer); 1187 } 1188 } 1189 1190 /** 1191 * Dump the NAT64 xlat information. 1192 * 1193 * @param pw print writer. 1194 */ 1195 public void dumpNat464Xlat(IndentingPrintWriter pw) { 1196 clatd.dump(pw); 1197 } 1198 1199 /** 1200 * Sets the most recent ConnectivityReport for this network. 1201 * 1202 * <p>This should only be called from the ConnectivityService thread. 1203 * 1204 * @hide 1205 */ 1206 public void setConnectivityReport(@NonNull ConnectivityReport connectivityReport) { 1207 mConnectivityReport = connectivityReport; 1208 } 1209 1210 /** 1211 * Returns the most recent ConnectivityReport for this network, or null if none have been 1212 * reported yet. 1213 * 1214 * <p>This should only be called from the ConnectivityService thread. 1215 * 1216 * @hide 1217 */ 1218 @Nullable 1219 public ConnectivityReport getConnectivityReport() { 1220 return mConnectivityReport; 1221 } 1222 1223 /** 1224 * Make sure the NC from network agents don't contain stuff they shouldn't. 1225 * 1226 * @param nc the capabilities to sanitize 1227 * @param creatorUid the UID of the process creating this network agent 1228 * @param hasAutomotiveFeature true if this device has the automotive feature, false otherwise 1229 * @param authenticator the carrier privilege authenticator to check for telephony constraints 1230 */ 1231 public static void restrictCapabilitiesFromNetworkAgent(@NonNull final NetworkCapabilities nc, 1232 final int creatorUid, final boolean hasAutomotiveFeature, 1233 @Nullable final CarrierPrivilegeAuthenticator authenticator) { 1234 if (nc.hasTransport(TRANSPORT_TEST)) { 1235 nc.restrictCapabilitiesForTestNetwork(creatorUid); 1236 } 1237 if (!areAllowedUidsAcceptableFromNetworkAgent(nc, hasAutomotiveFeature, authenticator)) { 1238 nc.setAllowedUids(new ArraySet<>()); 1239 } 1240 } 1241 1242 private static boolean areAllowedUidsAcceptableFromNetworkAgent( 1243 @NonNull final NetworkCapabilities nc, final boolean hasAutomotiveFeature, 1244 @Nullable final CarrierPrivilegeAuthenticator carrierPrivilegeAuthenticator) { 1245 // NCs without access UIDs are fine. 1246 if (!nc.hasAllowedUids()) return true; 1247 // S and below must never accept access UIDs, even if an agent sends them, because netd 1248 // didn't support the required feature in S. 1249 if (!SdkLevel.isAtLeastT()) return false; 1250 1251 // On a non-restricted network, access UIDs make no sense 1252 if (nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) return false; 1253 1254 // If this network has TRANSPORT_TEST, then the caller can do whatever they want to 1255 // access UIDs 1256 if (nc.hasTransport(TRANSPORT_TEST)) return true; 1257 1258 // Factories that make ethernet networks can allow UIDs for automotive devices. 1259 if (nc.hasSingleTransport(TRANSPORT_ETHERNET) && hasAutomotiveFeature) { 1260 return true; 1261 } 1262 1263 // Factories that make cell networks can allow the UID for the carrier service package. 1264 // This can only work in T where there is support for CarrierPrivilegeAuthenticator 1265 if (null != carrierPrivilegeAuthenticator 1266 && nc.hasSingleTransport(TRANSPORT_CELLULAR) 1267 && (1 == nc.getAllowedUidsNoCopy().size()) 1268 && (carrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities( 1269 nc.getAllowedUidsNoCopy().valueAt(0), nc))) { 1270 return true; 1271 } 1272 1273 return false; 1274 } 1275 1276 // TODO: Print shorter members first and only print the boolean variable which value is true 1277 // to improve readability. 1278 public String toString() { 1279 return "NetworkAgentInfo{" 1280 + "network{" + network + "} handle{" + network.getNetworkHandle() + "} ni{" 1281 + networkInfo.toShortString() + "} " 1282 + mScore + " " 1283 + (created ? " created" : "") 1284 + (destroyed ? " destroyed" : "") 1285 + (isNascent() ? " nascent" : (isLingering() ? " lingering" : "")) 1286 + (everValidated ? " everValidated" : "") 1287 + (lastValidated ? " lastValidated" : "") 1288 + (partialConnectivity ? " partialConnectivity" : "") 1289 + (everCaptivePortalDetected ? " everCaptivePortal" : "") 1290 + (lastCaptivePortalDetected ? " isCaptivePortal" : "") 1291 + (networkAgentConfig.explicitlySelected ? " explicitlySelected" : "") 1292 + (networkAgentConfig.acceptUnvalidated ? " acceptUnvalidated" : "") 1293 + (networkAgentConfig.acceptPartialConnectivity ? " acceptPartialConnectivity" : "") 1294 + (clatd.isStarted() ? " clat{" + clatd + "} " : "") 1295 + (declaredUnderlyingNetworks != null 1296 ? " underlying{" + Arrays.toString(declaredUnderlyingNetworks) + "}" : "") 1297 + " lp{" + linkProperties + "}" 1298 + " nc{" + networkCapabilities + "}" 1299 + " factorySerialNumber=" + factorySerialNumber 1300 + "}"; 1301 } 1302 1303 /** 1304 * Show a short string representing a Network. 1305 * 1306 * This is often not enough for debugging purposes for anything complex, but the full form 1307 * is very long and hard to read, so this is useful when there isn't a lot of ambiguity. 1308 * This represents the network with something like "[100 WIFI|VPN]" or "[108 MOBILE]". 1309 */ 1310 public String toShortString() { 1311 return "[" + network.getNetId() + " " 1312 + transportNamesOf(networkCapabilities.getTransportTypes()) + "]"; 1313 } 1314 1315 // Enables sorting in descending order of score. 1316 @Override 1317 public int compareTo(NetworkAgentInfo other) { 1318 return other.getCurrentScore() - getCurrentScore(); 1319 } 1320 1321 /** 1322 * Null-guarding version of NetworkAgentInfo#toShortString() 1323 */ 1324 @NonNull 1325 public static String toShortString(@Nullable final NetworkAgentInfo nai) { 1326 return null != nai ? nai.toShortString() : "[null]"; 1327 } 1328 } 1329