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

Commit e07e3856 authored by Chalard Jean's avatar Chalard Jean Committed by Gerrit Code Review
Browse files

Merge "[NS03] Mix in other CS-managed properties"

parents 46e3f182 395bde4d
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -50,7 +50,8 @@ public final class NetworkAgentConfig implements Parcelable {
     * ap in the wifi settings to trigger a connection is explicit.  A 3rd party app asking to
     * connect to a particular access point is also explicit, though this may change in the future
     * as we want apps to use the multinetwork apis.
     *
     * TODO : this is a bad name, because it sounds like the user just tapped on the network.
     * It's not necessarily the case ; auto-reconnection to WiFi has this true for example.
     * @hide
     */
    public boolean explicitlySelected;
+14 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.annotations.VisibleForTesting;

/**
 * Object representing the quality of a network as perceived by the user.
 *
@@ -35,6 +37,10 @@ public final class NetworkScore implements Parcelable {

    // Agent-managed policies
    // TODO : add them here, starting from 1
    /** @hide */
    public static final int MIN_AGENT_MANAGED_POLICY = 0;
    /** @hide */
    public static final int MAX_AGENT_MANAGED_POLICY = -1;

    // Bitmask of all the policies applied to this score.
    private final long mPolicies;
@@ -54,6 +60,14 @@ public final class NetworkScore implements Parcelable {
        return mLegacyInt;
    }

    /**
     * @return whether this score has a particular policy.
     */
    @VisibleForTesting
    public boolean hasPolicy(final int policy) {
        return 0 != (mPolicies & (1L << policy));
    }

    @Override
    public String toString() {
        return "Score(" + mLegacyInt + ")";
+4 −0
Original line number Diff line number Diff line
@@ -2961,6 +2961,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
                case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
                    if (nai.everConnected) {
                        loge("ERROR: cannot call explicitlySelected on already-connected network");
                        // Note that if the NAI had been connected, this would affect the
                        // score, and therefore would require re-mixing the score and performing
                        // a rematch.
                    }
                    nai.networkAgentConfig.explicitlySelected = toBool(msg.arg1);
                    nai.networkAgentConfig.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2);
@@ -4045,6 +4048,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
            // network, we should respect the user's option and don't need to popup the
            // PARTIAL_CONNECTIVITY notification to user again.
            nai.networkAgentConfig.acceptPartialConnectivity = accept;
            nai.updateScoreForNetworkAgentConfigUpdate();
            rematchAllNetworksAndRequests();
            sendUpdatedScoreToFactories(nai);
        }
+1 −9
Original line number Diff line number Diff line
@@ -18,18 +18,10 @@ package com.android.server.connectivity;

/**
 * A class encapsulating various constants used by Connectivity.
 * TODO : remove this class.
 * @hide
 */
public class ConnectivityConstants {

    // Penalty applied to scores of Networks that have not been validated.
    public static final int UNVALIDATED_SCORE_PENALTY = 40;

    // Score for explicitly connected network.
    //
    // This ensures that a) the explicitly selected network is never trumped by anything else, and
    // b) the explicitly selected network is never torn down.
    public static final int EXPLICITLY_SELECTED_NETWORK_SCORE = 100;
    // VPNs typically have priority over other networks. Give them a score that will
    // let them win every single time.
    public static final int VPN_DEFAULT_SCORE = 101;
+151 −8
Original line number Diff line number Diff line
@@ -16,9 +16,21 @@

package com.android.server.connectivity;

import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkScore;

import com.android.internal.annotations.VisibleForTesting;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.StringJoiner;

/**
 * This class represents how desirable a network is.
 *
@@ -31,11 +43,54 @@ public class FullScore {
    // a migration.
    private final int mLegacyInt;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"POLICY_"}, value = {
            POLICY_IS_VALIDATED,
            POLICY_IS_VPN,
            POLICY_EVER_USER_SELECTED,
            POLICY_ACCEPT_UNVALIDATED
    })
    public @interface Policy {
    }

    // Agent-managed policies are in NetworkScore. They start from 1.
    // CS-managed policies
    // CS-managed policies, counting from 63 downward
    // This network is validated. CS-managed because the source of truth is in NetworkCapabilities.
    /** @hide */
    public static final int POLICY_IS_VALIDATED = 63;

    // This is a VPN and behaves as one for scoring purposes.
    /** @hide */
    public static final int POLICY_IS_VPN = 62;

    // This network has been selected by the user manually from settings or a 3rd party app
    // at least once. {@see NetworkAgentConfig#explicitlySelected}.
    /** @hide */
    public static final int POLICY_EVER_USER_SELECTED = 61;

    // The user has indicated in UI that this network should be used even if it doesn't
    // validate. {@see NetworkAgentConfig#acceptUnvalidated}.
    /** @hide */
    public static final int POLICY_ACCEPT_UNVALIDATED = 60;

    // To help iterate when printing
    @VisibleForTesting
    static final int MIN_CS_MANAGED_POLICY = POLICY_ACCEPT_UNVALIDATED;
    @VisibleForTesting
    static final int MAX_CS_MANAGED_POLICY = POLICY_IS_VALIDATED;

    @VisibleForTesting
    static @NonNull String policyNameOf(final int policy) {
        switch (policy) {
            case POLICY_IS_VALIDATED: return "IS_VALIDATED";
            case POLICY_IS_VPN: return "IS_VPN";
            case POLICY_EVER_USER_SELECTED: return "EVER_USER_SELECTED";
            case POLICY_ACCEPT_UNVALIDATED: return "ACCEPT_UNVALIDATED";
        }
        throw new IllegalArgumentException("Unknown policy : " + policy);
    }

