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.
1073d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti//
1083d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti// If the network was satisfying a foreground NetworkRequest (i.e. had been the highest scoring that
1093d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti// satisfied the NetworkRequest's constraints), but is no longer the highest scoring network for any
1103d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti// foreground NetworkRequest, then there will be a 30s pause to allow network communication to be
1113d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti// wrapped up rather than abruptly terminated. During this pause the network is said to be
1123d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti// "lingering". During this pause if the network begins satisfying a foreground NetworkRequest,
1133d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti// ConnectivityService will cancel the future disconnection of the NetworkAgent's AsyncChannel, and
1143d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti// the network is no longer considered "lingering". After the linger timer expires, if the network
1153d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti// is satisfying one or more background NetworkRequests it is kept up in the background. If it is
1163d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti// not, ConnectivityService disconnects the NetworkAgent's AsyncChannel.
11785cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensenpublic class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
118c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi
1197b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt    public NetworkInfo networkInfo;
12031a94f48bf8014cf6a1127bd23cf9a8541a9abedPaul Jensen    // This Network object should always be used if possible, so as to encourage reuse of the
12131a94f48bf8014cf6a1127bd23cf9a8541a9abedPaul Jensen    // enclosed socket factory and connection pool.  Avoid creating other Network objects.
12231a94f48bf8014cf6a1127bd23cf9a8541a9abedPaul Jensen    // This Network object is always valid.
12331a94f48bf8014cf6a1127bd23cf9a8541a9abedPaul Jensen    public final Network network;
1247b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt    public LinkProperties linkProperties;
1251c7ba0285b3fe8de479d6c09b2ff45572913c2cbPaul Jensen    // This should only be modified via ConnectivityService.updateCapabilities().
1267b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt    public NetworkCapabilities networkCapabilities;
127ca8f16ad14819ba17f5ff3d2e2bf6fbc9bbaa9f7Paul Jensen    public final NetworkMonitor networkMonitor;
1288cd33ed84e94036a5e1201485af7603dc6fb0d9bSreeram Ramachandran    public final NetworkMisc networkMisc;
129585e24889455d1d70d14a9c89a8acef922994898Robin Lee    // Indicates if netd has been told to create this Network. From this point on the appropriate
130585e24889455d1d70d14a9c89a8acef922994898Robin Lee    // routing rules are setup and routes are added so packets can begin flowing over the Network.
131d49159f4e997faae6ef4141b667ad6fef74a6724Lorenzo Colitti    // This is a sticky bit; once set it is never cleared.
132eec75412a971a5ccb769364120c769c331946eb3Paul Jensen    public boolean created;
133585e24889455d1d70d14a9c89a8acef922994898Robin Lee    // Set to true after the first time this network is marked as CONNECTED. Once set, the network
134585e24889455d1d70d14a9c89a8acef922994898Robin Lee    // shows up in API calls, is able to satisfy NetworkRequests and can become the default network.
135585e24889455d1d70d14a9c89a8acef922994898Robin Lee    // This is a sticky bit; once set it is never cleared.
136585e24889455d1d70d14a9c89a8acef922994898Robin Lee    public boolean everConnected;
13771b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen    // Set to true if this Network successfully passed validation or if it did not satisfy the
13871b645fe9cb8106dfcbf025a3fd7f58698c051bbPaul Jensen    // default NetworkRequest in which case validation will not be attempted.
139d49159f4e997faae6ef4141b667ad6fef74a6724Lorenzo Colitti    // This is a sticky bit; once set it is never cleared even if future validation attempts fail.
140d3b8a3e77696ecd90ce59a869aaadf1e7804a9c8Lorenzo Colitti    public boolean everValidated;
141ca8f16ad14819ba17f5ff3d2e2bf6fbc9bbaa9f7Paul Jensen
1427b42f399430d5d4ace4efbee225bbd3ecd2d4146Lorenzo Colitti    // The result of the last validation attempt on this network (true if validated, false if not).
1437b42f399430d5d4ace4efbee225bbd3ecd2d4146Lorenzo Colitti    public boolean lastValidated;
1447b42f399430d5d4ace4efbee225bbd3ecd2d4146Lorenzo Colitti
145165c51c0eb9834a3d95ce0b31b07c7c8975a54d7Lorenzo Colitti    // If true, becoming unvalidated will lower the network's score. This is only meaningful if the
146165c51c0eb9834a3d95ce0b31b07c7c8975a54d7Lorenzo Colitti    // system is configured not to do this for certain networks, e.g., if the
147165c51c0eb9834a3d95ce0b31b07c7c8975a54d7Lorenzo Colitti    // config_networkAvoidBadWifi option is set to 0 and the user has not overridden that via
148165c51c0eb9834a3d95ce0b31b07c7c8975a54d7Lorenzo Colitti    // Settings.Global.NETWORK_AVOID_BAD_WIFI.
149165c51c0eb9834a3d95ce0b31b07c7c8975a54d7Lorenzo Colitti    public boolean avoidUnvalidated;
150165c51c0eb9834a3d95ce0b31b07c7c8975a54d7Lorenzo Colitti
151d49159f4e997faae6ef4141b667ad6fef74a6724Lorenzo Colitti    // Whether a captive portal was ever detected on this network.
152d49159f4e997faae6ef4141b667ad6fef74a6724Lorenzo Colitti    // This is a sticky bit; once set it is never cleared.
1533d194eae6f658ed865b2d3b748f8b83834c877abPaul Jensen    public boolean everCaptivePortalDetected;
1543d194eae6f658ed865b2d3b748f8b83834c877abPaul Jensen
1553d194eae6f658ed865b2d3b748f8b83834c877abPaul Jensen    // Whether a captive portal was found during the last network validation attempt.
1563d194eae6f658ed865b2d3b748f8b83834c877abPaul Jensen    public boolean lastCaptivePortalDetected;
157d49159f4e997faae6ef4141b667ad6fef74a6724Lorenzo Colitti
158b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // Networks are lingered when they become unneeded as a result of their NetworkRequests being
159b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // satisfied by a higher-scoring network. so as to allow communication to wrap up before the
160b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // network is taken down.  This usually only happens to the default network. Lingering ends with
161b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // either the linger timeout expiring and the network being taken down, or the network
162b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // satisfying a request again.
163b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    public static class LingerTimer implements Comparable<LingerTimer> {
164b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        public final NetworkRequest request;
165b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        public final long expiryMs;
166b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
167b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        public LingerTimer(NetworkRequest request, long expiryMs) {
168b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            this.request = request;
169b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            this.expiryMs = expiryMs;
170b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        }
171b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        public boolean equals(Object o) {
172b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            if (!(o instanceof LingerTimer)) return false;
173b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            LingerTimer other = (LingerTimer) o;
174b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            return (request.requestId == other.request.requestId) && (expiryMs == other.expiryMs);
175b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        }
176b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        public int hashCode() {
177b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            return Objects.hash(request.requestId, expiryMs);
178b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        }
179b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        public int compareTo(LingerTimer other) {
180b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            return (expiryMs != other.expiryMs) ?
181b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti                    Long.compare(expiryMs, other.expiryMs) :
182b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti                    Integer.compare(request.requestId, other.request.requestId);
183b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        }
184b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        public String toString() {
185b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            return String.format("%s, expires %dms", request.toString(),
186b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti                    expiryMs - SystemClock.elapsedRealtime());
187b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        }
188b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    }
189b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
190b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    /**
191b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti     * Inform ConnectivityService that the network LINGER period has
192b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti     * expired.
193b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti     * obj = this NetworkAgentInfo
194b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti     */
195b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    public static final int EVENT_NETWORK_LINGER_COMPLETE = 1001;
196b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
197b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // All linger timers for this network, sorted by expiry time. A linger timer is added whenever
198b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // a request is moved to a network with a better score, regardless of whether the network is or
199b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // was lingering or not.
200b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // TODO: determine if we can replace this with a smaller or unsorted data structure. (e.g.,
201b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // SparseLongArray) combined with the timestamp of when the last timer is scheduled to fire.
202b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    private final SortedSet<LingerTimer> mLingerTimers = new TreeSet<>();
203b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
204b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // For fast lookups. Indexes into mLingerTimers by request ID.
205b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    private final SparseArray<LingerTimer> mLingerTimerForRequest = new SparseArray<>();
206b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
207b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // Linger expiry timer. Armed whenever mLingerTimers is non-empty, regardless of whether the
208b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // network is lingering or not. Always set to the expiry of the LingerTimer that expires last.
209b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // When the timer fires, all linger state is cleared, and if the network has no requests, it is
210b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // torn down.
211b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    private WakeupMessage mLingerMessage;
212b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
213b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // Linger expiry. Holds the expiry time of the linger timer, or 0 if the timer is not armed.
214b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    private long mLingerExpiryMs;
215b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
216b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // Whether the network is lingering or not. Must be maintained separately from the above because
217b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // it depends on the state of other networks and requests, which only ConnectivityService knows.
218b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // (Example: we don't linger a network if it would become the best for a NetworkRequest if it
219b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    // validated).
220b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    private boolean mLingering;
22185cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen
2222161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen    // This represents the last score received from the NetworkAgent.
2232161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen    private int currentScore;
2242161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen    // Penalty applied to scores of Networks that have not been validated.
2252161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen    private static final int UNVALIDATED_SCORE_PENALTY = 40;
2262161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen
227e73cc4646bed3926024c9f54ca59e3a82a97b56cRobert Greenwalt    // Score for explicitly connected network.
228e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti    //
229e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti    // This ensures that a) the explicitly selected network is never trumped by anything else, and
230e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti    // b) the explicitly selected network is never torn down.
231e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti    private static final int MAXIMUM_NETWORK_SCORE = 100;
232e73cc4646bed3926024c9f54ca59e3a82a97b56cRobert Greenwalt
2337b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt    // The list of NetworkRequests being satisfied by this Network.
234767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>();
2353d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti
236767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    // How many of the satisfied requests are actual requests and not listens.
237767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    private int mNumRequestNetworkRequests = 0;
2387b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt
2393d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    // How many of the satisfied requests are of type BACKGROUND_REQUEST.
2403d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    private int mNumBackgroundNetworkRequests = 0;
2413d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti
2427b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt    public final Messenger messenger;
2437b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt    public final AsyncChannel asyncChannel;
2447b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt
245954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti    // Used by ConnectivityService to keep track of 464xlat.
246954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti    public Nat464Xlat clatd;
247954394653dad05838235f48244a4320893e0f0cfLorenzo Colitti
248b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    private static final String TAG = ConnectivityService.class.getSimpleName();
249b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    private static final boolean VDBG = false;
250b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    private final ConnectivityService mConnService;
251b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    private final Context mContext;
252b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    private final Handler mHandler;
253b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
25431a94f48bf8014cf6a1127bd23cf9a8541a9abedPaul Jensen    public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
2558cd33ed84e94036a5e1201485af7603dc6fb0d9bSreeram Ramachandran            LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler,
256cf4c2c637268b1a2979e20a8b5644916777a02a4Paul Jensen            NetworkMisc misc, NetworkRequest defaultRequest, ConnectivityService connService) {
2577b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt        this.messenger = messenger;
2587b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt        asyncChannel = ac;
25931a94f48bf8014cf6a1127bd23cf9a8541a9abedPaul Jensen        network = net;
2607b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt        networkInfo = info;
2617b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt        linkProperties = lp;
2627b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt        networkCapabilities = nc;
2637b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt        currentScore = score;
264b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        mConnService = connService;
265b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        mContext = context;
266b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        mHandler = handler;
267b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        networkMonitor = mConnService.createNetworkMonitor(context, handler, this, defaultRequest);
2688cd33ed84e94036a5e1201485af7603dc6fb0d9bSreeram Ramachandran        networkMisc = misc;
2697b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt    }
2707b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt
271767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    // Functions for manipulating the requests satisfied by this network.
272767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    //
273767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    // These functions must only called on ConnectivityService's main thread.
274767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti
2753d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    private static final boolean ADD = true;
2763d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    private static final boolean REMOVE = false;
2773d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti
2783d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    private void updateRequestCounts(boolean add, NetworkRequest request) {
2793d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti        int delta = add ? +1 : -1;
2803d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti        switch (request.type) {
2813d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti            case REQUEST:
2823d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti            case TRACK_DEFAULT:
2833d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti                mNumRequestNetworkRequests += delta;
2843d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti                break;
2853d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti
2863d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti            case BACKGROUND_REQUEST:
2873d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti                mNumRequestNetworkRequests += delta;
2883d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti                mNumBackgroundNetworkRequests += delta;
2893d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti                break;
2903d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti
2913d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti            case LISTEN:
2923d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti                break;
2933d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti
2943d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti            case NONE:
2953d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti            default:
2963d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti                Log.wtf(TAG, "Unhandled request type " + request.type);
2973d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti                break;
2983d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti        }
2993d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    }
3003d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti
3013d911469a190437fe936103e861bfa171841fbd6Paul Jensen    /**
3023d911469a190437fe936103e861bfa171841fbd6Paul Jensen     * Add {@code networkRequest} to this network as it's satisfied by this network.
3033d911469a190437fe936103e861bfa171841fbd6Paul Jensen     * @return true if {@code networkRequest} was added or false if {@code networkRequest} was
3043d911469a190437fe936103e861bfa171841fbd6Paul Jensen     *         already present.
3053d911469a190437fe936103e861bfa171841fbd6Paul Jensen     */
3063d911469a190437fe936103e861bfa171841fbd6Paul Jensen    public boolean addRequest(NetworkRequest networkRequest) {
307767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti        NetworkRequest existing = mNetworkRequests.get(networkRequest.requestId);
308767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti        if (existing == networkRequest) return false;
3093d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti        if (existing != null) {
3103d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti            // Should only happen if the requestId wraps. If that happens lots of other things will
3113d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti            // be broken as well.
3123d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti            Log.wtf(TAG, String.format("Duplicate requestId for %s and %s on %s",
3133d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti                    networkRequest, existing, name()));
3143d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti            updateRequestCounts(REMOVE, existing);
3153d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti        }
316767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti        mNetworkRequests.put(networkRequest.requestId, networkRequest);
3173d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti        updateRequestCounts(ADD, networkRequest);
3183d911469a190437fe936103e861bfa171841fbd6Paul Jensen        return true;
31971bf33a02f49444fbfa35b267c70592f3b07a07dRobert Greenwalt    }
32071bf33a02f49444fbfa35b267c70592f3b07a07dRobert Greenwalt
321767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    /**
322767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti     * Remove the specified request from this network.
323767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti     */
324767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    public void removeRequest(int requestId) {
325767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti        NetworkRequest existing = mNetworkRequests.get(requestId);
326b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        if (existing == null) return;
3273d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti        updateRequestCounts(REMOVE, existing);
328767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti        mNetworkRequests.remove(requestId);
329b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        if (existing.isRequest()) {
330b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            unlingerRequest(existing);
331b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        }
332767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    }
333767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti
334767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    /**
335767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti     * Returns whether this network is currently satisfying the request with the specified ID.
336767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti     */
337767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    public boolean isSatisfyingRequest(int id) {
338767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti        return mNetworkRequests.get(id) != null;
339767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    }
340767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti
341767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    /**
342767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti     * Returns the request at the specified position in the list of requests satisfied by this
343767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti     * network.
344767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti     */
345767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    public NetworkRequest requestAt(int index) {
346767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti        return mNetworkRequests.valueAt(index);
347767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    }
348767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti
349767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    /**
350767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti     * Returns the number of requests currently satisfied by this network for which
351767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti     * {@link android.net.NetworkRequest#isRequest} returns {@code true}.
352767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti     */
353767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    public int numRequestNetworkRequests() {
354767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti        return mNumRequestNetworkRequests;
355767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    }
356767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti
357767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    /**
3583d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti     * Returns the number of requests currently satisfied by this network of type
3593d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti     * {@link android.net.NetworkRequest.Type.BACKGROUND_REQUEST}.
3603d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti     */
3613d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    public int numBackgroundNetworkRequests() {
3623d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti        return mNumBackgroundNetworkRequests;
3633d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    }
3643d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti
3653d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    /**
3663d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti     * Returns the number of foreground requests currently satisfied by this network.
3673d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti     */
3683d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    public int numForegroundNetworkRequests() {
3693d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti        return mNumRequestNetworkRequests - mNumBackgroundNetworkRequests;
3703d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    }
3713d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti
3723d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    /**
373767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti     * Returns the number of requests of any type currently satisfied by this network.
374767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti     */
375767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    public int numNetworkRequests() {
376767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti        return mNetworkRequests.size();
377767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti    }
378767708db54edbdb26e166157fa05966769a629ccLorenzo Colitti
3793d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    /**
3803d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti     * Returns whether the network is a background network. A network is a background network if it
3813d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti     * is satisfying no foreground requests and at least one background request. (If it did not have
3823d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti     * a background request, it would be a speculative network that is only being kept up because
3833d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti     * it might satisfy a request if it validated).
3843d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti     */
3853d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    public boolean isBackgroundNetwork() {
386f0e9a33435c02001836a359a37aae56a7eeee2adLorenzo Colitti        return !isVPN() && numForegroundNetworkRequests() == 0 && mNumBackgroundNetworkRequests > 0;
3873d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti    }
3883d4a10617c6d967aa0f07e129264e07320e99073Lorenzo Colitti
3890cc1732cfb9d68779449b4c12661b4df6bfc720bPaul Jensen    // Does this network satisfy request?
3900cc1732cfb9d68779449b4c12661b4df6bfc720bPaul Jensen    public boolean satisfies(NetworkRequest request) {
3910cc1732cfb9d68779449b4c12661b4df6bfc720bPaul Jensen        return created &&
3920cc1732cfb9d68779449b4c12661b4df6bfc720bPaul Jensen                request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities);
3930cc1732cfb9d68779449b4c12661b4df6bfc720bPaul Jensen    }
3940cc1732cfb9d68779449b4c12661b4df6bfc720bPaul Jensen
395c3f21f3b8b01508f5dc01b2e5fa4c3d652bb67bbLorenzo Colitti    public boolean satisfiesImmutableCapabilitiesOf(NetworkRequest request) {
396c3f21f3b8b01508f5dc01b2e5fa4c3d652bb67bbLorenzo Colitti        return created &&
397c3f21f3b8b01508f5dc01b2e5fa4c3d652bb67bbLorenzo Colitti                request.networkCapabilities.satisfiedByImmutableNetworkCapabilities(
398c3f21f3b8b01508f5dc01b2e5fa4c3d652bb67bbLorenzo Colitti                        networkCapabilities);
399c3f21f3b8b01508f5dc01b2e5fa4c3d652bb67bbLorenzo Colitti    }
400c3f21f3b8b01508f5dc01b2e5fa4c3d652bb67bbLorenzo Colitti
4016bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    public boolean isVPN() {
4026bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen        return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
4036bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen    }
4046bc2c2c34f2b23eae79ad733c97a691734055c4fPaul Jensen
405b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen    private int getCurrentScore(boolean pretendValidated) {
4062161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen        // TODO: We may want to refactor this into a NetworkScore class that takes a base score from
4072161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen        // the NetworkAgent and signals from the NetworkAgent and uses those signals to modify the
4082161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen        // score.  The NetworkScore class would provide a nice place to centralize score constants
4092161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen        // so they are not scattered about the transports.
4102161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen
411e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti        // If this network is explicitly selected and the user has decided to use it even if it's
412e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti        // unvalidated, give it the maximum score. Also give it the maximum score if it's explicitly
413e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti        // selected and we're trying to see what its score could be. This ensures that we don't tear
414e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti        // down an explicitly selected network before the user gets a chance to prefer it when
415e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti        // a higher-scoring network (e.g., Ethernet) is available.
416e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti        if (networkMisc.explicitlySelected && (networkMisc.acceptUnvalidated || pretendValidated)) {
417e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti            return MAXIMUM_NETWORK_SCORE;
418e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti        }
4192161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen
420e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti        int score = currentScore;
421c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi        if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty()) {
422e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen            score -= UNVALIDATED_SCORE_PENALTY;
423e098854c41a72b22f4174bc623e8e93cde8d7331Paul Jensen        }
4242161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen        if (score < 0) score = 0;
4252161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen        return score;
4262161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen    }
4272161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen
428c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi    // Return true on devices configured to ignore score penalty for wifi networks
429c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi    // that become unvalidated (b/31075769).
430c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi    private boolean ignoreWifiUnvalidationPenalty() {
431165c51c0eb9834a3d95ce0b31b07c7c8975a54d7Lorenzo Colitti        boolean isWifi = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) &&
432165c51c0eb9834a3d95ce0b31b07c7c8975a54d7Lorenzo Colitti                networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
433165c51c0eb9834a3d95ce0b31b07c7c8975a54d7Lorenzo Colitti        boolean avoidBadWifi = mConnService.avoidBadWifi() || avoidUnvalidated;
434165c51c0eb9834a3d95ce0b31b07c7c8975a54d7Lorenzo Colitti        return isWifi && !avoidBadWifi && everValidated;
435c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi    }
436c8e9e1229a91e22d6ab32d491d4c60086fbc9199Hugo Benichi
437b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen    // Get the current score for this Network.  This may be modified from what the
438b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen    // NetworkAgent sent, as it has modifiers applied to it.
439b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen    public int getCurrentScore() {
440b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen        return getCurrentScore(false);
441b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen    }
442b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen
443b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen    // Get the current score for this Network as if it was validated.  This may be modified from
444b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen    // what the NetworkAgent sent, as it has modifiers applied to it.
445b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen    public int getCurrentScoreAsValidated() {
446b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen        return getCurrentScore(true);
447b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen    }
448b10e37fd1c3a95f7e621eed234c2491eb71241e2Paul Jensen
4492161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen    public void setCurrentScore(int newScore) {
4502161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen        currentScore = newScore;
4512161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen    }
4522161a8ea123134ee3f9a10c0f8f56aabd8289f69Paul Jensen
453f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey    public NetworkState getNetworkState() {
454f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey        synchronized (this) {
455f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey            // Network objects are outwardly immutable so there is no point to duplicating.
456f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey            // Duplicating also precludes sharing socket factories and connection pools.
457f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey            final String subscriberId = (networkMisc != null) ? networkMisc.subscriberId : null;
458f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey            return new NetworkState(new NetworkInfo(networkInfo),
459f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey                    new LinkProperties(linkProperties),
460f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey                    new NetworkCapabilities(networkCapabilities), network, subscriberId, null);
461f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey        }
462f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey    }
463f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey
464b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    /**
465b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti     * Sets the specified request to linger on this network for the specified time. Called by
466b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti     * ConnectivityService when the request is moved to another network with a higher score.
467b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti     */
468b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    public void lingerRequest(NetworkRequest request, long now, long duration) {
469b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        if (mLingerTimerForRequest.get(request.requestId) != null) {
470b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            // Cannot happen. Once a request is lingering on a particular network, we cannot
471b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            // re-linger it unless that network becomes the best for that request again, in which
472b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            // case we should have unlingered it.
473b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            Log.wtf(TAG, this.name() + ": request " + request.requestId + " already lingered");
474b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        }
475b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        final long expiryMs = now + duration;
476b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        LingerTimer timer = new LingerTimer(request, expiryMs);
477b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        if (VDBG) Log.d(TAG, "Adding LingerTimer " + timer + " to " + this.name());
478b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        mLingerTimers.add(timer);
479b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        mLingerTimerForRequest.put(request.requestId, timer);
480b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    }
481b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
482b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    /**
483b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti     * Cancel lingering. Called by ConnectivityService when a request is added to this network.
4845526f9c78c6fcad500c272ef14b7403e3395525eLorenzo Colitti     * Returns true if the given request was lingering on this network, false otherwise.
485b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti     */
4865526f9c78c6fcad500c272ef14b7403e3395525eLorenzo Colitti    public boolean unlingerRequest(NetworkRequest request) {
487b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        LingerTimer timer = mLingerTimerForRequest.get(request.requestId);
488b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        if (timer != null) {
489b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            if (VDBG) Log.d(TAG, "Removing LingerTimer " + timer + " from " + this.name());
490b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            mLingerTimers.remove(timer);
491b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            mLingerTimerForRequest.remove(request.requestId);
4925526f9c78c6fcad500c272ef14b7403e3395525eLorenzo Colitti            return true;
493b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        }
4945526f9c78c6fcad500c272ef14b7403e3395525eLorenzo Colitti        return false;
495b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    }
496b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
497b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    public long getLingerExpiry() {
498b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        return mLingerExpiryMs;
499b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    }
500b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
501b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    public void updateLingerTimer() {
502b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        long newExpiry = mLingerTimers.isEmpty() ? 0 : mLingerTimers.last().expiryMs;
503b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        if (newExpiry == mLingerExpiryMs) return;
504b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
505b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        // Even if we're going to reschedule the timer, cancel it first. This is because the
506b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        // semantics of WakeupMessage guarantee that if cancel is called then the alarm will
507b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        // never call its callback (handleLingerComplete), even if it has already fired.
508b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        // WakeupMessage makes no such guarantees about rescheduling a message, so if mLingerMessage
509b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        // has already been dispatched, rescheduling to some time in the future it won't stop it
510b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        // from calling its callback immediately.
511b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        if (mLingerMessage != null) {
512b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            mLingerMessage.cancel();
513b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            mLingerMessage = null;
514b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        }
515b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
516b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        if (newExpiry > 0) {
517b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            mLingerMessage = mConnService.makeWakeupMessage(
518b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti                    mContext, mHandler,
519b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti                    "NETWORK_LINGER_COMPLETE." + network.netId,
520b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti                    EVENT_NETWORK_LINGER_COMPLETE, this);
521b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            mLingerMessage.schedule(newExpiry);
522b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        }
523b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
524b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        mLingerExpiryMs = newExpiry;
525b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    }
526b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
527b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    public void linger() {
528b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        mLingering = true;
529b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    }
530b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
531b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    public void unlinger() {
532b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        mLingering = false;
533b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    }
534b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
535b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    public boolean isLingering() {
536b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        return mLingering;
537b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    }
538b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
539b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    public void clearLingerState() {
540b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        if (mLingerMessage != null) {
541b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            mLingerMessage.cancel();
542b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti            mLingerMessage = null;
543b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        }
544b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        mLingerTimers.clear();
545b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        mLingerTimerForRequest.clear();
546b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        updateLingerTimer();  // Sets mLingerExpiryMs, cancels and nulls out mLingerMessage.
547b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        mLingering = false;
548b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    }
549b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
550b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    public void dumpLingerTimers(PrintWriter pw) {
551b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti        for (LingerTimer timer : mLingerTimers) { pw.println(timer); }
552b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti    }
553b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti
5547b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt    public String toString() {
555230d5ca49821bd7a10bb1b3e61d10f534f687772Erik Kline        return "NetworkAgentInfo{ ni{" + networkInfo + "}  " +
556230d5ca49821bd7a10bb1b3e61d10f534f687772Erik Kline                "network{" + network + "}  nethandle{" + network.getNetworkHandle() + "}  " +
557230d5ca49821bd7a10bb1b3e61d10f534f687772Erik Kline                "lp{" + linkProperties + "}  " +
558230d5ca49821bd7a10bb1b3e61d10f534f687772Erik Kline                "nc{" + networkCapabilities + "}  Score{" + getCurrentScore() + "}  " +
5597b42f399430d5d4ace4efbee225bbd3ecd2d4146Lorenzo Colitti                "everValidated{" + everValidated + "}  lastValidated{" + lastValidated + "}  " +
560b57578ca4f0fa64406ffad09ad9250391e3bbfa5Lorenzo Colitti                "created{" + created + "} lingering{" + isLingering() + "} " +
561e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti                "explicitlySelected{" + networkMisc.explicitlySelected + "} " +
562e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti                "acceptUnvalidated{" + networkMisc.acceptUnvalidated + "} " +
5633d194eae6f658ed865b2d3b748f8b83834c877abPaul Jensen                "everCaptivePortalDetected{" + everCaptivePortalDetected + "} " +
5643d194eae6f658ed865b2d3b748f8b83834c877abPaul Jensen                "lastCaptivePortalDetected{" + lastCaptivePortalDetected + "} " +
565e03c3c7edf54854ed22adf1e55b27b2408c4c66aLorenzo Colitti                "}";
5667b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt    }
5677b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt
5687b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt    public String name() {
5697b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt        return "NetworkAgentInfo [" + networkInfo.getTypeName() + " (" +
57060061a6ebf4ef758c4a47d210de0e5be2484be5bPaul Jensen                networkInfo.getSubtypeName() + ") - " +
57160061a6ebf4ef758c4a47d210de0e5be2484be5bPaul Jensen                (network == null ? "null" : network.toString()) + "]";
5727b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt    }
57385cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen
57485cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen    // Enables sorting in descending order of score.
57585cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen    @Override
57685cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen    public int compareTo(NetworkAgentInfo other) {
57785cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen        return other.getCurrentScore() - getCurrentScore();
57885cf78edc92b85ec90e91de42b14b84e202260f3Paul Jensen    }
5797b81602f3c18df8a4ca0342c514af8f7e394c0d7Robert Greenwalt}
580