NetworkAgentInfo.java revision c8e9e1229a91e22d6ab32d491d4c60086fbc9199
17b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt/* 27b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * Copyright (C) 2014 The Android Open Source Project 37b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * 47b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License"); 57b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * you may not use this file except in compliance with the License. 67b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * You may obtain a copy of the License at 77b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * 87b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * http://www.apache.org/licenses/LICENSE-2.0 97b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * 107b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * Unless required by applicable law or agreed to in writing, software 117b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS, 127b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * See the License for the specific language governing permissions and 147b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * limitations under the License. 157b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt */ 167b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt 177b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwaltpackage com.android.server.connectivity; 187b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt 19e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensenimport static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; 20e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen 21ca8f16ad14819ba17f5ff3d2e2bf6fbc9bbaa9f7Paul Jensenimport android.content.Context; 227b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwaltimport android.net.LinkProperties; 237b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwaltimport android.net.Network; 247b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwaltimport android.net.NetworkCapabilities; 257b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwaltimport android.net.NetworkInfo; 268cd33ed84e94036a5e1201485af7603dc6fb0d9bSreeram Ramachandranimport android.net.NetworkMisc; 277b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwaltimport android.net.NetworkRequest; 28f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkeyimport android.net.NetworkState; 29ca8f16ad14819ba17f5ff3d2e2bf6fbc9bbaa9f7Paul Jensenimport android.os.Handler; 307b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwaltimport android.os.Messenger; 31b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colittiimport android.os.SystemClock; 32b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colittiimport android.util.Log; 337b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwaltimport android.util.SparseArray; 347b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt 357b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwaltimport com.android.internal.util.AsyncChannel; 36b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colittiimport com.android.internal.util.WakeupMessage; 37cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensenimport com.android.server.ConnectivityService; 38ca8f16ad14819ba17f5ff3d2e2bf6fbc9bbaa9f7Paul Jensenimport com.android.server.connectivity.NetworkMonitor; 397b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt 40b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colittiimport java.io.PrintWriter; 417b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwaltimport java.util.ArrayList; 4285cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenimport java.util.Comparator; 43b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colittiimport java.util.Objects; 44b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colittiimport java.util.SortedSet; 45b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colittiimport java.util.TreeSet; 467b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt 477b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt/** 487b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * A bag class used by ConnectivityService for holding a collection of most recent 497b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * information published by a particular NetworkAgent as well as the 507b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt * AsyncChannel/messenger for reaching that NetworkAgent and lists of NetworkRequests 5185cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen * interested in using it. Default sort order is descending by score. 527b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt */ 53e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// States of a network: 54e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// -------------------- 55e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// 1. registered, uncreated, disconnected, unvalidated 56e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// This state is entered when a NetworkFactory registers a NetworkAgent in any state except 57e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// the CONNECTED state. 58585e24889455d1d70d14a9c89a8acef922994898Robin Lee// 2. registered, uncreated, connecting, unvalidated 59585e24889455d1d70d14a9c89a8acef922994898Robin Lee// This state is entered when a registered NetworkAgent for a VPN network transitions to the 60585e24889455d1d70d14a9c89a8acef922994898Robin Lee// CONNECTING state (TODO: go through this state for every network, not just VPNs). 61585e24889455d1d70d14a9c89a8acef922994898Robin Lee// ConnectivityService will tell netd to create the network early in order to add extra UID 62585e24889455d1d70d14a9c89a8acef922994898Robin Lee// routing rules referencing the netID. These rules need to be in place before the network is 63585e24889455d1d70d14a9c89a8acef922994898Robin Lee// connected to avoid racing against client apps trying to connect to a half-setup network. 64585e24889455d1d70d14a9c89a8acef922994898Robin Lee// 3. registered, uncreated, connected, unvalidated 65585e24889455d1d70d14a9c89a8acef922994898Robin Lee// This state is entered when a registered NetworkAgent transitions to the CONNECTED state. 66585e24889455d1d70d14a9c89a8acef922994898Robin Lee// ConnectivityService will tell netd to create the network if it was not already created, and 67585e24889455d1d70d14a9c89a8acef922994898Robin Lee// immediately transition to state #4. 68585e24889455d1d70d14a9c89a8acef922994898Robin Lee// 4. registered, created, connected, unvalidated 69cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen// If this network can satisfy the default NetworkRequest, then NetworkMonitor will 70e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// probe for Internet connectivity. 71e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// If this network cannot satisfy the default NetworkRequest, it will immediately be 72585e24889455d1d70d14a9c89a8acef922994898Robin Lee// transitioned to state #5. 73e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// A network may remain in this state if NetworkMonitor fails to find Internet connectivity, 74e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// for example: 75e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// a. a captive portal is present, or 76e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// b. a WiFi router whose Internet backhaul is down, or 77e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// c. a wireless connection stops transfering packets temporarily (e.g. device is in elevator 78e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// or tunnel) but does not disconnect from the AP/cell tower, or 79e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// d. a stand-alone device offering a WiFi AP without an uplink for configuration purposes. 80585e24889455d1d70d14a9c89a8acef922994898Robin Lee// 5. registered, created, connected, validated 81e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// 82e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// The device's default network connection: 83e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// ---------------------------------------- 84585e24889455d1d70d14a9c89a8acef922994898Robin Lee// Networks in states #4 and #5 may be used as a device's default network connection if they 85e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// satisfy the default NetworkRequest. 86585e24889455d1d70d14a9c89a8acef922994898Robin Lee// A network, that satisfies the default NetworkRequest, in state #5 should always be chosen 87585e24889455d1d70d14a9c89a8acef922994898Robin Lee// in favor of a network, that satisfies the default NetworkRequest, in state #4. 88e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// When deciding between two networks, that both satisfy the default NetworkRequest, to select 89e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// for the default network connection, the one with the higher score should be chosen. 90e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// 91e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// When a network disconnects: 92e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// --------------------------- 93e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// If a network's transport disappears, for example: 94e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// a. WiFi turned off, or 95e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// b. cellular data turned off, or 96e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// c. airplane mode is turned on, or 97e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// d. a wireless connection disconnects from AP/cell tower entirely (e.g. device is out of range 98e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// of AP for an extended period of time, or switches to another AP without roaming) 99585e24889455d1d70d14a9c89a8acef922994898Robin Lee// then that network can transition from any state (#1-#5) to unregistered. This happens by 100e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// the transport disconnecting their NetworkAgent's AsyncChannel with ConnectivityManager. 101e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// ConnectivityService also tells netd to destroy the network. 102e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// 103e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// When ConnectivityService disconnects a network: 104e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// ----------------------------------------------- 105e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// If a network has no chance of satisfying any requests (even if it were to become validated 106585e24889455d1d70d14a9c89a8acef922994898Robin Lee// and enter state #5), ConnectivityService will disconnect the NetworkAgent's AsyncChannel. 107e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// If the network ever for any period of time had satisfied a NetworkRequest (i.e. had been 108e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// the highest scoring that satisfied the NetworkRequest's constraints), but is no longer the 109e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// highest scoring network for any NetworkRequest, then there will be a 30s pause before 110e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// ConnectivityService disconnects the NetworkAgent's AsyncChannel. During this pause the 111e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// network is considered "lingering". This pause exists to allow network communication to be 112e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// wrapped up rather than abruptly terminated. During this pause if the network begins satisfying 113e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// a NetworkRequest, ConnectivityService will cancel the future disconnection of the NetworkAgent's 114e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen// AsyncChannel, and the network is no longer considered "lingering". 11585cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenpublic class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { 116c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi 1177b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt public NetworkInfo networkInfo; 11831a94f48bf8014cf6a1127bd23cf9a8541a9abedPaul Jensen // This Network object should always be used if possible, so as to encourage reuse of the 11931a94f48bf8014cf6a1127bd23cf9a8541a9abedPaul Jensen // enclosed socket factory and connection pool. Avoid creating other Network objects. 12031a94f48bf8014cf6a1127bd23cf9a8541a9abedPaul Jensen // This Network object is always valid. 12131a94f48bf8014cf6a1127bd23cf9a8541a9abedPaul Jensen public final Network network; 1227b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt public LinkProperties linkProperties; 1231c7ba0285b3fe8de479d6c09b2ff45572913c2cbPaul Jensen // This should only be modified via ConnectivityService.updateCapabilities(). 1247b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt public NetworkCapabilities networkCapabilities; 125ca8f16ad14819ba17f5ff3d2e2bf6fbc9bbaa9f7Paul Jensen public final NetworkMonitor networkMonitor; 1268cd33ed84e94036a5e1201485af7603dc6fb0d9bSreeram Ramachandran public final NetworkMisc networkMisc; 127585e24889455d1d70d14a9c89a8acef922994898Robin Lee // Indicates if netd has been told to create this Network. From this point on the appropriate 128585e24889455d1d70d14a9c89a8acef922994898Robin Lee // routing rules are setup and routes are added so packets can begin flowing over the Network. 129d49159f4e997faae6ef4141b667ad6fef74a6724Lorenzo Colitti // This is a sticky bit; once set it is never cleared. 130eec75412a971a5ccb769364120c769c331946eb3Paul Jensen public boolean created; 131585e24889455d1d70d14a9c89a8acef922994898Robin Lee // Set to true after the first time this network is marked as CONNECTED. Once set, the network 132585e24889455d1d70d14a9c89a8acef922994898Robin Lee // shows up in API calls, is able to satisfy NetworkRequests and can become the default network. 133585e24889455d1d70d14a9c89a8acef922994898Robin Lee // This is a sticky bit; once set it is never cleared. 134585e24889455d1d70d14a9c89a8acef922994898Robin Lee public boolean everConnected; 13571b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen // Set to true if this Network successfully passed validation or if it did not satisfy the 13671b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen // default NetworkRequest in which case validation will not be attempted. 137d49159f4e997faae6ef4141b667ad6fef74a6724Lorenzo Colitti // This is a sticky bit; once set it is never cleared even if future validation attempts fail. 138d3b8a3e77696ecd90ce59a869aaadf1e7804a9c8Lorenzo Colitti public boolean everValidated; 139ca8f16ad14819ba17f5ff3d2e2bf6fbc9bbaa9f7Paul Jensen 1407b42f399430d5d4ace4efbee225bbd3ecd2d4146Lorenzo Colitti // The result of the last validation attempt on this network (true if validated, false if not). 1417b42f399430d5d4ace4efbee225bbd3ecd2d4146Lorenzo Colitti // This bit exists only because we never unvalidate a network once it's been validated, and that 1427b42f399430d5d4ace4efbee225bbd3ecd2d4146Lorenzo Colitti // is because the network scoring and revalidation code does not (may not?) deal properly with 1437b42f399430d5d4ace4efbee225bbd3ecd2d4146Lorenzo Colitti // networks becoming unvalidated. 1447b42f399430d5d4ace4efbee225bbd3ecd2d4146Lorenzo Colitti // TODO: Fix the network scoring code, remove this, and rename everValidated to validated. 1457b42f399430d5d4ace4efbee225bbd3ecd2d4146Lorenzo Colitti public boolean lastValidated; 1467b42f399430d5d4ace4efbee225bbd3ecd2d4146Lorenzo Colitti 147d49159f4e997faae6ef4141b667ad6fef74a6724Lorenzo Colitti // Whether a captive portal was ever detected on this network. 148d49159f4e997faae6ef4141b667ad6fef74a6724Lorenzo Colitti // This is a sticky bit; once set it is never cleared. 1493d194eae6f658ed865b2d3b748f8b83834c877abPaul Jensen public boolean everCaptivePortalDetected; 1503d194eae6f658ed865b2d3b748f8b83834c877abPaul Jensen 1513d194eae6f658ed865b2d3b748f8b83834c877abPaul Jensen // Whether a captive portal was found during the last network validation attempt. 1523d194eae6f658ed865b2d3b748f8b83834c877abPaul Jensen public boolean lastCaptivePortalDetected; 153d49159f4e997faae6ef4141b667ad6fef74a6724Lorenzo Colitti 154b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // Networks are lingered when they become unneeded as a result of their NetworkRequests being 155b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // satisfied by a higher-scoring network. so as to allow communication to wrap up before the 156b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // network is taken down. This usually only happens to the default network. Lingering ends with 157b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // either the linger timeout expiring and the network being taken down, or the network 158b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // satisfying a request again. 159b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public static class LingerTimer implements Comparable<LingerTimer> { 160b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public final NetworkRequest request; 161b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public final long expiryMs; 162b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 163b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public LingerTimer(NetworkRequest request, long expiryMs) { 164b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti this.request = request; 165b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti this.expiryMs = expiryMs; 166b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 167b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public boolean equals(Object o) { 168b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti if (!(o instanceof LingerTimer)) return false; 169b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti LingerTimer other = (LingerTimer) o; 170b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti return (request.requestId == other.request.requestId) && (expiryMs == other.expiryMs); 171b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 172b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public int hashCode() { 173b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti return Objects.hash(request.requestId, expiryMs); 174b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 175b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public int compareTo(LingerTimer other) { 176b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti return (expiryMs != other.expiryMs) ? 177b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti Long.compare(expiryMs, other.expiryMs) : 178b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti Integer.compare(request.requestId, other.request.requestId); 179b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 180b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public String toString() { 181b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti return String.format("%s, expires %dms", request.toString(), 182b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti expiryMs - SystemClock.elapsedRealtime()); 183b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 184b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 185b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 186b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti /** 187b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti * Inform ConnectivityService that the network LINGER period has 188b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti * expired. 189b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti * obj = this NetworkAgentInfo 190b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti */ 191b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public static final int EVENT_NETWORK_LINGER_COMPLETE = 1001; 192b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 193b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // All linger timers for this network, sorted by expiry time. A linger timer is added whenever 194b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // a request is moved to a network with a better score, regardless of whether the network is or 195b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // was lingering or not. 196b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // TODO: determine if we can replace this with a smaller or unsorted data structure. (e.g., 197b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // SparseLongArray) combined with the timestamp of when the last timer is scheduled to fire. 198b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti private final SortedSet<LingerTimer> mLingerTimers = new TreeSet<>(); 199b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 200b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // For fast lookups. Indexes into mLingerTimers by request ID. 201b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti private final SparseArray<LingerTimer> mLingerTimerForRequest = new SparseArray<>(); 202b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 203b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // Linger expiry timer. Armed whenever mLingerTimers is non-empty, regardless of whether the 204b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // network is lingering or not. Always set to the expiry of the LingerTimer that expires last. 205b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // When the timer fires, all linger state is cleared, and if the network has no requests, it is 206b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // torn down. 207b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti private WakeupMessage mLingerMessage; 208b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 209b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // Linger expiry. Holds the expiry time of the linger timer, or 0 if the timer is not armed. 210b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti private long mLingerExpiryMs; 211b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 212b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // Whether the network is lingering or not. Must be maintained separately from the above because 213b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // it depends on the state of other networks and requests, which only ConnectivityService knows. 214b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // (Example: we don't linger a network if it would become the best for a NetworkRequest if it 215b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // validated). 216b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti private boolean mLingering; 21785cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen 2182161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen // This represents the last score received from the NetworkAgent. 2192161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen private int currentScore; 2202161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen // Penalty applied to scores of Networks that have not been validated. 2212161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen private static final int UNVALIDATED_SCORE_PENALTY = 40; 2222161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen 223e73cc4646bed3926024c9f54ca59e3a82a97b56cRobert Greenwalt // Score for explicitly connected network. 224e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti // 225e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti // This ensures that a) the explicitly selected network is never trumped by anything else, and 226e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti // b) the explicitly selected network is never torn down. 227e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti private static final int MAXIMUM_NETWORK_SCORE = 100; 228e73cc4646bed3926024c9f54ca59e3a82a97b56cRobert Greenwalt 2297b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt // The list of NetworkRequests being satisfied by this Network. 230767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>(); 23171b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen // The list of NetworkRequests that this Network previously satisfied with the highest 23271b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen // score. A non-empty list indicates that if this Network was validated it is lingered. 233767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti // How many of the satisfied requests are actual requests and not listens. 234767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti private int mNumRequestNetworkRequests = 0; 2357b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt 2367b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt public final Messenger messenger; 2377b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt public final AsyncChannel asyncChannel; 2387b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt 239954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti // Used by ConnectivityService to keep track of 464xlat. 240954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti public Nat464Xlat clatd; 241954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti 242b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti private static final String TAG = ConnectivityService.class.getSimpleName(); 243b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti private static final boolean VDBG = false; 244b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti private final ConnectivityService mConnService; 245b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti private final Context mContext; 246b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti private final Handler mHandler; 247b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 24831a94f48bf8014cf6a1127bd23cf9a8541a9abedPaul Jensen public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info, 2498cd33ed84e94036a5e1201485af7603dc6fb0d9bSreeram Ramachandran LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler, 250cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen NetworkMisc misc, NetworkRequest defaultRequest, ConnectivityService connService) { 2517b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt this.messenger = messenger; 2527b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt asyncChannel = ac; 25331a94f48bf8014cf6a1127bd23cf9a8541a9abedPaul Jensen network = net; 2547b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt networkInfo = info; 2557b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt linkProperties = lp; 2567b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt networkCapabilities = nc; 2577b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt currentScore = score; 258b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mConnService = connService; 259b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mContext = context; 260b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mHandler = handler; 261b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti networkMonitor = mConnService.createNetworkMonitor(context, handler, this, defaultRequest); 2628cd33ed84e94036a5e1201485af7603dc6fb0d9bSreeram Ramachandran networkMisc = misc; 2637b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt } 2647b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt 265767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti // Functions for manipulating the requests satisfied by this network. 266767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti // 267767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti // These functions must only called on ConnectivityService's main thread. 268767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti 2693d911469a190437fe936103e861bfa171841fbd6Paul Jensen /** 2703d911469a190437fe936103e861bfa171841fbd6Paul Jensen * Add {@code networkRequest} to this network as it's satisfied by this network. 2713d911469a190437fe936103e861bfa171841fbd6Paul Jensen * @return true if {@code networkRequest} was added or false if {@code networkRequest} was 2723d911469a190437fe936103e861bfa171841fbd6Paul Jensen * already present. 2733d911469a190437fe936103e861bfa171841fbd6Paul Jensen */ 2743d911469a190437fe936103e861bfa171841fbd6Paul Jensen public boolean addRequest(NetworkRequest networkRequest) { 275767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti NetworkRequest existing = mNetworkRequests.get(networkRequest.requestId); 276767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti if (existing == networkRequest) return false; 277767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti if (existing != null && existing.isRequest()) mNumRequestNetworkRequests--; 278767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti mNetworkRequests.put(networkRequest.requestId, networkRequest); 279767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti if (networkRequest.isRequest()) mNumRequestNetworkRequests++; 2803d911469a190437fe936103e861bfa171841fbd6Paul Jensen return true; 28171bf33a02f49444fbfa35b267c70592f3b07a07dRobert Greenwalt } 28271bf33a02f49444fbfa35b267c70592f3b07a07dRobert Greenwalt 283767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti /** 284767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti * Remove the specified request from this network. 285767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti */ 286767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti public void removeRequest(int requestId) { 287767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti NetworkRequest existing = mNetworkRequests.get(requestId); 288b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti if (existing == null) return; 289767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti mNetworkRequests.remove(requestId); 290b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti if (existing.isRequest()) { 291b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mNumRequestNetworkRequests--; 292b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti unlingerRequest(existing); 293b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 294767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti } 295767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti 296767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti /** 297767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti * Returns whether this network is currently satisfying the request with the specified ID. 298767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti */ 299767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti public boolean isSatisfyingRequest(int id) { 300767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti return mNetworkRequests.get(id) != null; 301767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti } 302767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti 303767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti /** 304767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti * Returns the request at the specified position in the list of requests satisfied by this 305767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti * network. 306767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti */ 307767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti public NetworkRequest requestAt(int index) { 308767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti return mNetworkRequests.valueAt(index); 309767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti } 310767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti 311767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti /** 312767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti * Returns the number of requests currently satisfied by this network for which 313767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti * {@link android.net.NetworkRequest#isRequest} returns {@code true}. 314767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti */ 315767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti public int numRequestNetworkRequests() { 316767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti return mNumRequestNetworkRequests; 317767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti } 318767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti 319767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti /** 320767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti * Returns the number of requests of any type currently satisfied by this network. 321767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti */ 322767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti public int numNetworkRequests() { 323767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti return mNetworkRequests.size(); 324767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti } 325767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti 3260cc1732cfb9d68779449b4c12661b4df6bfc720bPaul Jensen // Does this network satisfy request? 3270cc1732cfb9d68779449b4c12661b4df6bfc720bPaul Jensen public boolean satisfies(NetworkRequest request) { 3280cc1732cfb9d68779449b4c12661b4df6bfc720bPaul Jensen return created && 3290cc1732cfb9d68779449b4c12661b4df6bfc720bPaul Jensen request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities); 3300cc1732cfb9d68779449b4c12661b4df6bfc720bPaul Jensen } 3310cc1732cfb9d68779449b4c12661b4df6bfc720bPaul Jensen 332c3f21f3b8b01508f5dc01b2e5fa4c3d652bb67bbLorenzo Colitti public boolean satisfiesImmutableCapabilitiesOf(NetworkRequest request) { 333c3f21f3b8b01508f5dc01b2e5fa4c3d652bb67bbLorenzo Colitti return created && 334c3f21f3b8b01508f5dc01b2e5fa4c3d652bb67bbLorenzo Colitti request.networkCapabilities.satisfiedByImmutableNetworkCapabilities( 335c3f21f3b8b01508f5dc01b2e5fa4c3d652bb67bbLorenzo Colitti networkCapabilities); 336c3f21f3b8b01508f5dc01b2e5fa4c3d652bb67bbLorenzo Colitti } 337c3f21f3b8b01508f5dc01b2e5fa4c3d652bb67bbLorenzo Colitti 3386bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen public boolean isVPN() { 3396bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN); 3406bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen } 3416bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen 342b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen private int getCurrentScore(boolean pretendValidated) { 3432161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen // TODO: We may want to refactor this into a NetworkScore class that takes a base score from 3442161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen // the NetworkAgent and signals from the NetworkAgent and uses those signals to modify the 3452161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen // score. The NetworkScore class would provide a nice place to centralize score constants 3462161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen // so they are not scattered about the transports. 3472161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen 348e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti // If this network is explicitly selected and the user has decided to use it even if it's 349e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti // unvalidated, give it the maximum score. Also give it the maximum score if it's explicitly 350e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti // selected and we're trying to see what its score could be. This ensures that we don't tear 351e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti // down an explicitly selected network before the user gets a chance to prefer it when 352e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti // a higher-scoring network (e.g., Ethernet) is available. 353e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti if (networkMisc.explicitlySelected && (networkMisc.acceptUnvalidated || pretendValidated)) { 354e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti return MAXIMUM_NETWORK_SCORE; 355e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti } 3562161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen 357e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti int score = currentScore; 358c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty()) { 359e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen score -= UNVALIDATED_SCORE_PENALTY; 360e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen } 3612161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen if (score < 0) score = 0; 3622161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen return score; 3632161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen } 3642161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen 365c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi // Return true on devices configured to ignore score penalty for wifi networks 366c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi // that become unvalidated (b/31075769). 367c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi private boolean ignoreWifiUnvalidationPenalty() { 368c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi boolean isWifi = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI); 369c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi return isWifi && !mConnService.avoidBadWifi() && everValidated; 370c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi } 371c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi 372b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen // Get the current score for this Network. This may be modified from what the 373b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen // NetworkAgent sent, as it has modifiers applied to it. 374b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen public int getCurrentScore() { 375b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen return getCurrentScore(false); 376b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen } 377b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen 378b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen // Get the current score for this Network as if it was validated. This may be modified from 379b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen // what the NetworkAgent sent, as it has modifiers applied to it. 380b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen public int getCurrentScoreAsValidated() { 381b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen return getCurrentScore(true); 382b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen } 383b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen 3842161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen public void setCurrentScore(int newScore) { 3852161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen currentScore = newScore; 3862161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen } 3872161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen 388f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey public NetworkState getNetworkState() { 389f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey synchronized (this) { 390f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey // Network objects are outwardly immutable so there is no point to duplicating. 391f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey // Duplicating also precludes sharing socket factories and connection pools. 392f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey final String subscriberId = (networkMisc != null) ? networkMisc.subscriberId : null; 393f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey return new NetworkState(new NetworkInfo(networkInfo), 394f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey new LinkProperties(linkProperties), 395f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey new NetworkCapabilities(networkCapabilities), network, subscriberId, null); 396f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey } 397f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey } 398f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey 399b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti /** 400b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti * Sets the specified request to linger on this network for the specified time. Called by 401b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti * ConnectivityService when the request is moved to another network with a higher score. 402b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti */ 403b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public void lingerRequest(NetworkRequest request, long now, long duration) { 404b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti if (mLingerTimerForRequest.get(request.requestId) != null) { 405b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // Cannot happen. Once a request is lingering on a particular network, we cannot 406b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // re-linger it unless that network becomes the best for that request again, in which 407b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // case we should have unlingered it. 408b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti Log.wtf(TAG, this.name() + ": request " + request.requestId + " already lingered"); 409b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 410b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti final long expiryMs = now + duration; 411b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti LingerTimer timer = new LingerTimer(request, expiryMs); 412b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti if (VDBG) Log.d(TAG, "Adding LingerTimer " + timer + " to " + this.name()); 413b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingerTimers.add(timer); 414b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingerTimerForRequest.put(request.requestId, timer); 415b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 416b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 417b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti /** 418b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti * Cancel lingering. Called by ConnectivityService when a request is added to this network. 4195526f9c78c6fcad500c272ef14b7403e3395525eLorenzo Colitti * Returns true if the given request was lingering on this network, false otherwise. 420b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti */ 4215526f9c78c6fcad500c272ef14b7403e3395525eLorenzo Colitti public boolean unlingerRequest(NetworkRequest request) { 422b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti LingerTimer timer = mLingerTimerForRequest.get(request.requestId); 423b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti if (timer != null) { 424b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti if (VDBG) Log.d(TAG, "Removing LingerTimer " + timer + " from " + this.name()); 425b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingerTimers.remove(timer); 426b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingerTimerForRequest.remove(request.requestId); 4275526f9c78c6fcad500c272ef14b7403e3395525eLorenzo Colitti return true; 428b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 4295526f9c78c6fcad500c272ef14b7403e3395525eLorenzo Colitti return false; 430b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 431b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 432b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public long getLingerExpiry() { 433b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti return mLingerExpiryMs; 434b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 435b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 436b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public void updateLingerTimer() { 437b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti long newExpiry = mLingerTimers.isEmpty() ? 0 : mLingerTimers.last().expiryMs; 438b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti if (newExpiry == mLingerExpiryMs) return; 439b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 440b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // Even if we're going to reschedule the timer, cancel it first. This is because the 441b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // semantics of WakeupMessage guarantee that if cancel is called then the alarm will 442b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // never call its callback (handleLingerComplete), even if it has already fired. 443b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // WakeupMessage makes no such guarantees about rescheduling a message, so if mLingerMessage 444b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // has already been dispatched, rescheduling to some time in the future it won't stop it 445b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti // from calling its callback immediately. 446b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti if (mLingerMessage != null) { 447b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingerMessage.cancel(); 448b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingerMessage = null; 449b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 450b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 451b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti if (newExpiry > 0) { 452b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingerMessage = mConnService.makeWakeupMessage( 453b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mContext, mHandler, 454b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti "NETWORK_LINGER_COMPLETE." + network.netId, 455b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti EVENT_NETWORK_LINGER_COMPLETE, this); 456b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingerMessage.schedule(newExpiry); 457b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 458b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 459b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingerExpiryMs = newExpiry; 460b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 461b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 462b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public void linger() { 463b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingering = true; 464b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 465b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 466b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public void unlinger() { 467b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingering = false; 468b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 469b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 470b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public boolean isLingering() { 471b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti return mLingering; 472b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 473b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 474b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public void clearLingerState() { 475b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti if (mLingerMessage != null) { 476b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingerMessage.cancel(); 477b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingerMessage = null; 478b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 479b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingerTimers.clear(); 480b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingerTimerForRequest.clear(); 481b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti updateLingerTimer(); // Sets mLingerExpiryMs, cancels and nulls out mLingerMessage. 482b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti mLingering = false; 483b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 484b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 485b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti public void dumpLingerTimers(PrintWriter pw) { 486b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti for (LingerTimer timer : mLingerTimers) { pw.println(timer); } 487b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti } 488b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti 4897b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt public String toString() { 490230d5ca49821bd7a10bb1b3e61d10f534f687772Erik Kline return "NetworkAgentInfo{ ni{" + networkInfo + "} " + 491230d5ca49821bd7a10bb1b3e61d10f534f687772Erik Kline "network{" + network + "} nethandle{" + network.getNetworkHandle() + "} " + 492230d5ca49821bd7a10bb1b3e61d10f534f687772Erik Kline "lp{" + linkProperties + "} " + 493230d5ca49821bd7a10bb1b3e61d10f534f687772Erik Kline "nc{" + networkCapabilities + "} Score{" + getCurrentScore() + "} " + 4947b42f399430d5d4ace4efbee225bbd3ecd2d4146Lorenzo Colitti "everValidated{" + everValidated + "} lastValidated{" + lastValidated + "} " + 495b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti "created{" + created + "} lingering{" + isLingering() + "} " + 496e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti "explicitlySelected{" + networkMisc.explicitlySelected + "} " + 497e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti "acceptUnvalidated{" + networkMisc.acceptUnvalidated + "} " + 4983d194eae6f658ed865b2d3b748f8b83834c877abPaul Jensen "everCaptivePortalDetected{" + everCaptivePortalDetected + "} " + 4993d194eae6f658ed865b2d3b748f8b83834c877abPaul Jensen "lastCaptivePortalDetected{" + lastCaptivePortalDetected + "} " + 500e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti "}"; 5017b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt } 5027b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt 5037b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt public String name() { 5047b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt return "NetworkAgentInfo [" + networkInfo.getTypeName() + " (" + 50560061a6ebf4ef758c4a47d210de0e5be2484be5bPaul Jensen networkInfo.getSubtypeName() + ") - " + 50660061a6ebf4ef758c4a47d210de0e5be2484be5bPaul Jensen (network == null ? "null" : network.toString()) + "]"; 5077b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt } 50885cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen 50985cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen // Enables sorting in descending order of score. 51085cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen @Override 51185cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen public int compareTo(NetworkAgentInfo other) { 51285cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen return other.getCurrentScore() - getCurrentScore(); 51385cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen } 5147b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt} 515