Snap for 6227479 from 3f9ddc30d980652f610f86959a3bf32669ff661e to rvc-release

Change-Id: I65b6bc752687d3530d7bc6b2167673374abbeb6d
This commit is contained in:
android-build-team Robot
2020-02-22 03:20:49 +00:00
6 changed files with 59 additions and 297 deletions

View File

@@ -21,6 +21,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.SystemApi; import android.annotation.SystemApi;
import android.annotation.TestApi; import android.annotation.TestApi;
import android.os.Bundle;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
@@ -83,69 +84,10 @@ public final class NetworkScore implements Parcelable {
uplinkBandwidthKBps = uplinkBandwidth; uplinkBandwidthKBps = uplinkBandwidth;
} }
/**
* Evaluate whether a metrics codes for faster network is faster than another.
*
* This is a simple comparison of expected speeds. If either of the tested attributes
* are unknown, this returns zero. This implementation just assumes downlink bandwidth
* is more important than uplink bandwidth, which is more important than latency. This
* is not a very good way of evaluating network speed, but it's a start.
* TODO : do something more representative of how fast the network feels
*
* @param other the Metrics to evaluate against
* @return a negative integer, zero, or a positive integer as this metrics is worse than,
* equally good as (or unknown), or better than the passed Metrics.
* @see #compareToPreferringKnown(Metrics)
* @hide
*/
// Can't implement Comparable<Metrics> because this is @hide.
public int compareTo(@NonNull final Metrics other) {
if (downlinkBandwidthKBps != BANDWIDTH_UNKNOWN
&& other.downlinkBandwidthKBps != BANDWIDTH_UNKNOWN) {
if (downlinkBandwidthKBps > other.downlinkBandwidthKBps) return 1;
if (downlinkBandwidthKBps < other.downlinkBandwidthKBps) return -1;
}
if (uplinkBandwidthKBps != BANDWIDTH_UNKNOWN
&& other.uplinkBandwidthKBps != BANDWIDTH_UNKNOWN) {
if (uplinkBandwidthKBps > other.uplinkBandwidthKBps) return 1;
if (uplinkBandwidthKBps < other.uplinkBandwidthKBps) return -1;
}
if (latencyMs != LATENCY_UNKNOWN && other.latencyMs != LATENCY_UNKNOWN) {
// Latency : lower is better
if (latencyMs > other.latencyMs) return -1;
if (latencyMs < other.latencyMs) return 1;
}
return 0;
}
/**
* Evaluate whether a metrics codes for faster network is faster than another.
*
* This is a simple comparison of expected speeds. If either of the tested attributes
* are unknown, this prefers the known attributes. This implementation just assumes
* downlink bandwidth is more important than uplink bandwidth, which is more important than
* latency. This is not a very good way of evaluating network speed, but it's a start.
* TODO : do something more representative of how fast the network feels
*
* @param other the Metrics to evaluate against
* @return a negative integer, zero, or a positive integer as this metrics is worse than,
* equally good as (or unknown), or better than the passed Metrics.
* @see #compareTo(Metrics)
* @hide
*/
public int compareToPreferringKnown(@NonNull final Metrics other) {
if (downlinkBandwidthKBps > other.downlinkBandwidthKBps) return 1;
if (downlinkBandwidthKBps < other.downlinkBandwidthKBps) return -1;
if (uplinkBandwidthKBps > other.uplinkBandwidthKBps) return 1;
if (uplinkBandwidthKBps < other.uplinkBandwidthKBps) return -1;
// Latency : lower is better
return -Integer.compare(latencyMs, other.latencyMs);
}
/** toString */ /** toString */
public String toString() { public String toString() {
return "latency = " + latencyMs + " downlinkBandwidth = " + downlinkBandwidthKBps return "latency = " + latencyMs + " downlinkBandwidth = " + downlinkBandwidthKBps
+ " uplinkBandwidth = " + uplinkBandwidthKBps; + "uplinkBandwidth = " + uplinkBandwidthKBps;
} }
@NonNull @NonNull
@@ -405,33 +347,6 @@ public final class NetworkScore implements Parcelable {
return mLegacyScore; return mLegacyScore;
} }
/**
* Use the metrics to evaluate whether a network is faster than another.
*
* This is purely based on the metrics, and explicitly ignores policy or exiting. It's
* provided to get a decision on two networks when policy can not decide, or to evaluate
* how a network is expected to compare to another if it should validate.
*
* @param other the score to evaluate against
* @return whether this network is probably faster than the other
* @hide
*/
public boolean probablyFasterThan(@NonNull final NetworkScore other) {
if (mLegacyScore > other.mLegacyScore) return true;
final int atEndToEnd = mEndToEndMetrics.compareTo(other.mEndToEndMetrics);
if (atEndToEnd > 0) return true;
if (atEndToEnd < 0) return false;
final int atLinkLayer = mLinkLayerMetrics.compareTo(other.mLinkLayerMetrics);
if (atLinkLayer > 0) return true;
if (atLinkLayer < 0) return false;
final int atEndToEndPreferringKnown =
mEndToEndMetrics.compareToPreferringKnown(other.mEndToEndMetrics);
if (atEndToEndPreferringKnown > 0) return true;
if (atEndToEndPreferringKnown < 0) return false;
// If this returns 0, neither is "probably faster" so just return false.
return mLinkLayerMetrics.compareToPreferringKnown(other.mLinkLayerMetrics) > 0;
}
/** Builder for NetworkScore. */ /** Builder for NetworkScore. */
public static class Builder { public static class Builder {
private int mPolicy = 0; private int mPolicy = 0;
@@ -439,27 +354,17 @@ public final class NetworkScore implements Parcelable {
private Metrics mLinkLayerMetrics = new Metrics(Metrics.LATENCY_UNKNOWN, private Metrics mLinkLayerMetrics = new Metrics(Metrics.LATENCY_UNKNOWN,
Metrics.BANDWIDTH_UNKNOWN, Metrics.BANDWIDTH_UNKNOWN); Metrics.BANDWIDTH_UNKNOWN, Metrics.BANDWIDTH_UNKNOWN);
@NonNull @NonNull
private Metrics mEndToEndMetrics = new Metrics(Metrics.LATENCY_UNKNOWN, private Metrics mEndToMetrics = new Metrics(Metrics.LATENCY_UNKNOWN,
Metrics.BANDWIDTH_UNKNOWN, Metrics.BANDWIDTH_UNKNOWN); Metrics.BANDWIDTH_UNKNOWN, Metrics.BANDWIDTH_UNKNOWN);
private int mSignalStrength = UNKNOWN_SIGNAL_STRENGTH; private int mSignalStrength = UNKNOWN_SIGNAL_STRENGTH;
private int mRange = RANGE_UNKNOWN; private int mRange = RANGE_UNKNOWN;
private boolean mExiting = false; private boolean mExiting = false;
private int mLegacyScore = 0; private int mLegacyScore = 0;
@NonNull private Bundle mExtensions = new Bundle();
/** Create a new builder. */ /** Create a new builder. */
public Builder() { } public Builder() { }
/** @hide */
public Builder(@NonNull final NetworkScore source) {
mPolicy = source.mPolicy;
mLinkLayerMetrics = source.mLinkLayerMetrics;
mEndToEndMetrics = source.mEndToEndMetrics;
mSignalStrength = source.mSignalStrength;
mRange = source.mRange;
mExiting = source.mExiting;
mLegacyScore = source.mLegacyScore;
}
/** Add a policy flag. */ /** Add a policy flag. */
@NonNull public Builder addPolicy(@Policy final int policy) { @NonNull public Builder addPolicy(@Policy final int policy) {
mPolicy |= policy; mPolicy |= policy;
@@ -480,7 +385,7 @@ public final class NetworkScore implements Parcelable {
/** Set the end-to-end metrics. */ /** Set the end-to-end metrics. */
@NonNull public Builder setEndToEndMetrics(@NonNull final Metrics endToEndMetrics) { @NonNull public Builder setEndToEndMetrics(@NonNull final Metrics endToEndMetrics) {
mEndToEndMetrics = endToEndMetrics; mEndToMetrics = endToEndMetrics;
return this; return this;
} }
@@ -512,7 +417,7 @@ public final class NetworkScore implements Parcelable {
/** Build the NetworkScore object represented by this builder. */ /** Build the NetworkScore object represented by this builder. */
@NonNull public NetworkScore build() { @NonNull public NetworkScore build() {
return new NetworkScore(mPolicy, mLinkLayerMetrics, mEndToEndMetrics, return new NetworkScore(mPolicy, mLinkLayerMetrics, mEndToMetrics,
mSignalStrength, mRange, mExiting, mLegacyScore); mSignalStrength, mRange, mExiting, mLegacyScore);
} }
} }

View File

@@ -3302,7 +3302,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
for (int i = 0; i < nai.numNetworkRequests(); i++) { for (int i = 0; i < nai.numNetworkRequests(); i++) {
NetworkRequest request = nai.requestAt(i); NetworkRequest request = nai.requestAt(i);
final NetworkRequestInfo nri = mNetworkRequests.get(request); final NetworkRequestInfo nri = mNetworkRequests.get(request);
ensureRunningOnConnectivityServiceThread();
final NetworkAgentInfo currentNetwork = nri.mSatisfier; final NetworkAgentInfo currentNetwork = nri.mSatisfier;
if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) { if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
nri.mSatisfier = null; nri.mSatisfier = null;
@@ -3454,18 +3453,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
// If this Network is already the highest scoring Network for a request, or if // If this Network is already the highest scoring Network for a request, or if
// there is hope for it to become one if it validated, then it is needed. // there is hope for it to become one if it validated, then it is needed.
ensureRunningOnConnectivityServiceThread();
if (nri.request.isRequest() && nai.satisfies(nri.request) && if (nri.request.isRequest() && nai.satisfies(nri.request) &&
(nai.isSatisfyingRequest(nri.request.requestId) (nai.isSatisfyingRequest(nri.request.requestId) ||
// Note that canPossiblyBeat catches two important cases: // Note that this catches two important cases:
// 1. Unvalidated slow networks will not be reaped when an unvalidated fast // 1. Unvalidated cellular will not be reaped when unvalidated WiFi
// network is currently satisfying the request. This is desirable for example // is currently satisfying the request. This is desirable when
// when cellular ends up validating but WiFi/Ethernet does not. // cellular ends up validating but WiFi does not.
// 2. Fast networks will not be reaped when a validated slow network is // 2. Unvalidated WiFi will not be reaped when validated cellular
// currently satisfying the request. This is desirable for example when // is currently satisfying the request. This is desirable when
// Ethernet ends up validating and out scoring WiFi, or WiFi/Ethernet ends // WiFi ends up validating and out scoring cellular.
// up validating and out scoring cellular. nri.mSatisfier.getCurrentScore()
|| nai.canPossiblyBeat(nri.mSatisfier))) { < nai.getCurrentScoreAsValidated())) {
return false; return false;
} }
} }
@@ -3493,7 +3491,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (mNetworkRequests.get(nri.request) == null) { if (mNetworkRequests.get(nri.request) == null) {
return; return;
} }
ensureRunningOnConnectivityServiceThread();
if (nri.mSatisfier != null) { if (nri.mSatisfier != null) {
return; return;
} }
@@ -3531,7 +3528,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
mNetworkRequestInfoLogs.log("RELEASE " + nri); mNetworkRequestInfoLogs.log("RELEASE " + nri);
if (nri.request.isRequest()) { if (nri.request.isRequest()) {
boolean wasKept = false; boolean wasKept = false;
ensureRunningOnConnectivityServiceThread();
final NetworkAgentInfo nai = nri.mSatisfier; final NetworkAgentInfo nai = nri.mSatisfier;
if (nai != null) { if (nai != null) {
boolean wasBackgroundNetwork = nai.isBackgroundNetwork(); boolean wasBackgroundNetwork = nai.isBackgroundNetwork();
@@ -3843,9 +3839,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
return avoidBadWifi(); return avoidBadWifi();
} }
private void rematchForAvoidBadWifiUpdate() { private void rematchForAvoidBadWifiUpdate() {
ensureRunningOnConnectivityServiceThread();
mixInAllNetworkScores();
rematchAllNetworksAndRequests(); rematchAllNetworksAndRequests();
for (NetworkAgentInfo nai: mNetworkAgentInfos.values()) { for (NetworkAgentInfo nai: mNetworkAgentInfos.values()) {
if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
@@ -7071,45 +7066,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
} }
/**
* Re-mixin all network scores.
* This is called when some global setting like avoidBadWifi has changed.
* TODO : remove this when all usages have been removed.
*/
private void mixInAllNetworkScores() {
ensureRunningOnConnectivityServiceThread();
for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
nai.setNetworkScore(mixInNetworkScore(nai, nai.getNetworkScore()));
}
}
/**
* Mix in the Connectivity-managed parts of the NetworkScore.
* @param nai The NAI this score applies to.
* @param sourceScore the score sent by the network agent, or the previous score of this NAI.
* @return A new score with the Connectivity-managed parts mixed in.
*/
@NonNull
private NetworkScore mixInNetworkScore(@NonNull final NetworkAgentInfo nai,
@NonNull final NetworkScore sourceScore) {
final NetworkScore.Builder score = new NetworkScore.Builder(sourceScore);
// TODO : this should be done in Telephony. It should be handled per-network because
// it's a carrier-dependent config.
if (nai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
if (mMultinetworkPolicyTracker.getAvoidBadWifi()) {
score.clearPolicy(NetworkScore.POLICY_IGNORE_ON_WIFI);
} else {
score.addPolicy(NetworkScore.POLICY_IGNORE_ON_WIFI);
}
}
return score.build();
}
private void updateNetworkScore(NetworkAgentInfo nai, NetworkScore ns) { private void updateNetworkScore(NetworkAgentInfo nai, NetworkScore ns) {
if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + ns); if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + ns);
nai.setNetworkScore(mixInNetworkScore(nai, ns)); nai.setNetworkScore(ns);
rematchAllNetworksAndRequests(); rematchAllNetworksAndRequests();
sendUpdatedScoreToFactories(nai); sendUpdatedScoreToFactories(nai);
} }

View File

@@ -16,8 +16,6 @@
package com.android.server.connectivity; package com.android.server.connectivity;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.transportNamesOf; import static android.net.NetworkCapabilities.transportNamesOf;
import android.annotation.NonNull; import android.annotation.NonNull;
@@ -477,16 +475,24 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN); return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
} }
/** Gets the current score */ private int getCurrentScore(boolean pretendValidated) {
public int getCurrentScore() { // TODO: We may want to refactor this into a NetworkScore class that takes a base score from
// the NetworkAgent and signals from the NetworkAgent and uses those signals to modify the
// score. The NetworkScore class would provide a nice place to centralize score constants
// so they are not scattered about the transports.
// If this network is explicitly selected and the user has decided to use it even if it's // If this network is explicitly selected and the user has decided to use it even if it's
// unvalidated, give it the maximum score. // unvalidated, give it the maximum score. Also give it the maximum score if it's explicitly
if (networkAgentConfig.explicitlySelected && networkAgentConfig.acceptUnvalidated) { // selected and we're trying to see what its score could be. This ensures that we don't tear
// down an explicitly selected network before the user gets a chance to prefer it when
// a higher-scoring network (e.g., Ethernet) is available.
if (networkAgentConfig.explicitlySelected
&& (networkAgentConfig.acceptUnvalidated || pretendValidated)) {
return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE; return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE;
} }
int score = mNetworkScore.getLegacyScore(); int score = mNetworkScore.getLegacyScore();
if (!lastValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) { if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) {
score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY; score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY;
} }
if (score < 0) score = 0; if (score < 0) score = 0;
@@ -502,6 +508,18 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
return isWifi && !avoidBadWifi && everValidated; return isWifi && !avoidBadWifi && everValidated;
} }
// Get the current score for this Network. This may be modified from what the
// NetworkAgent sent, as it has modifiers applied to it.
public int getCurrentScore() {
return getCurrentScore(false);
}
// Get the current score for this Network as if it was validated. This may be modified from
// what the NetworkAgent sent, as it has modifiers applied to it.
public int getCurrentScoreAsValidated() {
return getCurrentScore(true);
}
public void setNetworkScore(@NonNull NetworkScore ns) { public void setNetworkScore(@NonNull NetworkScore ns) {
mNetworkScore = ns; mNetworkScore = ns;
} }
@@ -611,41 +629,6 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
mLingering = false; mLingering = false;
} }
/**
* Returns whether this NAI has any chance of ever beating this other agent.
*
* The chief use case of this is the decision to tear down this network. ConnectivityService
* tears down networks that don't satisfy any request, unless they have a chance to beat any
* existing satisfier.
*
* @param other the agent to beat
* @return whether this should be given more time to try and beat the other agent
* TODO : remove this and migrate to a ranker-based approach
*/
public boolean canPossiblyBeat(@NonNull final NetworkAgentInfo other) {
// Any explicitly selected network should be held on.
if (networkAgentConfig.explicitlySelected) return true;
// An outscored exiting network should be torn down.
if (mNetworkScore.isExiting()) return false;
// If this network is validated it can be torn down as it can't hope to be better than
// it already is.
if (networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) return false;
// If neither network is validated, keep both until at least one does.
if (!other.networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) return true;
// If this network is not metered but the other is, it should be preferable if it validates.
if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)
&& !other.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
return true;
}
// If the control comes here :
// • This network is neither exiting or explicitly selected
// • This network is not validated, but the other is
// • This network is metered, or both networks are unmetered
// Keep it if it's expected to be faster than the other., should it validate.
return mNetworkScore.probablyFasterThan(other.mNetworkScore);
}
public void dumpLingerTimers(PrintWriter pw) { public void dumpLingerTimers(PrintWriter pw) {
for (LingerTimer timer : mLingerTimers) { pw.println(timer); } for (LingerTimer timer : mLingerTimers) { pw.println(timer); }
} }

