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