Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9fd5a72 authored by Chalard Jean's avatar Chalard Jean
Browse files

[NS D06] Implement more policies

Namely :
• Explicitly selected policy
• VPN policy
• Validated policy

These go together to avoid breaking any test, because multiple
tests rely on all of these working.

Test: ConnectivityServiceTest

Change-Id: I7d815f87320c2becbfc93a60a3c54346ff4f47c9
parent ea0cf508
Loading
Loading
Loading
Loading
+44 −4
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

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;
@@ -42,8 +45,15 @@ public class NetworkRanker {
            @NonNull final Collection<NetworkAgentInfo> nais) {
        final ArrayList<NetworkAgentInfo> candidates = new ArrayList<>(nais);
        candidates.removeIf(nai -> !nai.satisfies(request));
        // Enforce policy.
        filterBadWifiAvoidancePolicy(candidates);

        // 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;
        int bestScore = Integer.MIN_VALUE;
@@ -57,9 +67,27 @@ public class NetworkRanker {
        return bestNetwork;
    }

    // If some network with wifi transport is present, drop all networks with POLICY_IGNORE_ON_WIFI.
    private void filterBadWifiAvoidancePolicy(
    // 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
@@ -71,4 +99,16 @@ public class NetworkRanker {
        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));
    }
}
+24 −4
Original line number Diff line number Diff line
@@ -16,8 +16,14 @@

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.NetworkScore
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
import org.junit.Test
@@ -33,10 +39,24 @@ import kotlin.test.assertNull
class NetworkRankerTest {
    private val ranker = NetworkRanker()

    private fun makeNai(satisfy: Boolean, score: Int) = mock(NetworkAgentInfo::class.java).also {
        doReturn(satisfy).`when`(it).satisfies(any())
        doReturn(score).`when`(it).currentScore
        it.networkCapabilities = NetworkCapabilities()
    private fun makeNai(satisfy: Boolean, score: Int) = object : NetworkAgentInfo(
            null /* messenger */,
            null /* asyncChannel*/,
            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