Revert "Add public fields to NetworkScore and make it @SystemApi"

This reverts commit a9727279aeeb7eb521f4d26dec93f01e596cb208.

Bug: 113554781
Test: FrameworksNetTests FrameworksTelephonyTests FrameworksWifiTests
Change-Id: Ie1e84bd2a16f088307b195f924f4e49335cbe367
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 62eff45..38ef814 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -3323,19 +3323,15 @@
     // 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) {
-        final NetworkScore ns = new NetworkScore.Builder().setLegacyScore(score).build();
-        return registerNetworkAgent(messenger, ni, lp, nc, ns, config, NetworkProvider.ID_NONE);
+        return registerNetworkAgent(messenger, ni, lp, nc, score, config, NetworkProvider.ID_NONE);
     }
 
     /**
@@ -3345,7 +3341,7 @@
      */
     @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
     public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
-            NetworkCapabilities nc, NetworkScore score, NetworkAgentConfig config, int providerId) {
+            NetworkCapabilities nc, int 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 d84d05d..1434560 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -26,7 +26,6 @@
 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;
@@ -164,7 +163,7 @@
     void declareNetworkRequestUnfulfillable(in NetworkRequest request);
 
     Network registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp,
-            in NetworkCapabilities nc, in NetworkScore score, in NetworkAgentConfig config,
+            in NetworkCapabilities nc, int 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 ddf8dbb..7cc569a 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -117,6 +117,13 @@
     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.
      * obj = network score Integer
@@ -265,13 +272,7 @@
      */
     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);
@@ -279,7 +280,6 @@
     }
 
     /** @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,7 +287,6 @@
     }
 
     /** @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);
@@ -295,12 +294,10 @@
     }
 
     /** @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, makeNetworkScore(score), config, providerId, ni,
-                true /* legacy */);
+        this(looper, context, logTag, nc, lp, score, config, providerId, ni, true /* legacy */);
         register();
     }
 
@@ -326,9 +323,8 @@
      * @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,
-            @NonNull NetworkScore score, @NonNull NetworkAgentConfig config,
-            @Nullable NetworkProvider provider) {
+            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int 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 */);
@@ -338,12 +334,12 @@
         public final Context context;
         public final NetworkCapabilities capabilities;
         public final LinkProperties properties;
-        public final NetworkScore score;
+        public final int score;
         public final NetworkAgentConfig config;
         public final NetworkInfo info;
         InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities,
-                @NonNull LinkProperties properties, @NonNull NetworkScore score,
-                @NonNull NetworkAgentConfig config, @NonNull NetworkInfo info) {
+                @NonNull LinkProperties properties, int score, @NonNull NetworkAgentConfig config,
+                @NonNull NetworkInfo info) {
             this.context = context;
             this.capabilities = capabilities;
             this.properties = properties;
@@ -355,7 +351,7 @@
     private volatile InitialConfiguration mInitialConfiguration;
 
     private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag,
-            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, NetworkScore score,
+            @NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
             @NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni,
             boolean legacy) {
         mHandler = new NetworkAgentHandler(looper);
@@ -650,8 +646,22 @@
      * Must be called by the agent to update the score of this network.
      * @param score the new score.
      */
-    public void sendNetworkScore(@NonNull final NetworkScore score) {
-        queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, 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));
     }
 
     /**
diff --git a/core/java/android/net/NetworkScore.java b/core/java/android/net/NetworkScore.java
index ae17378..13f2994 100644
--- a/core/java/android/net/NetworkScore.java
+++ b/core/java/android/net/NetworkScore.java
@@ -15,18 +15,12 @@
  */
 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;
 
 /**
@@ -34,392 +28,57 @@
  *
  * 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;
 
-        /** 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.
-     */
+    // 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";
     @NonNull
-    private final Metrics mLinkLayerMetrics;
+    private final Bundle mExtensions;
 
-    /**
-     * 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() {
+        mExtensions = new Bundle();
+    }
 
-    /** 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 {
+    public NetworkScore(@NonNull NetworkScore source) {
+        mExtensions = new Bundle(source.mExtensions);
     }
 
     /**
-     * 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.
+     * Put the value of parcelable inside the bundle by key.
      */
-    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;
+    public void putExtension(@Nullable String key, @Nullable Parcelable value) {
+        mExtensions.putParcelable(key, value);
     }
 
     /**
-     * Utility function to return a copy of this with a different exiting value.
+     * Put the value of int inside the bundle by key.
      */
