diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index ce9693d88a..fa12c08f22 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -3322,15 +3322,19 @@ public class ConnectivityManager { // of dependent changes that would conflict throughout the automerger graph. Having this // temporarily helps with the process of going through with all these dependent changes across // the entire tree. + // STOPSHIP (b/148055573) : remove this before R is released. /** * @hide * Register a NetworkAgent with ConnectivityService. * @return Network corresponding to NetworkAgent. + * @deprecated use the version that takes a NetworkScore and a provider ID. */ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) + @Deprecated public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp, NetworkCapabilities nc, int score, NetworkAgentConfig config) { - return registerNetworkAgent(messenger, ni, lp, nc, score, config, NetworkProvider.ID_NONE); + final NetworkScore ns = new NetworkScore.Builder().setLegacyScore(score).build(); + return registerNetworkAgent(messenger, ni, lp, nc, ns, config, NetworkProvider.ID_NONE); } /** @@ -3340,7 +3344,7 @@ public class ConnectivityManager { */ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp, - NetworkCapabilities nc, int score, NetworkAgentConfig config, int providerId) { + NetworkCapabilities nc, NetworkScore score, NetworkAgentConfig config, int providerId) { try { return mService.registerNetworkAgent(messenger, ni, lp, nc, score, config, providerId); } catch (RemoteException e) { diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 186196bd31..c58ffd5606 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -25,6 +25,7 @@ import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkQuotaInfo; import android.net.NetworkRequest; +import android.net.NetworkScore; import android.net.NetworkState; import android.net.ISocketKeepaliveCallback; import android.net.ProxyInfo; @@ -153,7 +154,7 @@ interface IConnectivityManager void declareNetworkRequestUnfulfillable(in NetworkRequest request); Network registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp, - in NetworkCapabilities nc, int score, in NetworkAgentConfig config, + in NetworkCapabilities nc, in NetworkScore score, in NetworkAgentConfig config, in int factorySerialNumber); NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index 7cc569a42b..ddf8dbbcb9 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -116,13 +116,6 @@ public abstract class NetworkAgent { */ public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3; - /** - * Centralize the place where base network score, and network score scaling, will be - * stored, so as we can consistently compare apple and oranges, or wifi, ethernet and LTE - * @hide - */ - public static final int WIFI_BASE_SCORE = 60; - /** * Sent by the NetworkAgent to ConnectivityService to pass the current * network score. @@ -272,7 +265,13 @@ public abstract class NetworkAgent { */ public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17; + // STOPSHIP (b/148055573) : remove this before R is released. + private static NetworkScore makeNetworkScore(int score) { + return new NetworkScore.Builder().setLegacyScore(score).build(); + } + /** @hide TODO: remove and replace usage with the public constructor. */ + // STOPSHIP (b/148055573) : remove this before R is released. public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score) { this(looper, context, logTag, ni, nc, lp, score, null, NetworkProvider.ID_NONE); @@ -280,6 +279,7 @@ public abstract class NetworkAgent { } /** @hide TODO: remove and replace usage with the public constructor. */ + // STOPSHIP (b/148055573) : remove this before R is released. public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config) { this(looper, context, logTag, ni, nc, lp, score, config, NetworkProvider.ID_NONE); @@ -287,6 +287,7 @@ public abstract class NetworkAgent { } /** @hide TODO: remove and replace usage with the public constructor. */ + // STOPSHIP (b/148055573) : remove this before R is released. public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score, int providerId) { this(looper, context, logTag, ni, nc, lp, score, null, providerId); @@ -294,10 +295,12 @@ public abstract class NetworkAgent { } /** @hide TODO: remove and replace usage with the public constructor. */ + // STOPSHIP (b/148055573) : remove this before R is released. public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config, int providerId) { - this(looper, context, logTag, nc, lp, score, config, providerId, ni, true /* legacy */); + this(looper, context, logTag, nc, lp, makeNetworkScore(score), config, providerId, ni, + true /* legacy */); register(); } @@ -323,8 +326,9 @@ public abstract class NetworkAgent { * @param provider the {@link NetworkProvider} managing this agent. */ public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag, - @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score, - @NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) { + @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, + @NonNull NetworkScore score, @NonNull NetworkAgentConfig config, + @Nullable NetworkProvider provider) { this(looper, context, logTag, nc, lp, score, config, provider == null ? NetworkProvider.ID_NONE : provider.getProviderId(), getLegacyNetworkInfo(config), false /* legacy */); @@ -334,12 +338,12 @@ public abstract class NetworkAgent { public final Context context; public final NetworkCapabilities capabilities; public final LinkProperties properties; - public final int score; + public final NetworkScore score; public final NetworkAgentConfig config; public final NetworkInfo info; InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities, - @NonNull LinkProperties properties, int score, @NonNull NetworkAgentConfig config, - @NonNull NetworkInfo info) { + @NonNull LinkProperties properties, @NonNull NetworkScore score, + @NonNull NetworkAgentConfig config, @NonNull NetworkInfo info) { this.context = context; this.capabilities = capabilities; this.properties = properties; @@ -351,7 +355,7 @@ public abstract class NetworkAgent { private volatile InitialConfiguration mInitialConfiguration; private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag, - @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score, + @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, NetworkScore score, @NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni, boolean legacy) { mHandler = new NetworkAgentHandler(looper); @@ -646,22 +650,8 @@ public abstract class NetworkAgent { * Must be called by the agent to update the score of this network. * @param score the new score. */ - public void sendNetworkScore(int score) { - if (score < 0) { - throw new IllegalArgumentException("Score must be >= 0"); - } - final NetworkScore ns = new NetworkScore(); - ns.putIntExtension(NetworkScore.LEGACY_SCORE, score); - updateScore(ns); - } - - /** - * Must be called by the agent when it has a new {@link NetworkScore} for this network. - * @param ns the new score. - * @hide TODO: unhide the NetworkScore class, and rename to sendNetworkScore. - */ - public void updateScore(@NonNull NetworkScore ns) { - queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new NetworkScore(ns)); + public void sendNetworkScore(@NonNull final NetworkScore score) { + queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, score); } /** diff --git a/core/java/android/net/NetworkScore.java b/core/java/android/net/NetworkScore.java index 13f2994110..ae17378cfc 100644 --- a/core/java/android/net/NetworkScore.java +++ b/core/java/android/net/NetworkScore.java @@ -15,12 +15,18 @@ */ package android.net; +import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.annotation.TestApi; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** @@ -28,57 +34,392 @@ import java.util.Objects; * * A NetworkScore object represents the characteristics of a network that affects how good the * network is considered for a particular use. + * + * This class is not thread-safe. * @hide */ +@TestApi +@SystemApi public final class NetworkScore implements Parcelable { + /** An object containing scoring-relevant metrics for a network. */ + public static class Metrics { + /** Value meaning the latency is unknown. */ + public static final int LATENCY_UNKNOWN = -1; - // The key of bundle which is used to get the legacy network score of NetworkAgentInfo. - // TODO: Remove this when the transition to NetworkScore is over. - public static final String LEGACY_SCORE = "LEGACY_SCORE"; + /** Value meaning the bandwidth is unknown. */ + public static final int BANDWIDTH_UNKNOWN = -1; + + /** + * Round-trip delay in milliseconds to the relevant destination for this Metrics object. + * + * LATENCY_UNKNOWN if unknown. + */ + @IntRange(from = LATENCY_UNKNOWN) + public final int latencyMs; + + /** + * Downlink in kB/s with the relevant destination for this Metrics object. + * + * BANDWIDTH_UNKNOWN if unknown. If directional bandwidth is unknown, up and downlink + * bandwidth can have the same value. + */ + @IntRange(from = BANDWIDTH_UNKNOWN) + public final int downlinkBandwidthKBps; + + /** + * Uplink in kB/s with the relevant destination for this Metrics object. + * + * BANDWIDTH_UNKNOWN if unknown. If directional bandwidth is unknown, up and downlink + * bandwidth can have the same value. + */ + @IntRange(from = BANDWIDTH_UNKNOWN) + public final int uplinkBandwidthKBps; + + /** Constructor */ + public Metrics(@IntRange(from = LATENCY_UNKNOWN) final int latency, + @IntRange(from = BANDWIDTH_UNKNOWN) final int downlinkBandwidth, + @IntRange(from = BANDWIDTH_UNKNOWN) final int uplinkBandwidth) { + latencyMs = latency; + downlinkBandwidthKBps = downlinkBandwidth; + uplinkBandwidthKBps = uplinkBandwidth; + } + + /** toString */ + public String toString() { + return "latency = " + latencyMs + " downlinkBandwidth = " + downlinkBandwidthKBps + + "uplinkBandwidth = " + uplinkBandwidthKBps; + } + + @NonNull + public static final Metrics EMPTY = + new Metrics(LATENCY_UNKNOWN, BANDWIDTH_UNKNOWN, BANDWIDTH_UNKNOWN); + } + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = true, prefix = "POLICY_", value = { + POLICY_LOCKDOWN_VPN, + POLICY_VPN, + POLICY_IGNORE_ON_WIFI, + POLICY_DEFAULT_SUBSCRIPTION + }) + public @interface Policy { + } + + /** + * This network is a VPN with lockdown enabled. + * + * If a network with this bit is present in the list of candidates and not connected, + * no network can satisfy the request. + */ + public static final int POLICY_LOCKDOWN_VPN = 1 << 0; + + /** + * This network is a VPN. + * + * If a network with this bit is present and the request UID is included in the UID ranges + * of this network, it outscores all other networks without this bit. + */ + public static final int POLICY_VPN = 1 << 1; + + /** + * This network should not be used if a previously validated WiFi network is available. + * + * If a network with this bit is present and a previously validated WiFi is present too, the + * network with this bit is outscored by it. This stays true if the WiFi network + * becomes unvalidated : this network will not be considered. + */ + public static final int POLICY_IGNORE_ON_WIFI = 1 << 2; + + /** + * This network is the default subscription for this transport. + * + * If a network with this bit is present, other networks of the same transport without this + * bit are outscored by it. A device with two active subscriptions and a setting + * to decide the default one would have this policy bit on the network for the default + * subscription so that when both are active at the same time, the device chooses the + * network associated with the default subscription rather than the one with the best link + * quality (which will happen if policy doesn't dictate otherwise). + */ + public static final int POLICY_DEFAULT_SUBSCRIPTION = 1 << 3; + + /** + * Policy bits for this network. Filled in by the NetworkAgent. + */ + private final int mPolicy; + + /** + * Predicted metrics to the gateway (it contains latency and bandwidth to the gateway). + * This is filled by the NetworkAgent with the theoretical values of the link if available, + * although they may fill it with predictions from historical data if available. + * Note that while this member cannot be null, any and all of its members can be unknown. + */ @NonNull - private final Bundle mExtensions; + private final Metrics mLinkLayerMetrics; - public NetworkScore() { - mExtensions = new Bundle(); - } + /** + * Predicted metrics to representative servers. + * This is filled by connectivity with (if available) a best-effort estimate of the performance + * information to servers the user connects to in similar circumstances, and predicted from + * actual measurements if possible. + * Note that while this member cannot be null, any and all of its members can be unknown. + */ + @NonNull + private final Metrics mEndToEndMetrics; - public NetworkScore(@NonNull NetworkScore source) { - mExtensions = new Bundle(source.mExtensions); + /** Value meaning the signal strength is unknown. */ + public static final int UNKNOWN_SIGNAL_STRENGTH = -1; + + /** The smallest meaningful signal strength. */ + public static final int MIN_SIGNAL_STRENGTH = 0; + + /** The largest meaningful signal strength. */ + public static final int MAX_SIGNAL_STRENGTH = 1000; + + /** + * User-visible measure of the strength of the signal normalized 1~1000. + * This represents a measure of the signal strength for this network. + * If unknown, this has value UNKNOWN_SIGNAL_STRENGTH. + */ + // A good way to populate this value is to fill it with the number of bars displayed in + // the system UI, scaled 0 to 1000. This is what the user sees and it makes sense to them. + // Cellular for example could quantize the ASU value (see SignalStrength#getAsuValue) into + // this, while WiFi could scale the RSSI (see WifiManager#calculateSignalLevel). + @IntRange(from = UNKNOWN_SIGNAL_STRENGTH, to = MAX_SIGNAL_STRENGTH) + private final int mSignalStrength; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = true, prefix = "RANGE_", value = { + RANGE_UNKNOWN, RANGE_CLOSE, RANGE_SHORT, RANGE_MEDIUM, RANGE_LONG + }) + public @interface Range { } /** - * Put the value of parcelable inside the bundle by key. + * The range of this network is not known. + * This can be used by VPN the range of which depends on the range of the underlying network. */ - public void putExtension(@Nullable String key, @Nullable Parcelable value) { - mExtensions.putParcelable(key, value); + public static final int RANGE_UNKNOWN = 0; + + /** + * This network typically only operates at close range, like an NFC beacon. + */ + public static final int RANGE_CLOSE = 1; + + /** + * This network typically operates at a range of a few meters to a few dozen meters, like WiFi. + */ + public static final int RANGE_SHORT = 2; + + /** + * This network typically operates at a range of a few dozen to a few hundred meters, like CBRS. + */ + public static final int RANGE_MEDIUM = 3; + + /** + * This network typically offers continuous connectivity up to many kilometers away, like LTE. + */ + public static final int RANGE_LONG = 4; + + /** + * The typical range of this networking technology. + * + * This is one of the RANGE_* constants and is filled by the NetworkAgent. + * This may be useful when evaluating how desirable a network is, because for two networks that + * have equivalent performance and cost, the one that won't lose IP continuity when the user + * moves is probably preferable. + * Agents should fill this with the largest typical range this technology provides. See the + * descriptions of the individual constants for guidance. + * + * If unknown, this is set to RANGE_UNKNOWN. + */ + @Range private final int mRange; + + /** + * A prediction of whether this network is likely to be unusable in a few seconds. + * + * NetworkAgents set this to true to mean they are aware that usability is limited due to + * low signal strength, congestion, or other reasons, and indicates that the system should + * only use this network as a last resort. An example would be a WiFi network when the device + * is about to move outside of range. + * + * This is filled by the NetworkAgent. Agents that don't know whether this network is likely + * to be unusable soon should set this to false. + */ + private final boolean mExiting; + + /** + * The legacy score, as a migration strategy from Q to R. + * STOPSHIP : remove this before R ships. + */ + private final int mLegacyScore; + + /** + * Create a new NetworkScore object. + */ + private NetworkScore(@Policy final int policy, @Nullable final Metrics l2Perf, + @Nullable final Metrics e2ePerf, + @IntRange(from = UNKNOWN_SIGNAL_STRENGTH, to = MAX_SIGNAL_STRENGTH) + final int signalStrength, + @Range final int range, final boolean exiting, final int legacyScore) { + mPolicy = policy; + mLinkLayerMetrics = null != l2Perf ? l2Perf : Metrics.EMPTY; + mEndToEndMetrics = null != e2ePerf ? e2ePerf : Metrics.EMPTY; + mSignalStrength = signalStrength; + mRange = range; + mExiting = exiting; + mLegacyScore = legacyScore; } /** - * Put the value of int inside the bundle by key. + * Utility function to return a copy of this with a different exiting value. */ - public void putIntExtension(@Nullable String key, int value) { - mExtensions.putInt(key, value); + @NonNull public NetworkScore withExiting(final boolean exiting) { + return new NetworkScore(mPolicy, mLinkLayerMetrics, mEndToEndMetrics, + mSignalStrength, mRange, exiting, mLegacyScore); } /** - * Get the value of non primitive type by key. + * Utility function to return a copy of this with a different signal strength. */ - public T getExtension(@Nullable String key) { - return mExtensions.getParcelable(key); + @NonNull public NetworkScore withSignalStrength( + @IntRange(from = UNKNOWN_SIGNAL_STRENGTH) final int signalStrength) { + return new NetworkScore(mPolicy, mLinkLayerMetrics, mEndToEndMetrics, + signalStrength, mRange, mExiting, mLegacyScore); } /** - * Get the value of int by key. + * Returns whether this network has a particular policy flag. + * @param policy the policy, as one of the POLICY_* constants. */ - public int getIntExtension(@Nullable String key) { - return mExtensions.getInt(key); + public boolean hasPolicy(@Policy final int policy) { + return 0 != (mPolicy & policy); } /** - * Remove the entry by given key. + * Returns the Metrics representing the performance of the link layer. + * + * This contains the theoretical performance of the link, if available. + * Note that while this function cannot return null, any and/or all of the members of the + * returned object can be null if unknown. */ - public void removeExtension(@Nullable String key) { - mExtensions.remove(key); + @NonNull public Metrics getLinkLayerMetrics() { + return mLinkLayerMetrics; + } + + /** + * Returns the Metrics representing the end-to-end performance of the network. + * + * This contains the end-to-end performance of the link, if available. + * Note that while this function cannot return null, any and/or all of the members of the + * returned object can be null if unknown. + */ + @NonNull public Metrics getEndToEndMetrics() { + return mEndToEndMetrics; + } + + /** + * Returns the signal strength of this network normalized 0~1000, or UNKNOWN_SIGNAL_STRENGTH. + */ + @IntRange(from = UNKNOWN_SIGNAL_STRENGTH, to = MAX_SIGNAL_STRENGTH) + public int getSignalStrength() { + return mSignalStrength; + } + + /** + * Returns the typical range of this network technology as one of the RANGE_* constants. + */ + @Range public int getRange() { + return mRange; + } + + /** Returns a prediction of whether this network is likely to be unusable in a few seconds. */ + public boolean isExiting() { + return mExiting; + } + + /** + * Get the legacy score. + * @hide + */ + public int getLegacyScore() { + return mLegacyScore; + } + + /** Builder for NetworkScore. */ + public static class Builder { + private int mPolicy = 0; + @NonNull + private Metrics mLinkLayerMetrics = new Metrics(Metrics.LATENCY_UNKNOWN, + Metrics.BANDWIDTH_UNKNOWN, Metrics.BANDWIDTH_UNKNOWN); + @NonNull + private Metrics mEndToMetrics = new Metrics(Metrics.LATENCY_UNKNOWN, + Metrics.BANDWIDTH_UNKNOWN, Metrics.BANDWIDTH_UNKNOWN); + private int mSignalStrength = UNKNOWN_SIGNAL_STRENGTH; + private int mRange = RANGE_UNKNOWN; + private boolean mExiting = false; + private int mLegacyScore = 0; + @NonNull private Bundle mExtensions = new Bundle(); + + /** Create a new builder. */ + public Builder() { } + + /** Add a policy flag. */ + @NonNull public Builder addPolicy(@Policy final int policy) { + mPolicy |= policy; + return this; + } + + /** Clear a policy flag */ + @NonNull public Builder clearPolicy(@Policy final int policy) { + mPolicy &= ~policy; + return this; + } + + /** Set the link layer metrics. */ + @NonNull public Builder setLinkLayerMetrics(@NonNull final Metrics linkLayerMetrics) { + mLinkLayerMetrics = linkLayerMetrics; + return this; + } + + /** Set the end-to-end metrics. */ + @NonNull public Builder setEndToEndMetrics(@NonNull final Metrics endToEndMetrics) { + mEndToMetrics = endToEndMetrics; + return this; + } + + /** Set the signal strength. */ + @NonNull public Builder setSignalStrength( + @IntRange(from = UNKNOWN_SIGNAL_STRENGTH, to = MAX_SIGNAL_STRENGTH) + final int signalStrength) { + mSignalStrength = signalStrength; + return this; + } + + /** Set the range. */ + @NonNull public Builder setRange(@Range final int range) { + mRange = range; + return this; + } + + /** Set whether this network is exiting. */ + @NonNull public Builder setExiting(final boolean exiting) { + mExiting = exiting; + return this; + } + + /** Add a parcelable extension. */ + @NonNull public Builder setLegacyScore(final int legacyScore) { + mLegacyScore = legacyScore; + return this; + } + + /** Build the NetworkScore object represented by this builder. */ + @NonNull public NetworkScore build() { + return new NetworkScore(mPolicy, mLinkLayerMetrics, mEndToMetrics, + mSignalStrength, mRange, mExiting, mLegacyScore); + } } @Override @@ -88,9 +429,17 @@ public final class NetworkScore implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { - synchronized (this) { - dest.writeBundle(mExtensions); - } + dest.writeInt(mPolicy); + dest.writeInt(mLinkLayerMetrics.latencyMs); + dest.writeInt(mLinkLayerMetrics.downlinkBandwidthKBps); + dest.writeInt(mLinkLayerMetrics.uplinkBandwidthKBps); + dest.writeInt(mEndToEndMetrics.latencyMs); + dest.writeInt(mEndToEndMetrics.downlinkBandwidthKBps); + dest.writeInt(mEndToEndMetrics.uplinkBandwidthKBps); + dest.writeInt(mSignalStrength); + dest.writeInt(mRange); + dest.writeBoolean(mExiting); + dest.writeInt(mLegacyScore); } public static final @NonNull Creator CREATOR = new Creator() { @@ -106,57 +455,52 @@ public final class NetworkScore implements Parcelable { }; private NetworkScore(@NonNull Parcel in) { - mExtensions = in.readBundle(); + mPolicy = in.readInt(); + mLinkLayerMetrics = new Metrics(in.readInt(), in.readInt(), in.readInt()); + mEndToEndMetrics = new Metrics(in.readInt(), in.readInt(), in.readInt()); + mSignalStrength = in.readInt(); + mRange = in.readInt(); + mExiting = in.readBoolean(); + mLegacyScore = in.readInt(); } - // TODO: Modify this method once new fields are added into this class. @Override public boolean equals(@Nullable Object obj) { if (!(obj instanceof NetworkScore)) { return false; } final NetworkScore other = (NetworkScore) obj; - return bundlesEqual(mExtensions, other.mExtensions); + return mPolicy == other.mPolicy + && mLinkLayerMetrics.latencyMs == other.mLinkLayerMetrics.latencyMs + && mLinkLayerMetrics.uplinkBandwidthKBps + == other.mLinkLayerMetrics.uplinkBandwidthKBps + && mEndToEndMetrics.latencyMs == other.mEndToEndMetrics.latencyMs + && mEndToEndMetrics.uplinkBandwidthKBps + == other.mEndToEndMetrics.uplinkBandwidthKBps + && mSignalStrength == other.mSignalStrength + && mRange == other.mRange + && mExiting == other.mExiting + && mLegacyScore == other.mLegacyScore; } @Override public int hashCode() { - int result = 29; - for (String key : mExtensions.keySet()) { - final Object value = mExtensions.get(key); - // The key may be null, so call Objects.hash() is safer. - result += 31 * value.hashCode() + 37 * Objects.hash(key); - } - return result; - } - - // mExtensions won't be null since the constructor will create it. - private boolean bundlesEqual(@NonNull Bundle bundle1, @NonNull Bundle bundle2) { - if (bundle1 == bundle2) { - return true; - } - - // This is unlikely but it's fine to add this clause here. - if (null == bundle1 || null == bundle2) { - return false; - } - - if (bundle1.size() != bundle2.size()) { - return false; - } - - for (String key : bundle1.keySet()) { - final Object value1 = bundle1.get(key); - final Object value2 = bundle2.get(key); - if (!Objects.equals(value1, value2)) { - return false; - } - } - return true; + return Objects.hash(mPolicy, + mLinkLayerMetrics.latencyMs, mLinkLayerMetrics.uplinkBandwidthKBps, + mEndToEndMetrics.latencyMs, mEndToEndMetrics.uplinkBandwidthKBps, + mSignalStrength, mRange, mExiting, mLegacyScore); } /** Convert to a string */ public String toString() { - return "NetworkScore[" + mExtensions.toString() + "]"; + return "NetworkScore [" + + "Policy = " + mPolicy + + " LinkLayerMetrics = " + mLinkLayerMetrics + + " EndToEndMetrics = " + mEndToEndMetrics + + " SignalStrength = " + mSignalStrength + + " Range = " + mRange + + " Exiting = " + mExiting + + " LegacyScore = " + mLegacyScore + + "]"; } } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 1c9f5dc9c2..ba4708f1cd 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -5510,20 +5510,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return nri.request.requestId == mDefaultRequest.requestId; } - // TODO : remove this method. It's a stopgap measure to help sheperding a number of dependent - // changes that would conflict throughout the automerger graph. Having this method temporarily - // helps with the process of going through with all these dependent changes across the entire - // tree. - /** - * Register a new agent. {@see #registerNetworkAgent} below. - */ - public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, - LinkProperties linkProperties, NetworkCapabilities networkCapabilities, - int currentScore, NetworkAgentConfig networkAgentConfig) { - return registerNetworkAgent(messenger, networkInfo, linkProperties, networkCapabilities, - currentScore, networkAgentConfig, NetworkProvider.ID_NONE); - } - /** * Register a new agent with ConnectivityService to handle a network. * @@ -5542,7 +5528,7 @@ public class ConnectivityService extends IConnectivityManager.Stub */ public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, - int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) { + NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId) { enforceNetworkFactoryPermission(); LinkProperties lp = new LinkProperties(linkProperties); @@ -5550,12 +5536,10 @@ public class ConnectivityService extends IConnectivityManager.Stub // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network // satisfies mDefaultRequest. final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); - final NetworkScore ns = new NetworkScore(); - ns.putIntExtension(NetworkScore.LEGACY_SCORE, currentScore); final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc, - ns, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig), this, - mNetd, mDnsResolver, mNMS, providerId); + currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig), + this, mNetd, mDnsResolver, mNMS, providerId); // Make sure the network capabilities reflect what the agent info says. nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc)); final String extraInfo = networkInfo.getExtraInfo(); diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index d66aec5761..3cfe916049 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -483,7 +483,7 @@ public class NetworkAgentInfo implements Comparable { return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE; } - int score = mNetworkScore.getIntExtension(NetworkScore.LEGACY_SCORE); + int score = mNetworkScore.getLegacyScore(); if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) { score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY; } diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java index a35fb407bc..7ae9e95a52 100644 --- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java +++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java @@ -40,6 +40,7 @@ import android.net.NetworkAgentConfig; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkProvider; +import android.net.NetworkScore; import android.net.NetworkSpecifier; import android.net.SocketKeepalive; import android.net.UidRange; @@ -155,9 +156,13 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork { } } + private NetworkScore makeNetworkScore(final int legacyScore) { + return new NetworkScore.Builder().setLegacyScore(legacyScore).build(); + } + public void adjustScore(int change) { mScore += change; - mNetworkAgent.sendNetworkScore(mScore); + mNetworkAgent.sendNetworkScore(makeNetworkScore(mScore)); } public int getScore() { diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java index e863266c4b..25e9057fd1 100644 --- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java @@ -353,8 +353,7 @@ public class LingerMonitorTest { NetworkCapabilities caps = new NetworkCapabilities(); caps.addCapability(0); caps.addTransportType(transport); - NetworkScore ns = new NetworkScore(); - ns.putIntExtension(NetworkScore.LEGACY_SCORE, 50); + NetworkScore ns = new NetworkScore.Builder().setLegacyScore(50).build(); NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null, caps, ns, mCtx, null, null /* config */, mConnService, mNetd, mDnsResolver, mNMS, NetworkProvider.ID_NONE);