[NS10] Fix a bug where registerIgnoringScore is broken
Fixes: 184028345
Test: ConnectivityServiceTest
Merged-In: I3c2563d4ae4e3715d0c6270344ba8f7ef067872f
Merged-In: Ib5cd2c27a2bd0f53b500e8edbe48126fbf58f34d
Change-Id: Ib5cd2c27a2bd0f53b500e8edbe48126fbf58f34d
(cherry-picked from ag/14034625)
diff --git a/service/src/com/android/server/connectivity/FullScore.java b/service/src/com/android/server/connectivity/FullScore.java
index 6e38e2d..a8a83fc 100644
--- a/service/src/com/android/server/connectivity/FullScore.java
+++ b/service/src/com/android/server/connectivity/FullScore.java
@@ -86,9 +86,14 @@
/** @hide */
public static final int POLICY_IS_UNMETERED = 59;
+ // This network is invincible. This is useful for offers until there is an API to listen
+ // to requests.
+ /** @hide */
+ public static final int POLICY_IS_INVINCIBLE = 58;
+
// To help iterate when printing
@VisibleForTesting
- static final int MIN_CS_MANAGED_POLICY = POLICY_IS_UNMETERED;
+ static final int MIN_CS_MANAGED_POLICY = POLICY_IS_INVINCIBLE;
@VisibleForTesting
static final int MAX_CS_MANAGED_POLICY = POLICY_IS_VALIDATED;
@@ -109,6 +114,7 @@
case POLICY_YIELD_TO_BAD_WIFI: return "YIELD_TO_BAD_WIFI";
case POLICY_TRANSPORT_PRIMARY: return "TRANSPORT_PRIMARY";
case POLICY_EXITING: return "EXITING";
+ case POLICY_IS_INVINCIBLE: return "INVINCIBLE";
}
throw new IllegalArgumentException("Unknown policy : " + policy);
}
@@ -147,7 +153,8 @@
caps.hasCapability(NET_CAPABILITY_NOT_METERED),
config.explicitlySelected,
config.acceptUnvalidated,
- yieldToBadWiFi);
+ yieldToBadWiFi,
+ false /* invincible */); // only prospective scores can be invincible
}
/**
@@ -178,8 +185,12 @@
final boolean acceptUnvalidated = false;
// Don't assume clinging to bad wifi
final boolean yieldToBadWiFi = false;
+ // A prospective score is invincible if the legacy int in the filter is over the maximum
+ // score.
+ final boolean invincible = score.getLegacyInt() > NetworkRanker.LEGACY_INT_MAX;
return withPolicies(score.getLegacyInt(), score.getPolicies(), KEEP_CONNECTED_NONE,
- mayValidate, vpn, unmetered, everUserSelected, acceptUnvalidated, yieldToBadWiFi);
+ mayValidate, vpn, unmetered, everUserSelected, acceptUnvalidated, yieldToBadWiFi,
+ invincible);
}
/**
@@ -200,7 +211,8 @@
caps.hasCapability(NET_CAPABILITY_NOT_METERED),
config.explicitlySelected,
config.acceptUnvalidated,
- yieldToBadWifi);
+ yieldToBadWifi,
+ false /* invincible */); // only prospective scores can be invincible
}
// TODO : this shouldn't manage bad wifi avoidance – instead this should be done by the
@@ -214,14 +226,16 @@
final boolean isUnmetered,
final boolean everUserSelected,
final boolean acceptUnvalidated,
- final boolean yieldToBadWiFi) {
+ final boolean yieldToBadWiFi,
+ final boolean invincible) {
return new FullScore(legacyInt, (externalPolicies & EXTERNAL_POLICIES_MASK)
| (isValidated ? 1L << POLICY_IS_VALIDATED : 0)
| (isVpn ? 1L << POLICY_IS_VPN : 0)
| (isUnmetered ? 1L << POLICY_IS_UNMETERED : 0)
| (everUserSelected ? 1L << POLICY_EVER_USER_SELECTED : 0)
| (acceptUnvalidated ? 1L << POLICY_ACCEPT_UNVALIDATED : 0)
- | (yieldToBadWiFi ? 1L << POLICY_YIELD_TO_BAD_WIFI : 0),
+ | (yieldToBadWiFi ? 1L << POLICY_YIELD_TO_BAD_WIFI : 0)
+ | (invincible ? 1L << POLICY_IS_INVINCIBLE : 0),
keepConnectedReason);
}
diff --git a/service/src/com/android/server/connectivity/NetworkRanker.java b/service/src/com/android/server/connectivity/NetworkRanker.java
index 698744a..3aaff59 100644
--- a/service/src/com/android/server/connectivity/NetworkRanker.java
+++ b/service/src/com/android/server/connectivity/NetworkRanker.java
@@ -26,6 +26,7 @@
import static com.android.server.connectivity.FullScore.POLICY_ACCEPT_UNVALIDATED;
import static com.android.server.connectivity.FullScore.POLICY_EVER_USER_SELECTED;
+import static com.android.server.connectivity.FullScore.POLICY_IS_INVINCIBLE;
import static com.android.server.connectivity.FullScore.POLICY_IS_VALIDATED;
import static com.android.server.connectivity.FullScore.POLICY_IS_VPN;
@@ -46,6 +47,10 @@
* A class that knows how to find the best network matching a request out of a list of networks.
*/
public class NetworkRanker {
+ // Historically the legacy ints have been 0~100 in principle (though the highest score in
+ // AOSP has always been 90). This is relied on by VPNs that send a legacy score of 101.
+ public static final int LEGACY_INT_MAX = 100;
+
/**
* A class that can be scored against other scoreables.
*/
@@ -72,7 +77,6 @@
return matches;
}
-
/**
* Find the best network satisfying this request among the list of passed networks.
*/
@@ -134,6 +138,12 @@
// 4. if none remain, the criterion did not help discriminate so keep them all. As an
// optimization, skip creating a new array and go on to the next criterion.
+ // If a network is invincible, use it.
+ partitionInto(candidates, nai -> nai.getScore().hasPolicy(POLICY_IS_INVINCIBLE),
+ accepted, rejected);
+ if (accepted.size() == 1) return accepted.get(0);
+ if (accepted.size() > 0 && rejected.size() > 0) candidates = new ArrayList<>(accepted);
+
// If there is a connected VPN, use it.
partitionInto(candidates, nai -> nai.getScore().hasPolicy(POLICY_IS_VPN),
accepted, rejected);
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index a42adbd..072d304 100644
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -3205,7 +3205,6 @@
// Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed.
}
- @Ignore("Refactoring in progress b/184028345")
@Test
public void testRegisterIgnoringScore() throws Exception {
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);