-    @NonNull public NetworkScore withExiting(final boolean exiting) {
-        return new NetworkScore(mPolicy, mLinkLayerMetrics, mEndToEndMetrics,
-                mSignalStrength, mRange, exiting, mLegacyScore);
+    public void putIntExtension(@Nullable String key, int value) {
+        mExtensions.putInt(key, value);
     }
 
     /**
-     * Utility function to return a copy of this with a different signal strength.
+     * Get the value of non primitive type by key.
      */
-    @NonNull public NetworkScore withSignalStrength(
-            @IntRange(from = UNKNOWN_SIGNAL_STRENGTH) final int signalStrength) {
-        return new NetworkScore(mPolicy, mLinkLayerMetrics, mEndToEndMetrics,
-                signalStrength, mRange, mExiting, mLegacyScore);
+    public <T extends Parcelable> T getExtension(@Nullable String key) {
+        return mExtensions.getParcelable(key);
     }
 
     /**
-     * Returns whether this network has a particular policy flag.
-     * @param policy the policy, as one of the POLICY_* constants.
+     * Get the value of int by key.
      */
-    public boolean hasPolicy(@Policy final int policy) {
-        return 0 != (mPolicy & policy);
+    public int getIntExtension(@Nullable String key) {
+        return mExtensions.getInt(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.
+     * Remove the entry by given 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);
-        }
+    public void removeExtension(@Nullable String key) {
+        mExtensions.remove(key);
     }
 
     @Override
@@ -429,17 +88,9 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        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);
+        synchronized (this) {
+            dest.writeBundle(mExtensions);
+        }
     }
 
     public static final @NonNull Creator<NetworkScore> CREATOR = new Creator<NetworkScore>() {
@@ -455,52 +106,57 @@
     };
 
     private NetworkScore(@NonNull Parcel in) {
-        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();
+        mExtensions = in.readBundle();
     }
 
+    // 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 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;
+        return bundlesEqual(mExtensions, other.mExtensions);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mPolicy,
-                mLinkLayerMetrics.latencyMs, mLinkLayerMetrics.uplinkBandwidthKBps,
-                mEndToEndMetrics.latencyMs, mEndToEndMetrics.uplinkBandwidthKBps,
-                mSignalStrength, mRange, mExiting, mLegacyScore);
+        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;
     }
 
     /** Convert to a string */
     public String toString() {
-        return "NetworkScore ["
-                + "Policy = " + mPolicy
-                + " LinkLayerMetrics = " + mLinkLayerMetrics
-                + " EndToEndMetrics = " + mEndToEndMetrics
-                + " SignalStrength = " + mSignalStrength
-                + " Range = " + mRange
-                + " Exiting = " + mExiting
-                + " LegacyScore = " + mLegacyScore
-                + "]";
+        return "NetworkScore[" + mExtensions.toString() + "]";
     }
 }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index f84d35f..16dd3ad 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -5779,6 +5779,20 @@
         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.
      *
@@ -5797,7 +5811,7 @@
      */
     public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
-            NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId) {
+            int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) {
         enforceNetworkFactoryPermission();
 
         LinkProperties lp = new LinkProperties(linkProperties);
@@ -5805,10 +5819,12 @@
         // 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,
-                currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
-                this, mNetd, mDnsResolver, mNMS, providerId);
+                ns, 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 4612cfd..58b5cba 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -491,7 +491,7 @@
             return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE;
         }
 
-        int score = mNetworkScore.getLegacyScore();
+        int score = mNetworkScore.getIntExtension(NetworkScore.LEGACY_SCORE);
         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 7ae9e95..a35fb40 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -40,7 +40,6 @@
 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;
@@ -156,13 +155,9 @@
         }
     }
 
-    private NetworkScore makeNetworkScore(final int legacyScore) {
-        return new NetworkScore.Builder().setLegacyScore(legacyScore).build();
-    }
-
     public void adjustScore(int change) {
         mScore += change;
-        mNetworkAgent.sendNetworkScore(makeNetworkScore(mScore));
+        mNetworkAgent.sendNetworkScore(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 25e9057..e863266 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -353,7 +353,8 @@
         NetworkCapabilities caps = new NetworkCapabilities();
         caps.addCapability(0);
         caps.addTransportType(transport);
-        NetworkScore ns = new NetworkScore.Builder().setLegacyScore(50).build();
+        NetworkScore ns = new NetworkScore();
+        ns.putIntExtension(NetworkScore.LEGACY_SCORE, 50);
         NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
                 caps, ns, mCtx, null, null /* config */, mConnService, mNetd, mDnsResolver, mNMS,
                 NetworkProvider.ID_NONE);