View File

@@ -16,19 +16,10 @@
package com.android.server.connectivity; package com.android.server.connectivity;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkScore.POLICY_IGNORE_ON_WIFI;
import static com.android.internal.util.FunctionalUtils.findFirst;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest; import android.net.NetworkRequest;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
/** /**
@@ -40,75 +31,20 @@ public class NetworkRanker {
/** /**
* Find the best network satisfying this request among the list of passed networks. * Find the best network satisfying this request among the list of passed networks.
*/ */
// Almost equivalent to Collections.max(nais), but allows returning null if no network
// satisfies the request.
@Nullable @Nullable
public NetworkAgentInfo getBestNetwork(@NonNull final NetworkRequest request, public NetworkAgentInfo getBestNetwork(@NonNull final NetworkRequest request,
@NonNull final Collection<NetworkAgentInfo> nais) { @NonNull final Collection<NetworkAgentInfo> nais) {
final ArrayList<NetworkAgentInfo> candidates = new ArrayList<>(nais);
candidates.removeIf(nai -> !nai.satisfies(request));
// Enforce policy. The order in which the policy is computed is essential, because each
// step may remove some of the candidates. For example, filterValidated drops non-validated
// networks in presence of validated networks for INTERNET requests, but the bad wifi
// avoidance policy takes priority over this, so it must be done before.
filterVpn(candidates);
filterExplicitlySelected(candidates);
filterBadWifiAvoidance(candidates);
filterValidated(request, candidates);
NetworkAgentInfo bestNetwork = null; NetworkAgentInfo bestNetwork = null;
int bestScore = Integer.MIN_VALUE; int bestScore = Integer.MIN_VALUE;
for (final NetworkAgentInfo nai : candidates) { for (final NetworkAgentInfo nai : nais) {
final int score = nai.getNetworkScore().getLegacyScore(); if (!nai.satisfies(request)) continue;
if (score > bestScore) { if (nai.getCurrentScore() > bestScore) {
bestNetwork = nai; bestNetwork = nai;
bestScore = score; bestScore = nai.getCurrentScore();
} }
} }
return bestNetwork; return bestNetwork;
} }
// If a network is a VPN it has priority.
private void filterVpn(@NonNull final ArrayList<NetworkAgentInfo> candidates) {
final NetworkAgentInfo vpn = findFirst(candidates,
nai -> nai.networkCapabilities.hasTransport(TRANSPORT_VPN));
if (null == vpn) return; // No VPN : this policy doesn't apply.
candidates.removeIf(nai -> !nai.networkCapabilities.hasTransport(TRANSPORT_VPN));
}
// If some network is explicitly selected and set to accept unvalidated connectivity, then
// drop all networks that are not explicitly selected.
private void filterExplicitlySelected(
@NonNull final ArrayList<NetworkAgentInfo> candidates) {
final NetworkAgentInfo explicitlySelected = findFirst(candidates,
nai -> nai.networkAgentConfig.explicitlySelected
&& nai.networkAgentConfig.acceptUnvalidated);
if (null == explicitlySelected) return; // No explicitly selected network accepting unvalid
candidates.removeIf(nai -> !nai.networkAgentConfig.explicitlySelected);
}
// If some network with wifi transport is present, drop all networks with POLICY_IGNORE_ON_WIFI.
private void filterBadWifiAvoidance(@NonNull final ArrayList<NetworkAgentInfo> candidates) {
final NetworkAgentInfo wifi = findFirst(candidates,
nai -> nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
&& nai.everValidated
// Horrible hack : there is old UI that will let a user say they want to
// override the policy only for this network only at this time and it
// feeds into the following member. This old UI should probably be removed
// but for now keep backward compatibility.
&& !nai.avoidUnvalidated);
if (null == wifi) return; // No wifi : this policy doesn't apply
candidates.removeIf(nai -> nai.getNetworkScore().hasPolicy(POLICY_IGNORE_ON_WIFI));
}
// If some network is validated and the request asks for INTERNET, drop all networks that are
// not validated.
private void filterValidated(@NonNull final NetworkRequest request,
@NonNull final ArrayList<NetworkAgentInfo> candidates) {
if (!request.hasCapability(NET_CAPABILITY_INTERNET)) return;
final NetworkAgentInfo validated = findFirst(candidates,
nai -> nai.networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED));
if (null == validated) return; // No validated network
candidates.removeIf(nai ->
!nai.networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED));
}
} }

