Loading packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading packages/Connectivity/framework/src/android/net/NetworkScore.java +14 −0 Original line number Diff line number Diff line Loading @@ -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. * Loading @@ -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; Loading @@ -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 + ")"; Loading services/core/java/com/android/server/ConnectivityService.java +4 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); } Loading services/core/java/com/android/server/connectivity/ConnectivityConstants.java +1 −9 Original line number Diff line number Diff line Loading @@ -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; Loading services/core/java/com/android/server/connectivity/FullScore.java +151 −8 Original line number Diff line number Diff line Loading @@ -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. * Loading @@ -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; Loading @@ -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)); } /** Loading @@ -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
packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
packages/Connectivity/framework/src/android/net/NetworkScore.java +14 −0 Original line number Diff line number Diff line Loading @@ -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. * Loading @@ -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; Loading @@ -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 + ")"; Loading
services/core/java/com/android/server/ConnectivityService.java +4 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); } Loading
services/core/java/com/android/server/connectivity/ConnectivityConstants.java +1 −9 Original line number Diff line number Diff line Loading @@ -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; Loading
services/core/java/com/android/server/connectivity/FullScore.java +151 −8 Original line number Diff line number Diff line Loading @@ -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. * Loading @@ -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; Loading @@ -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)); } /** Loading @@ -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(); } }