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