View File

@@ -2058,15 +2058,14 @@ public class ConnectivityServiceTest {
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
// Bring up validated wifi. // Bring up wifi with a score of 70.
// Cell is lingered because it would not satisfy any request, even if it validated. // Cell is lingered because it would not satisfy any request, even if it validated.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(true); // Score: 60 mWiFiNetworkAgent.adjustScore(50);
mWiFiNetworkAgent.connect(false); // Score: 70
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
// TODO: Investigate sending validated before losing.
callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent); callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork()); assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -5850,7 +5849,7 @@ public class ConnectivityServiceTest {
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(true); mWiFiNetworkAgent.connect(true);
trustedCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent); trustedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
verify(mNetworkManagementService).setDefaultNetId(eq(mWiFiNetworkAgent.getNetwork().netId)); verify(mNetworkManagementService).setDefaultNetId(eq(mWiFiNetworkAgent.getNetwork().netId));
reset(mNetworkManagementService); reset(mNetworkManagementService);

View File

@@ -16,18 +16,13 @@
package com.android.server.connectivity package com.android.server.connectivity
import android.net.ConnectivityManager.TYPE_WIFI
import android.net.LinkProperties
import android.net.Network
import android.net.NetworkAgentConfig
import android.net.NetworkCapabilities
import android.net.NetworkInfo
import android.net.NetworkRequest import android.net.NetworkRequest
import android.net.NetworkScore
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4 import androidx.test.runner.AndroidJUnit4
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.any
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock import org.mockito.Mockito.mock
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertNull import kotlin.test.assertNull
@@ -37,24 +32,9 @@ import kotlin.test.assertNull
class NetworkRankerTest { class NetworkRankerTest {
private val ranker = NetworkRanker() private val ranker = NetworkRanker()
private fun makeNai(satisfy: Boolean, score: Int) = object : NetworkAgentInfo( private fun makeNai(satisfy: Boolean, score: Int) = mock(NetworkAgentInfo::class.java).also {
null /* messenger */, doReturn(satisfy).`when`(it).satisfies(any())
null /* asyncChannel*/, doReturn(score).`when`(it).currentScore
Network(100),
NetworkInfo(TYPE_WIFI, 0 /* subtype */, "" /* typename */, "" /* subtypename */),
LinkProperties(),
NetworkCapabilities(),
NetworkScore.Builder().setLegacyScore(score).build(),
null /* context */,
null /* handler */,
NetworkAgentConfig(),
null /* connectivityService */,
null /* netd */,
null /* dnsResolver */,
null /* networkManagementService */,
0 /* factorySerialNumber */) {
override fun satisfies(request: NetworkRequest?): Boolean = satisfy
override fun getCurrentScore(): Int = score
} }
@Test @Test