From 2801857fecbf3a17218ae58c0d8ee2bb4ea8b54b Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Mon, 21 Dec 2020 18:36:52 +0900 Subject: [PATCH] [NS01] Add NetworkScore As attested by numerous TODOs in the code, a new way of representing network quality and policy is needed instead of an int. An int representing the quality of the network requires all parties using it to know how all other parties are using it, and implementation details about the decision algorithm. For all intents and purposes, the selection is left to individual network factories who try to achieve a desired result while piecing together all possible states of the system. As the number of such cases and desires increases, this becomes both intractable and unmaintainable. Indeed, at this time in the codebase nobody can really predict exactly how a given change in score will affect selection across the board, and it is essentially impossible to figure out the behavior of network selection by inspecting the code because the moving parts are scattered throughout the entire codebase. Having an object encapsulating policy and quality values will let us centralize the selection and make it again possible to maintain without knowledge of all behaviors of all network factories. It will also provide better guarantees of respecting policy, and allow bugfixes that were not possible before because they'd touch too many parts of the code. Test: FrameworksNetTests FrameworksWifiTests NetworkStackTests Change-Id: I3185a6412b9b659798faf0c6882699e9c63cc115 --- core/java/android/net/NetworkScore.java | 108 ++++++++++++++++++ .../src/android/net/ConnectivityManager.java | 20 +--- .../src/android/net/IConnectivityManager.aidl | 3 +- framework/src/android/net/NetworkAgent.java | 42 +++++-- .../aidl/INetworkAgentRegistry.aidl | 5 +- .../android/server/ConnectivityService.java | 42 +++---- .../server/connectivity/NetworkAgentInfo.java | 18 +-- .../server/ConnectivityServiceTest.java | 4 +- .../connectivity/LingerMonitorTest.java | 6 +- .../android/server/connectivity/VpnTest.java | 8 +- 10 files changed, 188 insertions(+), 68 deletions(-) create mode 100644 core/java/android/net/NetworkScore.java diff --git a/core/java/android/net/NetworkScore.java b/core/java/android/net/NetworkScore.java new file mode 100644 index 0000000000..f478010022 --- /dev/null +++ b/core/java/android/net/NetworkScore.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Object representing the quality of a network as perceived by the user. + * + * A NetworkScore object represents the characteristics of a network that affects how good the + * network is considered for a particular use. + * @hide + */ +// TODO : @SystemApi when the implementation is complete +public final class NetworkScore implements Parcelable { + // This will be removed soon. Do *NOT* depend on it for any new code that is not part of + // a migration. + private final int mLegacyInt; + + /** @hide */ + NetworkScore(final int legacyInt) { + this.mLegacyInt = legacyInt; + } + + private NetworkScore(@NonNull final Parcel in) { + mLegacyInt = in.readInt(); + } + + public int getLegacyInt() { + return mLegacyInt; + } + + @Override + public String toString() { + return "Score(" + mLegacyInt + ")"; + } + + @Override + public void writeToParcel(@NonNull final Parcel dest, final int flags) { + dest.writeInt(mLegacyInt); + } + + @Override + public int describeContents() { + return 0; + } + + @NonNull public static final Creator CREATOR = new Creator<>() { + @Override + @NonNull + public NetworkScore createFromParcel(@NonNull final Parcel in) { + return new NetworkScore(in); + } + + @Override + @NonNull + public NetworkScore[] newArray(int size) { + return new NetworkScore[size]; + } + }; + + /** + * A builder for NetworkScore. + */ + public static final class Builder { + private static final int INVALID_LEGACY_INT = Integer.MIN_VALUE; + private int mLegacyInt = INVALID_LEGACY_INT; + + /** + * Sets the legacy int for this score. + * + * Do not rely on this. It will be gone by the time S is released. + * + * @param score the legacy int + * @return this + */ + @NonNull + public Builder setLegacyInt(final int score) { + mLegacyInt = score; + return this; + } + + /** + * Builds this NetworkScore. + * @return The built NetworkScore object. + */ + @NonNull + public NetworkScore build() { + return new NetworkScore(mLegacyInt); + } + } +} diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java index 8c66db9a20..aec6b0a6ca 100644 --- a/framework/src/android/net/ConnectivityManager.java +++ b/framework/src/android/net/ConnectivityManager.java @@ -3205,10 +3205,6 @@ public class ConnectivityManager { } } - // TODO : remove this method. It is a stopgap measure to help sheperding a number - // of dependent changes that would conflict throughout the automerger graph. Having this - // temporarily helps with the process of going through with all these dependent changes across - // the entire tree. /** * @hide * Register a NetworkAgent with ConnectivityService. @@ -3218,20 +3214,8 @@ public class ConnectivityManager { NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public Network registerNetworkAgent(INetworkAgent na, NetworkInfo ni, LinkProperties lp, - NetworkCapabilities nc, int score, NetworkAgentConfig config) { - return registerNetworkAgent(na, ni, lp, nc, score, config, NetworkProvider.ID_NONE); - } - - /** - * @hide - * Register a NetworkAgent with ConnectivityService. - * @return Network corresponding to NetworkAgent. - */ - @RequiresPermission(anyOf = { - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - android.Manifest.permission.NETWORK_FACTORY}) - public Network registerNetworkAgent(INetworkAgent na, NetworkInfo ni, LinkProperties lp, - NetworkCapabilities nc, int score, NetworkAgentConfig config, int providerId) { + NetworkCapabilities nc, @NonNull NetworkScore score, NetworkAgentConfig config, + int providerId) { try { return mService.registerNetworkAgent(na, ni, lp, nc, score, config, providerId); } catch (RemoteException e) { diff --git a/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl index f9393e315b..1bbf1a95fc 100644 --- a/framework/src/android/net/IConnectivityManager.aidl +++ b/framework/src/android/net/IConnectivityManager.aidl @@ -30,6 +30,7 @@ import android.net.NetworkAgentConfig; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; +import android.net.NetworkScore; import android.net.NetworkState; import android.net.NetworkStateSnapshot; import android.net.OemNetworkPreferences; @@ -138,7 +139,7 @@ interface IConnectivityManager void declareNetworkRequestUnfulfillable(in NetworkRequest request); Network registerNetworkAgent(in INetworkAgent na, in NetworkInfo ni, in LinkProperties lp, - in NetworkCapabilities nc, int score, in NetworkAgentConfig config, + in NetworkCapabilities nc, in NetworkScore score, in NetworkAgentConfig config, in int factorySerialNumber); NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, int reqType, diff --git a/framework/src/android/net/NetworkAgent.java b/framework/src/android/net/NetworkAgent.java index 27aa15d1e1..b3ab0ee8bd 100644 --- a/framework/src/android/net/NetworkAgent.java +++ b/framework/src/android/net/NetworkAgent.java @@ -371,6 +371,14 @@ public abstract class NetworkAgent { return ni; } + // Temporary backward compatibility constructor + public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag, + @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score, + @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) { + this(context, looper, logTag, nc, lp, + new NetworkScore.Builder().setLegacyInt(score).build(), config, provider); + } + /** * Create a new network agent. * @param context a {@link Context} to get system services from. @@ -382,10 +390,12 @@ public abstract class NetworkAgent { * @param score the initial score of this network. Update with sendNetworkScore. * @param config an immutable {@link NetworkAgentConfig} for this agent. * @param provider the {@link NetworkProvider} managing this agent. + * @hide TODO : unhide when impl is complete */ public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag, - @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score, - @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) { + @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, + @NonNull NetworkScore score, @NonNull NetworkAgentConfig config, + @Nullable NetworkProvider provider) { this(looper, context, logTag, nc, lp, score, config, provider == null ? NetworkProvider.ID_NONE : provider.getProviderId(), getLegacyNetworkInfo(config)); @@ -395,12 +405,12 @@ public abstract class NetworkAgent { public final Context context; public final NetworkCapabilities capabilities; public final LinkProperties properties; - public final int score; + public final NetworkScore score; public final NetworkAgentConfig config; public final NetworkInfo info; InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities, - @NonNull LinkProperties properties, int score, @NonNull NetworkAgentConfig config, - @NonNull NetworkInfo info) { + @NonNull LinkProperties properties, @NonNull NetworkScore score, + @NonNull NetworkAgentConfig config, @NonNull NetworkInfo info) { this.context = context; this.capabilities = capabilities; this.properties = properties; @@ -412,8 +422,9 @@ public abstract class NetworkAgent { private volatile InitialConfiguration mInitialConfiguration; private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag, - @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score, - @NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni) { + @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, + @NonNull NetworkScore score, @NonNull NetworkAgentConfig config, int providerId, + @NonNull NetworkInfo ni) { mHandler = new NetworkAgentHandler(looper); LOG_TAG = logTag; mNetworkInfo = new NetworkInfo(ni); @@ -872,16 +883,25 @@ public abstract class NetworkAgent { queueOrSendMessage(reg -> reg.sendNetworkCapabilities(nc)); } + /** + * Must be called by the agent to update the score of this network. + * + * @param score the new score. + * @hide TODO : unhide when impl is complete + */ + public final void sendNetworkScore(@NonNull NetworkScore score) { + Objects.requireNonNull(score); + queueOrSendMessage(reg -> reg.sendScore(score)); + } + /** * Must be called by the agent to update the score of this network. * * @param score the new score, between 0 and 99. + * deprecated use sendNetworkScore(NetworkScore) TODO : remove in S. */ public final void sendNetworkScore(@IntRange(from = 0, to = 99) int score) { - if (score < 0) { - throw new IllegalArgumentException("Score must be >= 0"); - } - queueOrSendMessage(reg -> reg.sendScore(score)); + sendNetworkScore(new NetworkScore.Builder().setLegacyInt(score).build()); } /** diff --git a/framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl b/framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl index f0193db5c2..18d26a7e4b 100644 --- a/framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl +++ b/framework/src/com/android/connectivity/aidl/INetworkAgentRegistry.aidl @@ -19,11 +19,12 @@ import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; +import android.net.NetworkScore; import android.net.QosSession; import android.telephony.data.EpsBearerQosSessionAttributes; /** - * Interface for NetworkAgents to send network network properties. + * Interface for NetworkAgents to send network properties. * @hide */ oneway interface INetworkAgentRegistry { @@ -31,7 +32,7 @@ oneway interface INetworkAgentRegistry { void sendLinkProperties(in LinkProperties lp); // TODO: consider replacing this by "markConnected()" and removing void sendNetworkInfo(in NetworkInfo info); - void sendScore(int score); + void sendScore(in NetworkScore score); void sendExplicitlySelected(boolean explicitlySelected, boolean acceptPartial); void sendSocketKeepaliveEvent(int slot, int reason); void sendUnderlyingNetworks(in @nullable List networks); diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index afa3bd1da6..b21424be7d 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -117,6 +117,7 @@ import android.net.NetworkMonitorManager; import android.net.NetworkPolicyManager; import android.net.NetworkProvider; import android.net.NetworkRequest; +import android.net.NetworkScore; import android.net.NetworkSpecifier; import android.net.NetworkStack; import android.net.NetworkStackClient; @@ -1271,12 +1272,18 @@ public class ConnectivityService extends IConnectivityManager.Stub mDnsManager = new DnsManager(mContext, mDnsResolver); registerPrivateDnsSettingsCallbacks(); + // This NAI is a sentinel used to offer no service to apps that are on a multi-layer + // request that doesn't allow fallback to the default network. It should never be visible + // to apps. As such, it's not in the list of NAIs and doesn't need many of the normal + // arguments like the handler or the DnsResolver. + // TODO : remove thisĀ ; it is probably better handled with a sentinel request. mNoServiceNetwork = new NetworkAgentInfo(null, new Network(NO_SERVICE_NET_ID), new NetworkInfo(TYPE_NONE, 0, "", ""), - new LinkProperties(), new NetworkCapabilities(), 0, mContext, - null, new NetworkAgentConfig(), this, null, - null, 0, INVALID_UID, mQosCallbackTracker, mDeps); + new LinkProperties(), new NetworkCapabilities(), + new NetworkScore.Builder().setLegacyInt(0).build(), mContext, null, + new NetworkAgentConfig(), this, null, null, 0, INVALID_UID, mQosCallbackTracker, + mDeps); } private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) { @@ -2947,7 +2954,7 @@ public class ConnectivityService extends IConnectivityManager.Stub break; } case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: { - updateNetworkScore(nai, msg.arg1); + updateNetworkScore(nai, (NetworkScore) arg.second); break; } case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: { @@ -6078,20 +6085,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return nai == getDefaultNetwork(); } - // TODO : remove this method. It's a stopgap measure to help sheperding a number of dependent - // changes that would conflict throughout the automerger graph. Having this method temporarily - // helps with the process of going through with all these dependent changes across the entire - // tree. - /** - * Register a new agent. {@see #registerNetworkAgent} below. - */ - public Network registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo, - LinkProperties linkProperties, NetworkCapabilities networkCapabilities, - int currentScore, NetworkAgentConfig networkAgentConfig) { - return registerNetworkAgent(na, networkInfo, linkProperties, networkCapabilities, - currentScore, networkAgentConfig, NetworkProvider.ID_NONE); - } - /** * Register a new agent with ConnectivityService to handle a network. * @@ -6102,7 +6095,7 @@ public class ConnectivityService extends IConnectivityManager.Stub * later : see {@link #updateLinkProperties}. * @param networkCapabilities the initial capabilites of this network. They can be updated * later : see {@link #updateCapabilities}. - * @param currentScore the initial score of the network. See + * @param initialScore the initial score of the network. See * {@link NetworkAgentInfo#getCurrentScore}. * @param networkAgentConfig metadata about the network. This is never updated. * @param providerId the ID of the provider owning this NetworkAgent. @@ -6110,10 +6103,12 @@ public class ConnectivityService extends IConnectivityManager.Stub */ public Network registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, - int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) { + @NonNull NetworkScore initialScore, NetworkAgentConfig networkAgentConfig, + int providerId) { Objects.requireNonNull(networkInfo, "networkInfo must not be null"); Objects.requireNonNull(linkProperties, "linkProperties must not be null"); Objects.requireNonNull(networkCapabilities, "networkCapabilities must not be null"); + Objects.requireNonNull(initialScore, "initialScore must not be null"); Objects.requireNonNull(networkAgentConfig, "networkAgentConfig must not be null"); if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { enforceAnyPermissionOf(Manifest.permission.MANAGE_TEST_NETWORKS); @@ -6125,7 +6120,7 @@ public class ConnectivityService extends IConnectivityManager.Stub final long token = Binder.clearCallingIdentity(); try { return registerNetworkAgentInternal(na, networkInfo, linkProperties, - networkCapabilities, currentScore, networkAgentConfig, providerId, uid); + networkCapabilities, initialScore, networkAgentConfig, providerId, uid); } finally { Binder.restoreCallingIdentity(token); } @@ -6133,7 +6128,8 @@ public class ConnectivityService extends IConnectivityManager.Stub private Network registerNetworkAgentInternal(INetworkAgent na, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, - int currentScore, NetworkAgentConfig networkAgentConfig, int providerId, int uid) { + NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId, + int uid) { if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { // Strictly, sanitizing here is unnecessary as the capabilities will be sanitized in // the call to mixInCapabilities below anyway, but sanitizing here means the NAI never @@ -7852,7 +7848,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final int score) { + private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final NetworkScore score) { if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score); nai.setScore(score); rematchAllNetworksAndRequests(); diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 803cc9d31c..9dcc55b81a 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -35,6 +35,7 @@ import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkMonitorManager; import android.net.NetworkRequest; +import android.net.NetworkScore; import android.net.NetworkStateSnapshot; import android.net.QosCallbackException; import android.net.QosFilter; @@ -302,8 +303,8 @@ public class NetworkAgentInfo implements Comparable { // validated). private boolean mInactive; - // This represents the quality of the network with no clear scale. - private int mScore; + // This represents the quality of the network. + private NetworkScore mScore; // The list of NetworkRequests being satisfied by this Network. private final SparseArray mNetworkRequests = new SparseArray<>(); @@ -338,7 +339,8 @@ public class NetworkAgentInfo implements Comparable { private final QosCallbackTracker mQosCallbackTracker; public NetworkAgentInfo(INetworkAgent na, Network net, NetworkInfo info, - @NonNull LinkProperties lp, @NonNull NetworkCapabilities nc, int score, Context context, + @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, QosCallbackTracker qosCallbackTracker, ConnectivityService.Dependencies deps) { @@ -603,9 +605,9 @@ public class NetworkAgentInfo implements Comparable { } @Override - public void sendScore(int score) { - mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_SCORE_CHANGED, score, 0, - new Pair<>(NetworkAgentInfo.this, null)).sendToTarget(); + public void sendScore(@NonNull final NetworkScore score) { + mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_SCORE_CHANGED, + new Pair<>(NetworkAgentInfo.this, score)).sendToTarget(); } @Override @@ -857,7 +859,7 @@ public class NetworkAgentInfo implements Comparable { return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE; } - int score = mScore; + int score = mScore.getLegacyInt(); if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) { score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY; } @@ -886,7 +888,7 @@ public class NetworkAgentInfo implements Comparable { return getCurrentScore(true); } - public void setScore(final int score) { + public void setScore(final NetworkScore score) { mScore = score; } diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 2c8c8a6409..a06ce27db6 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -202,6 +202,7 @@ import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkPolicyManager; import android.net.NetworkRequest; +import android.net.NetworkScore; import android.net.NetworkSpecifier; import android.net.NetworkStack; import android.net.NetworkStackClient; @@ -9153,7 +9154,8 @@ public class ConnectivityServiceTest { ConnectivityManager.getNetworkTypeName(TYPE_MOBILE), TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE)); return new NetworkAgentInfo(null, new Network(NET_ID), info, new LinkProperties(), - nc, 0, mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0, + nc, new NetworkScore.Builder().setLegacyInt(0).build(), + mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0, INVALID_UID, mQosCallbackTracker, new ConnectivityService.Dependencies()); } diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java index 1c0ba4f8d8..ea2b362c53 100644 --- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java @@ -40,6 +40,7 @@ import android.net.NetworkAgentConfig; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkProvider; +import android.net.NetworkScore; import android.os.Binder; import android.text.format.DateUtils; @@ -355,8 +356,9 @@ public class LingerMonitorTest { caps.addCapability(0); caps.addTransportType(transport); NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info, - new LinkProperties(), caps, 50, mCtx, null, new NetworkAgentConfig() /* config */, - mConnService, mNetd, mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(), + new LinkProperties(), caps, new NetworkScore.Builder().setLegacyInt(50).build(), + mCtx, null, new NetworkAgentConfig() /* config */, mConnService, mNetd, + mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(), mQosCallbackTracker, new ConnectivityService.Dependencies()); nai.everValidated = true; return nai; diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java index b8f7fbca39..11fcea60d9 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/tests/net/java/com/android/server/connectivity/VpnTest.java @@ -1026,7 +1026,11 @@ public class VpnTest { .thenReturn(new Network[] { new Network(101) }); when(mConnectivityManager.registerNetworkAgent(any(), any(), any(), any(), - anyInt(), any(), anyInt())).thenReturn(new Network(102)); + any(), any(), anyInt())).thenAnswer(invocation -> { + // The runner has registered an agent and is now ready. + legacyRunnerReady.open(); + return new Network(102); + }); final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), profile); final TestDeps deps = (TestDeps) vpn.mDeps; try { @@ -1048,7 +1052,7 @@ public class VpnTest { ArgumentCaptor ncCaptor = ArgumentCaptor.forClass(NetworkCapabilities.class); verify(mConnectivityManager, timeout(10_000)).registerNetworkAgent(any(), any(), - lpCaptor.capture(), ncCaptor.capture(), anyInt(), any(), anyInt()); + lpCaptor.capture(), ncCaptor.capture(), any(), any(), anyInt()); // In this test the expected address is always v4 so /32. // Note that the interface needs to be specified because RouteInfo objects stored in