Prioritize non-slices over slices
For general internet access, a specialized slice is generally not preferable to a non-specialized network. Test: new test in this patch Change-Id: I052ce923300566807999b2f20f5911181fb761dd
This commit is contained in:
@@ -17,6 +17,8 @@
|
|||||||
package com.android.server.connectivity;
|
package com.android.server.connectivity;
|
||||||
|
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
|
||||||
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH;
|
||||||
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
|
import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
|
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
|
||||||
@@ -220,6 +222,19 @@ public class NetworkRanker {
|
|||||||
accepted, rejected);
|
accepted, rejected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the scorable has any of the PRIORITIZE_* capabilities.
|
||||||
|
*
|
||||||
|
* These capabilities code for customer slices, and a network that has one is a customer slice.
|
||||||
|
*/
|
||||||
|
private boolean hasPrioritizedCapability(@NonNull final Scoreable nai) {
|
||||||
|
final NetworkCapabilities caps = nai.getCapsNoCopy();
|
||||||
|
final long anyPrioritizeCapability =
|
||||||
|
(1L << NET_CAPABILITY_PRIORITIZE_LATENCY)
|
||||||
|
| (1L << NET_CAPABILITY_PRIORITIZE_BANDWIDTH);
|
||||||
|
return 0 != (caps.getCapabilitiesInternal() & anyPrioritizeCapability);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the best network among a list of candidates according to policy.
|
* Get the best network among a list of candidates according to policy.
|
||||||
* @param candidates the candidates
|
* @param candidates the candidates
|
||||||
@@ -324,6 +339,12 @@ public class NetworkRanker {
|
|||||||
// change from the previous result. If there were, it's guaranteed candidates.size() > 0
|
// change from the previous result. If there were, it's guaranteed candidates.size() > 0
|
||||||
// because accepted.size() > 0 above.
|
// because accepted.size() > 0 above.
|
||||||
|
|
||||||
|
// If any network is not a slice with prioritized bandwidth or latency, don't choose one
|
||||||
|
// that is.
|
||||||
|
partitionInto(candidates, nai -> !hasPrioritizedCapability(nai), accepted, rejected);
|
||||||
|
if (accepted.size() == 1) return accepted.get(0);
|
||||||
|
if (accepted.size() > 0 && rejected.size() > 0) candidates = new ArrayList<>(accepted);
|
||||||
|
|
||||||
// If some of the networks have a better transport than others, keep only the ones with
|
// If some of the networks have a better transport than others, keep only the ones with
|
||||||
// the best transports.
|
// the best transports.
|
||||||
for (final int transport : PREFERRED_TRANSPORTS_ORDER) {
|
for (final int transport : PREFERRED_TRANSPORTS_ORDER) {
|
||||||
|
|||||||
@@ -18,9 +18,12 @@ package com.android.server.connectivity
|
|||||||
|
|
||||||
import android.net.NetworkCapabilities
|
import android.net.NetworkCapabilities
|
||||||
import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL as NET_CAP_PORTAL
|
import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL as NET_CAP_PORTAL
|
||||||
|
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET as NET_CAP_INTERNET
|
||||||
|
import android.net.NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH as NET_CAP_PRIO_BW
|
||||||
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
|
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
|
||||||
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
||||||
import android.net.NetworkScore.KEEP_CONNECTED_NONE
|
import android.net.NetworkScore.KEEP_CONNECTED_NONE
|
||||||
|
import android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY
|
||||||
import android.net.NetworkScore.POLICY_EXITING as EXITING
|
import android.net.NetworkScore.POLICY_EXITING as EXITING
|
||||||
import android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY as PRIMARY
|
import android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY as PRIMARY
|
||||||
import android.net.NetworkScore.POLICY_YIELD_TO_BAD_WIFI as YIELD_TO_BAD_WIFI
|
import android.net.NetworkScore.POLICY_YIELD_TO_BAD_WIFI as YIELD_TO_BAD_WIFI
|
||||||
@@ -50,8 +53,8 @@ private fun caps(transport: Int, vararg capabilities: Int) =
|
|||||||
class NetworkRankerTest(private val activelyPreferBadWifi: Boolean) {
|
class NetworkRankerTest(private val activelyPreferBadWifi: Boolean) {
|
||||||
private val mRanker = NetworkRanker(NetworkRanker.Configuration(activelyPreferBadWifi))
|
private val mRanker = NetworkRanker(NetworkRanker.Configuration(activelyPreferBadWifi))
|
||||||
|
|
||||||
private class TestScore(private val sc: FullScore, private val nc: NetworkCapabilities)
|
private class TestScore(private val sc: FullScore, private val nc: NetworkCapabilities) :
|
||||||
: NetworkRanker.Scoreable {
|
NetworkRanker.Scoreable {
|
||||||
override fun getScore() = sc
|
override fun getScore() = sc
|
||||||
override fun getCapsNoCopy(): NetworkCapabilities = nc
|
override fun getCapsNoCopy(): NetworkCapabilities = nc
|
||||||
}
|
}
|
||||||
@@ -196,4 +199,41 @@ class NetworkRankerTest(private val activelyPreferBadWifi: Boolean) {
|
|||||||
val badExitingWifi = TestScore(score(EVER_EVALUATED, EVER_VALIDATED, EXITING), CAPS_WIFI)
|
val badExitingWifi = TestScore(score(EVER_EVALUATED, EVER_VALIDATED, EXITING), CAPS_WIFI)
|
||||||
assertEquals(cell, rank(cell, badExitingWifi))
|
assertEquals(cell, rank(cell, badExitingWifi))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testValidatedPolicyStrongerThanSlice() {
|
||||||
|
val unvalidatedNonslice = TestScore(score(EVER_EVALUATED),
|
||||||
|
caps(TRANSPORT_CELLULAR, NET_CAP_INTERNET))
|
||||||
|
val slice = TestScore(score(EVER_EVALUATED, IS_VALIDATED),
|
||||||
|
caps(TRANSPORT_CELLULAR, NET_CAP_INTERNET, NET_CAP_PRIO_BW))
|
||||||
|
assertEquals(slice, rank(slice, unvalidatedNonslice))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testPrimaryPolicyStrongerThanSlice() {
|
||||||
|
val nonslice = TestScore(score(EVER_EVALUATED),
|
||||||
|
caps(TRANSPORT_CELLULAR, NET_CAP_INTERNET))
|
||||||
|
val primarySlice = TestScore(score(EVER_EVALUATED, POLICY_TRANSPORT_PRIMARY),
|
||||||
|
caps(TRANSPORT_CELLULAR, NET_CAP_INTERNET, NET_CAP_PRIO_BW))
|
||||||
|
assertEquals(primarySlice, rank(nonslice, primarySlice))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testPreferNonSlices() {
|
||||||
|
// Slices lose to non-slices for general ranking
|
||||||
|
val nonslice = TestScore(score(EVER_EVALUATED, IS_VALIDATED),
|
||||||
|
caps(TRANSPORT_CELLULAR, NET_CAP_INTERNET))
|
||||||
|
val slice = TestScore(score(EVER_EVALUATED, IS_VALIDATED),
|
||||||
|
caps(TRANSPORT_CELLULAR, NET_CAP_INTERNET, NET_CAP_PRIO_BW))
|
||||||
|
assertEquals(nonslice, rank(slice, nonslice))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSlicePolicyStrongerThanTransport() {
|
||||||
|
val nonSliceCell = TestScore(score(EVER_EVALUATED, IS_VALIDATED),
|
||||||
|
caps(TRANSPORT_CELLULAR, NET_CAP_INTERNET))
|
||||||
|
val sliceWifi = TestScore(score(EVER_EVALUATED, IS_VALIDATED),
|
||||||
|
caps(TRANSPORT_WIFI, NET_CAP_INTERNET, NET_CAP_PRIO_BW))
|
||||||
|
assertEquals(nonSliceCell, rank(nonSliceCell, sliceWifi))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user