    // Bitmask of all the policies applied to this score.
    private final long mPolicies;

@@ -45,12 +100,46 @@ public class FullScore {
    }

    /**
     * Make a FullScore from a NetworkScore
     * Given a score supplied by the NetworkAgent and CS-managed objects, produce a full score.
     *
     * @param score the score supplied by the agent
     * @param caps the NetworkCapabilities of the network
     * @param config the NetworkAgentConfig of the network
     * @return an FullScore that is appropriate to use for ranking.
     */
    public static FullScore withPolicy(@NonNull final NetworkScore originalScore,
            final boolean isValidated) {
        return new FullScore(originalScore.getLegacyInt(),
                isValidated ? 1L << POLICY_IS_VALIDATED : 0L);
    public static FullScore fromNetworkScore(@NonNull final NetworkScore score,
            @NonNull final NetworkCapabilities caps, @NonNull final NetworkAgentConfig config) {
        return withPolicies(score.getLegacyInt(), caps.hasCapability(NET_CAPABILITY_VALIDATED),
                caps.hasTransport(TRANSPORT_VPN),
                config.explicitlySelected,
                config.acceptUnvalidated);
    }

    /**
     * Return a new score given updated caps and config.
     *
     * @param caps the NetworkCapabilities of the network
     * @param config the NetworkAgentConfig of the network
     * @return a score with the policies from the arguments reset
     */
    public FullScore mixInScore(@NonNull final NetworkCapabilities caps,
            @NonNull final NetworkAgentConfig config) {
        return withPolicies(mLegacyInt, caps.hasCapability(NET_CAPABILITY_VALIDATED),
                caps.hasTransport(TRANSPORT_VPN),
                config.explicitlySelected,
                config.acceptUnvalidated);
    }

    private static FullScore withPolicies(@NonNull final int legacyInt,
            final boolean isValidated,
            final boolean isVpn,
            final boolean everUserSelected,
            final boolean acceptUnvalidated) {
        return new FullScore(legacyInt,
                (isValidated         ? 1L << POLICY_IS_VALIDATED : 0)
                | (isVpn             ? 1L << POLICY_IS_VPN : 0)
                | (everUserSelected  ? 1L << POLICY_EVER_USER_SELECTED : 0)
                | (acceptUnvalidated ? 1L << POLICY_ACCEPT_UNVALIDATED : 0));
    }

    /**
@@ -58,11 +147,65 @@ public class FullScore {
     * This will be removed before S is published.
     */
    public int getLegacyInt() {
        return mLegacyInt;
        return getLegacyInt(false /* pretendValidated */);
    }

    public int getLegacyIntAsValidated() {
        return getLegacyInt(true /* pretendValidated */);
    }

    // TODO : remove these two constants
    // Penalty applied to scores of Networks that have not been validated.
    private static final int UNVALIDATED_SCORE_PENALTY = 40;

    // Score for a network that can be used unvalidated
    private static final int ACCEPT_UNVALIDATED_NETWORK_SCORE = 100;

    private int getLegacyInt(boolean pretendValidated) {
        // If the user has chosen this network at least once, give it the maximum score when
        // checking to pretend it's validated, or if it doesn't need to validate because the
        // user said to use it even if it doesn't validate.
        // This ensures that networks that have been selected in UI are not torn down before the
        // user gets a chance to prefer it when a higher-scoring network (e.g., Ethernet) is
        // available.
        if (hasPolicy(POLICY_EVER_USER_SELECTED)
                && (hasPolicy(POLICY_ACCEPT_UNVALIDATED) || pretendValidated)) {
            return ACCEPT_UNVALIDATED_NETWORK_SCORE;
        }

        int score = mLegacyInt;
        // Except for VPNs, networks are subject to a penalty for not being validated.
        // Apply the penalty unless the network is a VPN, or it's validated or pretending to be.
        if (!hasPolicy(POLICY_IS_VALIDATED) && !pretendValidated && !hasPolicy(POLICY_IS_VPN)) {
            score -= UNVALIDATED_SCORE_PENALTY;
        }
        if (score < 0) score = 0;
        return score;
    }

    /**
     * @return whether this score has a particular policy.
     */
    @VisibleForTesting
    public boolean hasPolicy(final int policy) {
        return 0 != (mPolicies & (1L << policy));
    }

    // Example output :
    // Score(50 ; Policies : EVER_USER_SELECTED&IS_VALIDATED)
    @Override
    public String toString() {
        return "Score(" + mLegacyInt + ")";
        final StringJoiner sj = new StringJoiner(
                "&", // delimiter
                "Score(" + mLegacyInt + " ; Policies : ", // prefix
                ")"); // suffix
        for (int i = NetworkScore.MIN_AGENT_MANAGED_POLICY;
                i <= NetworkScore.MAX_AGENT_MANAGED_POLICY; ++i) {
            if (hasPolicy(i)) sj.add(policyNameOf(i));
        }
        for (int i = MIN_CS_MANAGED_POLICY; i <= MAX_CS_MANAGED_POLICY; ++i) {
            if (hasPolicy(i)) sj.add(policyNameOf(i));
        }
        return sj.toString();
    }
}
Loading