Merge "Split NetworkStackUtils to frameworks/libs/net"
diff --git a/src/android/net/apf/ApfFilter.java b/src/android/net/apf/ApfFilter.java
index c9eee6d..0bb4094 100644
--- a/src/android/net/apf/ApfFilter.java
+++ b/src/android/net/apf/ApfFilter.java
@@ -64,6 +64,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.HexDump;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.ConnectivityUtils;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -1027,9 +1029,9 @@
         public String toString() {
             try {
                 return String.format("%s -> %s",
-                        NetworkStackUtils.addressAndPortToString(
+                        ConnectivityUtils.addressAndPortToString(
                                 InetAddress.getByAddress(mPacket.srcAddress), mPacket.srcPort),
-                        NetworkStackUtils.addressAndPortToString(
+                        ConnectivityUtils.addressAndPortToString(
                                 InetAddress.getByAddress(mPacket.dstAddress), mPacket.dstPort));
             } catch (UnknownHostException e) {
                 return "Unknown host";
@@ -1082,9 +1084,9 @@
         public String toString() {
             try {
                 return String.format("%s -> %s , seq=%d, ack=%d",
-                        NetworkStackUtils.addressAndPortToString(
+                        ConnectivityUtils.addressAndPortToString(
                                 InetAddress.getByAddress(mPacket.srcAddress), mPacket.srcPort),
-                        NetworkStackUtils.addressAndPortToString(
+                        ConnectivityUtils.addressAndPortToString(
                                 InetAddress.getByAddress(mPacket.dstAddress), mPacket.dstPort),
                         Integer.toUnsignedLong(mPacket.seq),
                         Integer.toUnsignedLong(mPacket.ack));
@@ -1363,7 +1365,7 @@
 
     private void generateKeepaliveFilters(ApfGenerator gen, Class<?> filterType, int proto,
             int offset, String label) throws IllegalInstructionException {
-        final boolean haveKeepaliveResponses = NetworkStackUtils.any(mKeepalivePackets,
+        final boolean haveKeepaliveResponses = CollectionUtils.any(mKeepalivePackets,
                 ack -> filterType.isInstance(ack));
 
         // If no keepalive packets of this type
diff --git a/src/android/net/dhcp/DhcpClient.java b/src/android/net/dhcp/DhcpClient.java
index 362864b..9059203 100644
--- a/src/android/net/dhcp/DhcpClient.java
+++ b/src/android/net/dhcp/DhcpClient.java
@@ -98,6 +98,7 @@
 import com.android.internal.util.StateMachine;
 import com.android.internal.util.TrafficStatsConstants;
 import com.android.internal.util.WakeupMessage;
+import com.android.net.module.util.DeviceConfigUtils;
 import com.android.net.module.util.PacketReader;
 import com.android.networkstack.R;
 import com.android.networkstack.apishim.CaptivePortalDataShimImpl;
@@ -435,11 +436,11 @@
 
         /**
          * Return whether a feature guarded by a feature flag is enabled.
-         * @see NetworkStackUtils#isFeatureEnabled(Context, String, String)
+         * @see DeviceConfigUtils#isFeatureEnabled(Context, String, String)
          */
         public boolean isFeatureEnabled(final Context context, final String name,
                 boolean defaultEnabled) {
-            return NetworkStackUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY, name,
+            return DeviceConfigUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY, name,
                     defaultEnabled);
         }
 
@@ -448,7 +449,7 @@
          */
         public int getIntDeviceConfig(final String name, int minimumValue, int maximumValue,
                 int defaultValue) {
-            return NetworkStackUtils.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
+            return DeviceConfigUtils.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
                     name, minimumValue, maximumValue, defaultValue);
         }
 
diff --git a/src/android/net/dhcp/DhcpServer.java b/src/android/net/dhcp/DhcpServer.java
index 05809ca..3acd76e 100644
--- a/src/android/net/dhcp/DhcpServer.java
+++ b/src/android/net/dhcp/DhcpServer.java
@@ -67,6 +67,7 @@
 import com.android.internal.util.HexDump;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.net.module.util.DeviceConfigUtils;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -231,7 +232,7 @@
 
         @Override
         public boolean isFeatureEnabled(@NonNull Context context, @NonNull String name) {
-            return NetworkStackUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY, name);
+            return DeviceConfigUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY, name);
         }
     }
 
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index 45dbe4b..af728e7 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -51,7 +51,6 @@
 import android.net.shared.ProvisioningConfiguration.ScanResultInfo;
 import android.net.shared.ProvisioningConfiguration.ScanResultInfo.InformationElement;
 import android.net.util.InterfaceParams;
-import android.net.util.NetworkStackUtils;
 import android.net.util.SharedLog;
 import android.os.Build;
 import android.os.ConditionVariable;
@@ -77,6 +76,7 @@
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
 import com.android.internal.util.WakeupMessage;
+import com.android.net.module.util.DeviceConfigUtils;
 import com.android.networkstack.apishim.NetworkInformationShimImpl;
 import com.android.networkstack.apishim.common.NetworkInformationShim;
 import com.android.networkstack.apishim.common.ShimUtils;
@@ -541,7 +541,7 @@
          * Read an integer DeviceConfig property.
          */
         public int getDeviceConfigPropertyInt(String name, int defaultValue) {
-            return NetworkStackUtils.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY, name,
+            return DeviceConfigUtils.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY, name,
                     defaultValue);
         }
 
diff --git a/src/android/net/util/NetworkStackUtils.java b/src/android/net/util/NetworkStackUtils.java
index de94ee3..5c11733 100755
--- a/src/android/net/util/NetworkStackUtils.java
+++ b/src/android/net/util/NetworkStackUtils.java
@@ -17,24 +17,13 @@
 package android.net.util;
 
 import android.content.Context;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.provider.DeviceConfig;
-import android.util.Log;
-import android.util.SparseArray;
 
-import androidx.annotation.BoolRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
+import com.android.net.module.util.DeviceConfigUtils;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
 import java.net.SocketException;
-import java.util.List;
-import java.util.function.Predicate;
 
 /**
  * Collection of utilities for the network stack.
@@ -239,7 +228,7 @@
      *
      * Metrics are sent by default. They can be disabled by setting the flag to a number greater
      * than the APK version (for example 999999999).
-     * @see #isFeatureEnabled(Context, String, String, boolean)
+     * @see DeviceConfigUtils#isFeatureEnabled(Context, String, String, boolean)
      */
     public static final String VALIDATION_METRICS_VERSION = "validation_metrics_version";
 
@@ -248,13 +237,6 @@
     }
 
     /**
-     * @return True if the array is null or 0-length.
-     */
-    public static <T> boolean isEmpty(T[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
      * Close a socket, ignoring any exception while closing.
      */
     public static void closeSocketQuietly(FileDescriptor fd) {
@@ -265,150 +247,6 @@
     }
 
     /**
-     * Returns an int array from the given Integer list.
-     */
-    public static int[] convertToIntArray(@NonNull List<Integer> list) {
-        int[] array = new int[list.size()];
-        for (int i = 0; i < list.size(); i++) {
-            array[i] = list.get(i);
-        }
-        return array;
-    }
-
-    /**
-     * Returns a long array from the given long list.
-     */
-    public static long[] convertToLongArray(@NonNull List<Long> list) {
-        long[] array = new long[list.size()];
-        for (int i = 0; i < list.size(); i++) {
-            array[i] = list.get(i);
-        }
-        return array;
-    }
-
-    /**
-     * @return True if there exists at least one element in the sparse array for which
-     * condition {@code predicate}
-     */
-    public static <T> boolean any(SparseArray<T> array, Predicate<T> predicate) {
-        for (int i = 0; i < array.size(); ++i) {
-            if (predicate.test(array.valueAt(i))) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Look up the value of a property for a particular namespace from {@link DeviceConfig}.
-     * @param namespace The namespace containing the property to look up.
-     * @param name The name of the property to look up.
-     * @param defaultValue The value to return if the property does not exist or has no valid value.
-     * @return the corresponding value, or defaultValue if none exists.
-     */
-    @Nullable
-    public static String getDeviceConfigProperty(@NonNull String namespace, @NonNull String name,
-            @Nullable String defaultValue) {
-        String value = DeviceConfig.getProperty(namespace, name);
-        return value != null ? value : defaultValue;
-    }
-
-    /**
-     * Look up the value of a property for a particular namespace from {@link DeviceConfig}.
-     * @param namespace The namespace containing the property to look up.
-     * @param name The name of the property to look up.
-     * @param defaultValue The value to return if the property does not exist or its value is null.
-     * @return the corresponding value, or defaultValue if none exists.
-     */
-    public static int getDeviceConfigPropertyInt(@NonNull String namespace, @NonNull String name,
-            int defaultValue) {
-        String value = getDeviceConfigProperty(namespace, name, null /* defaultValue */);
-        try {
-            return (value != null) ? Integer.parseInt(value) : defaultValue;
-        } catch (NumberFormatException e) {
-            return defaultValue;
-        }
-    }
-
-    /**
-     * Look up the value of a property for a particular namespace from {@link DeviceConfig}.
-     * @param namespace The namespace containing the property to look up.
-     * @param name The name of the property to look up.
-     * @param minimumValue The minimum value of a property.
-     * @param maximumValue The maximum value of a property.
-     * @param defaultValue The value to return if the property does not exist or its value is null.
-     * @return the corresponding value, or defaultValue if none exists or the fetched value is
-     *         greater than maximumValue.
-     */
-    public static int getDeviceConfigPropertyInt(@NonNull String namespace, @NonNull String name,
-            int minimumValue, int maximumValue, int defaultValue) {
-        int value = getDeviceConfigPropertyInt(namespace, name, defaultValue);
-        if (value < minimumValue || value > maximumValue) return defaultValue;
-        return value;
-    }
-
-    /**
-     * Look up the value of a property for a particular namespace from {@link DeviceConfig}.
-     * @param namespace The namespace containing the property to look up.
-     * @param name The name of the property to look up.
-     * @param defaultValue The value to return if the property does not exist or its value is null.
-     * @return the corresponding value, or defaultValue if none exists.
-     */
-    public static boolean getDeviceConfigPropertyBoolean(@NonNull String namespace,
-            @NonNull String name, boolean defaultValue) {
-        String value = getDeviceConfigProperty(namespace, name, null /* defaultValue */);
-        return (value != null) ? Boolean.parseBoolean(value) : defaultValue;
-    }
-
-    /**
-     * Check whether or not one specific experimental feature for a particular namespace from
-     * {@link DeviceConfig} is enabled by comparing NetworkStack module version {@link NetworkStack}
-     * with current version of property. If this property version is valid, the corresponding
-     * experimental feature would be enabled, otherwise disabled.
-     *
-     * This is useful to ensure that if a module install is rolled back, flags are not left fully
-     * rolled out on a version where they have not been well tested.
-     * @param context The global context information about an app environment.
-     * @param namespace The namespace containing the property to look up.
-     * @param name The name of the property to look up.
-     * @return true if this feature is enabled, or false if disabled.
-     */
-    public static boolean isFeatureEnabled(@NonNull Context context, @NonNull String namespace,
-            @NonNull String name) {
-        return isFeatureEnabled(context, namespace, name, false /* defaultEnabled */);
-    }
-
-    /**
-     * Check whether or not one specific experimental feature for a particular namespace from
-     * {@link DeviceConfig} is enabled by comparing NetworkStack module version {@link NetworkStack}
-     * with current version of property. If this property version is valid, the corresponding
-     * experimental feature would be enabled, otherwise disabled.
-     *
-     * This is useful to ensure that if a module install is rolled back, flags are not left fully
-     * rolled out on a version where they have not been well tested.
-     * @param context The global context information about an app environment.
-     * @param namespace The namespace containing the property to look up.
-     * @param name The name of the property to look up.
-     * @param defaultEnabled The value to return if the property does not exist or its value is
-     *                       null.
-     * @return true if this feature is enabled, or false if disabled.
-     */
-    public static boolean isFeatureEnabled(@NonNull Context context, @NonNull String namespace,
-            @NonNull String name, boolean defaultEnabled) {
-        try {
-            final int propertyVersion = getDeviceConfigPropertyInt(namespace, name,
-                    0 /* default value */);
-            final long packageVersion = context.getPackageManager().getPackageInfo(
-                    context.getPackageName(), 0).getLongVersionCode();
-            return (propertyVersion == 0 && defaultEnabled)
-                    || (propertyVersion != 0 && packageVersion >= (long) propertyVersion);
-        } catch (NameNotFoundException e) {
-            Log.e(TAG, "Could not find the package name", e);
-            return false;
-        }
-    }
-
-    /**
      * Attaches a socket filter that accepts DHCP packets to the given socket.
      */
     public static native void attachDhcpFilter(FileDescriptor fd) throws SocketException;
@@ -443,51 +281,4 @@
     private static native void addArpEntry(byte[] ethAddr, byte[] netAddr, String ifname,
             FileDescriptor fd) throws IOException;
 
-    /**
-     * Return IP address and port in a string format.
-     */
-    public static String addressAndPortToString(InetAddress address, int port) {
-        return String.format(
-                (address instanceof Inet6Address) ? "[%s]:%d" : "%s:%d",
-                        address.getHostAddress(), port);
-    }
-
-    /**
-     * Return true if the provided address is non-null and an IPv6 Unique Local Address (RFC4193).
-     */
-    public static boolean isIPv6ULA(@Nullable InetAddress addr) {
-        return addr instanceof Inet6Address
-                && ((addr.getAddress()[0] & 0xfe) == 0xfc);
-    }
-
-    /**
-     * Returns the {@code int} nearest in value to {@code value}.
-     *
-     * @param value any {@code long} value
-     * @return the same value cast to {@code int} if it is in the range of the {@code int}
-     * type, {@link Integer#MAX_VALUE} if it is too large, or {@link Integer#MIN_VALUE} if
-     * it is too small
-     */
-    public static int saturatedCast(long value) {
-        if (value > Integer.MAX_VALUE) {
-            return Integer.MAX_VALUE;
-        }
-        if (value < Integer.MIN_VALUE) {
-            return Integer.MIN_VALUE;
-        }
-        return (int) value;
-    }
-
-    /**
-     * Gets boolean config from resources.
-     */
-    public static boolean getResBooleanConfig(@NonNull final Context context,
-            @BoolRes int configResource, final boolean defaultValue) {
-        final Resources res = context.getResources();
-        try {
-            return res.getBoolean(configResource);
-        } catch (Resources.NotFoundException e) {
-            return defaultValue;
-        }
-    }
 }
diff --git a/src/com/android/networkstack/metrics/DataStallDetectionStats.java b/src/com/android/networkstack/metrics/DataStallDetectionStats.java
index 131fb79..751d98d 100644
--- a/src/com/android/networkstack/metrics/DataStallDetectionStats.java
+++ b/src/com/android/networkstack/metrics/DataStallDetectionStats.java
@@ -16,7 +16,6 @@
 
 package com.android.networkstack.metrics;
 
-import android.net.util.NetworkStackUtils;
 import android.net.wifi.WifiInfo;
 
 import androidx.annotation.IntRange;
@@ -25,6 +24,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.util.HexDump;
+import com.android.net.module.util.CollectionUtils;
 import com.android.server.connectivity.nano.CellularData;
 import com.android.server.connectivity.nano.DataStallEventProto;
 import com.android.server.connectivity.nano.DnsEvent;
@@ -299,8 +299,8 @@
          */
         public DataStallDetectionStats build() {
             return new DataStallDetectionStats(mCellularInfo, mWifiInfo,
-                    NetworkStackUtils.convertToIntArray(mDnsReturnCode),
-                    NetworkStackUtils.convertToLongArray(mDnsTimeStamp),
+                    CollectionUtils.toIntArray(mDnsReturnCode),
+                    CollectionUtils.toLongArray(mDnsTimeStamp),
                     mEvaluationType, mNetworkType, mTcpFailRate, mTcpSentSinceLastRecv);
         }
     }
diff --git a/src/com/android/networkstack/metrics/IpProvisioningMetrics.java b/src/com/android/networkstack/metrics/IpProvisioningMetrics.java
index 64e173d..b015a51 100644
--- a/src/com/android/networkstack/metrics/IpProvisioningMetrics.java
+++ b/src/com/android/networkstack/metrics/IpProvisioningMetrics.java
@@ -16,13 +16,14 @@
 
 package com.android.networkstack.metrics;
 
-import android.net.util.NetworkStackUtils;
 import android.net.util.Stopwatch;
 import android.stats.connectivity.DhcpErrorCode;
 import android.stats.connectivity.DhcpFeature;
 import android.stats.connectivity.DisconnectCode;
 import android.stats.connectivity.HostnameTransResult;
 
+import com.android.net.module.util.ConnectivityUtils;
+
 import java.util.HashSet;
 import java.util.Set;
 
@@ -70,7 +71,7 @@
      */
     public void setIPv4ProvisionedLatencyOnFirstTime(final boolean isIpv4Provisioned) {
         if (isIpv4Provisioned && !mStatsBuilder.hasIpv4LatencyMicros()) {
-            mStatsBuilder.setIpv4LatencyMicros(NetworkStackUtils.saturatedCast(mIpv4Watch.stop()));
+            mStatsBuilder.setIpv4LatencyMicros(ConnectivityUtils.saturatedCast(mIpv4Watch.stop()));
         }
     }
 
@@ -79,7 +80,7 @@
      */
     public void setIPv6ProvisionedLatencyOnFirstTime(final boolean isIpv6Provisioned) {
         if (isIpv6Provisioned && !mStatsBuilder.hasIpv6LatencyMicros()) {
-            mStatsBuilder.setIpv6LatencyMicros(NetworkStackUtils.saturatedCast(mIpv6Watch.stop()));
+            mStatsBuilder.setIpv6LatencyMicros(ConnectivityUtils.saturatedCast(mIpv6Watch.stop()));
         }
     }
 
diff --git a/src/com/android/networkstack/metrics/NetworkValidationMetrics.java b/src/com/android/networkstack/metrics/NetworkValidationMetrics.java
index f27a939..76bd5fc 100644
--- a/src/com/android/networkstack/metrics/NetworkValidationMetrics.java
+++ b/src/com/android/networkstack/metrics/NetworkValidationMetrics.java
@@ -30,7 +30,6 @@
 import android.net.NetworkCapabilities;
 import android.net.captiveportal.CaptivePortalProbeResult;
 import android.net.metrics.ValidationProbeEvent;
-import android.net.util.NetworkStackUtils;
 import android.net.util.Stopwatch;
 import android.stats.connectivity.ProbeResult;
 import android.stats.connectivity.ProbeType;
@@ -40,6 +39,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.net.module.util.ConnectivityUtils;
 import com.android.networkstack.apishim.common.CaptivePortalDataShim;
 
 /**
@@ -195,7 +195,7 @@
         // many probes are skipped.
         if (mProbeEventsBuilder.getProbeEventCount() >= MAX_PROBE_EVENTS_COUNT) return;
 
-        int latencyUs = NetworkStackUtils.saturatedCast(durationUs);
+        int latencyUs = ConnectivityUtils.saturatedCast(durationUs);
 
         final ProbeEvent.Builder probeEventBuilder = ProbeEvent.newBuilder()
                 .setLatencyMicros(latencyUs)
@@ -206,10 +206,10 @@
             final long secondsRemaining =
                     (capportData.getExpiryTimeMillis() - currentTimeMillis()) / 1000;
             mCapportApiDataBuilder
-                .setRemainingTtlSecs(NetworkStackUtils.saturatedCast(secondsRemaining))
+                .setRemainingTtlSecs(ConnectivityUtils.saturatedCast(secondsRemaining))
                 // TODO: rename this field to setRemainingKBytes, or use a long
                 .setRemainingBytes(
-                        NetworkStackUtils.saturatedCast(capportData.getByteLimit() / 1000))
+                        ConnectivityUtils.saturatedCast(capportData.getByteLimit() / 1000))
                 .setHasPortalUrl((capportData.getUserPortalUrl() != null))
                 .setHasVenueInfo((capportData.getVenueInfoUrl() != null));
             probeEventBuilder.setCapportApiData(mCapportApiDataBuilder);
@@ -234,7 +234,7 @@
     public NetworkValidationReported maybeStopCollectionAndSend() {
         if (!mWatch.isStarted()) return null;
         mStatsBuilder.setProbeEvents(mProbeEventsBuilder);
-        mStatsBuilder.setLatencyMicros(NetworkStackUtils.saturatedCast(mWatch.stop()));
+        mStatsBuilder.setLatencyMicros(ConnectivityUtils.saturatedCast(mWatch.stop()));
         mStatsBuilder.setValidationIndex(mValidationIndex);
         // write a random value(0 ~ 999) for sampling.
         mStatsBuilder.setRandomNumber((int) (Math.random() * 1000));
diff --git a/src/com/android/networkstack/netlink/TcpSocketTracker.java b/src/com/android/networkstack/netlink/TcpSocketTracker.java
index ef33f13..770e85a 100644
--- a/src/com/android/networkstack/netlink/TcpSocketTracker.java
+++ b/src/com/android/networkstack/netlink/TcpSocketTracker.java
@@ -65,6 +65,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.DeviceConfigUtils;
 import com.android.networkstack.apishim.NetworkShimImpl;
 import com.android.networkstack.apishim.common.ShimUtils;
 import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
@@ -569,7 +570,7 @@
          */
         public int getDeviceConfigPropertyInt(@NonNull final String namespace,
                 @NonNull final String name, final int defaultValue) {
-            return NetworkStackUtils.getDeviceConfigPropertyInt(namespace, name, defaultValue);
+            return DeviceConfigUtils.getDeviceConfigPropertyInt(namespace, name, defaultValue);
         }
 
         /**
diff --git a/src/com/android/server/NetworkStackService.java b/src/com/android/server/NetworkStackService.java
index 512f221..903a5a8 100644
--- a/src/com/android/server/NetworkStackService.java
+++ b/src/com/android/server/NetworkStackService.java
@@ -19,8 +19,8 @@
 import static android.net.dhcp.IDhcpServer.STATUS_INVALID_ARGUMENT;
 import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
 import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR;
-import static android.net.util.NetworkStackUtils.getResBooleanConfig;
 
+import static com.android.net.module.util.DeviceConfigUtils.getResBooleanConfig;
 import static com.android.server.util.PermissionUtil.checkDumpPermission;
 
 import android.app.Service;
diff --git a/src/com/android/server/connectivity/NetworkMonitor.java b/src/com/android/server/connectivity/NetworkMonitor.java
index e9b59d7..f8a9bab 100755
--- a/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/src/com/android/server/connectivity/NetworkMonitor.java
@@ -77,11 +77,11 @@
 import static android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL;
 import static android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL;
 import static android.net.util.NetworkStackUtils.TEST_URL_EXPIRATION_TIME;
-import static android.net.util.NetworkStackUtils.getResBooleanConfig;
-import static android.net.util.NetworkStackUtils.isEmpty;
-import static android.net.util.NetworkStackUtils.isIPv6ULA;
 import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
 
+import static com.android.net.module.util.CollectionUtils.isEmpty;
+import static com.android.net.module.util.ConnectivityUtils.isIPv6ULA;
+import static com.android.net.module.util.DeviceConfigUtils.getResBooleanConfig;
 import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_DNS_EVENTS;
 import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_TCP_METRICS;
 import static com.android.networkstack.apishim.ConstantsShim.TRANSPORT_TEST;
@@ -162,6 +162,7 @@
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
 import com.android.internal.util.TrafficStatsConstants;
+import com.android.net.module.util.DeviceConfigUtils;
 import com.android.networkstack.NetworkStackNotifier;
 import com.android.networkstack.R;
 import com.android.networkstack.apishim.CaptivePortalDataShimImpl;
@@ -3158,7 +3159,7 @@
         @Nullable
         public String getDeviceConfigProperty(@NonNull String namespace, @NonNull String name,
                 @Nullable String defaultValue) {
-            return NetworkStackUtils.getDeviceConfigProperty(namespace, name, defaultValue);
+            return DeviceConfigUtils.getDeviceConfigProperty(namespace, name, defaultValue);
         }
 
         /**
@@ -3171,17 +3172,17 @@
          */
         public int getDeviceConfigPropertyInt(@NonNull String namespace, @NonNull String name,
                 int defaultValue) {
-            return NetworkStackUtils.getDeviceConfigPropertyInt(namespace, name, defaultValue);
+            return DeviceConfigUtils.getDeviceConfigPropertyInt(namespace, name, defaultValue);
         }
 
         /**
          * Check whether or not one experimental feature in the connectivity namespace is
          * enabled.
          * @param name Flag name of the experiment in the connectivity namespace.
-         * @see NetworkStackUtils#isFeatureEnabled(Context, String, String)
+         * @see DeviceConfigUtils#isFeatureEnabled(Context, String, String)
          */
         public boolean isFeatureEnabled(@NonNull Context context, @NonNull String name) {
-            return NetworkStackUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY, name);
+            return DeviceConfigUtils.isFeatureEnabled(context, NAMESPACE_CONNECTIVITY, name);
         }
 
         /**
@@ -3207,7 +3208,7 @@
          */
         public boolean isFeatureEnabled(@NonNull Context context, @NonNull String namespace,
                 @NonNull String name, boolean defaultEnabled) {
-            return NetworkStackUtils.isFeatureEnabled(context, namespace, name, defaultEnabled);
+            return DeviceConfigUtils.isFeatureEnabled(context, namespace, name, defaultEnabled);
         }
 
         /**
diff --git a/tests/unit/src/android/net/util/NetworkStackUtilsTest.java b/tests/unit/src/android/net/util/NetworkStackUtilsTest.java
deleted file mode 100644
index 93ea32f..0000000
--- a/tests/unit/src/android/net/util/NetworkStackUtilsTest.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.util.NetworkStackUtils.isIPv6ULA;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.eq;
-
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.provider.DeviceConfig;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.networkstack.R;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.MockitoSession;
-
-
-/**
- * Tests for NetworkStackUtils.
- *
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class NetworkStackUtilsTest {
-    private static final String TEST_NAME_SPACE = "connectivity";
-    private static final String TEST_EXPERIMENT_FLAG = "experiment_flag";
-    private static final int TEST_FLAG_VALUE = 28;
-    private static final String TEST_FLAG_VALUE_STRING = "28";
-    private static final int TEST_DEFAULT_FLAG_VALUE = 0;
-    private static final int TEST_MAX_FLAG_VALUE = 1000;
-    private static final int TEST_MIN_FLAG_VALUE = 100;
-    private static final long TEST_PACKAGE_VERSION = 290000000;
-    private static final String TEST_PACKAGE_NAME = "NetworkStackUtilsTest";
-    private MockitoSession mSession;
-
-    @Mock private Context mContext;
-    @Mock private PackageManager mPm;
-    @Mock private PackageInfo mPi;
-    @Mock private Resources mResources;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mSession = mockitoSession().spyStatic(DeviceConfig.class).startMocking();
-
-        final PackageInfo pi = new PackageInfo();
-        pi.setLongVersionCode(TEST_PACKAGE_VERSION);
-
-        doReturn(mPm).when(mContext).getPackageManager();
-        doReturn(TEST_PACKAGE_NAME).when(mContext).getPackageName();
-        doReturn(pi).when(mPm).getPackageInfo(anyString(), anyInt());
-        doReturn(mResources).when(mContext).getResources();
-    }
-
-    @After
-    public void tearDown() {
-        mSession.finishMocking();
-    }
-
-    @Test
-    public void testGetDeviceConfigPropertyInt_Null() {
-        doReturn(null).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
-                eq(TEST_EXPERIMENT_FLAG)));
-        assertEquals(TEST_DEFAULT_FLAG_VALUE, NetworkStackUtils.getDeviceConfigPropertyInt(
-                TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG,
-                TEST_DEFAULT_FLAG_VALUE /* default value */));
-    }
-
-    @Test
-    public void testGetDeviceConfigPropertyInt_NotNull() {
-        doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
-                eq(TEST_EXPERIMENT_FLAG)));
-        assertEquals(TEST_FLAG_VALUE, NetworkStackUtils.getDeviceConfigPropertyInt(
-                TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG,
-                TEST_DEFAULT_FLAG_VALUE /* default value */));
-    }
-
-    @Test
-    public void testGetDeviceConfigPropertyInt_NormalValue() {
-        doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
-                eq(TEST_EXPERIMENT_FLAG)));
-        assertEquals(TEST_FLAG_VALUE, NetworkStackUtils.getDeviceConfigPropertyInt(
-                TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, 0 /* minimum value */,
-                TEST_MAX_FLAG_VALUE /* maximum value */,
-                TEST_DEFAULT_FLAG_VALUE /* default value */));
-    }
-
-    @Test
-    public void testGetDeviceConfigPropertyInt_NullValue() {
-        doReturn(null).when(() -> DeviceConfig.getProperty(
-                eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG)));
-        assertEquals(TEST_DEFAULT_FLAG_VALUE, NetworkStackUtils.getDeviceConfigPropertyInt(
-                TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, 0 /* minimum value */,
-                TEST_MAX_FLAG_VALUE /* maximum value */,
-                TEST_DEFAULT_FLAG_VALUE /* default value */));
-    }
-
-    @Test
-    public void testGetDeviceConfigPropertyInt_OverMaximumValue() {
-        doReturn(Integer.toString(TEST_MAX_FLAG_VALUE + 10)).when(() -> DeviceConfig.getProperty(
-                eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG)));
-        assertEquals(TEST_DEFAULT_FLAG_VALUE, NetworkStackUtils.getDeviceConfigPropertyInt(
-                TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, TEST_MIN_FLAG_VALUE /* minimum value */,
-                TEST_MAX_FLAG_VALUE /* maximum value */,
-                TEST_DEFAULT_FLAG_VALUE /* default value */));
-    }
-
-    @Test
-    public void testGetDeviceConfigPropertyInt_BelowMinimumValue() {
-        doReturn(Integer.toString(TEST_MIN_FLAG_VALUE - 10)).when(() -> DeviceConfig.getProperty(
-                eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG)));
-        assertEquals(TEST_DEFAULT_FLAG_VALUE, NetworkStackUtils.getDeviceConfigPropertyInt(
-                TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, TEST_MIN_FLAG_VALUE /* minimum value */,
-                TEST_MAX_FLAG_VALUE /* maximum value */,
-                TEST_DEFAULT_FLAG_VALUE /* default value */));
-    }
-
-    @Test
-    public void testGetDeviceConfigPropertyBoolean_Null() {
-        doReturn(null).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
-                eq(TEST_EXPERIMENT_FLAG)));
-        assertFalse(NetworkStackUtils.getDeviceConfigPropertyBoolean(
-                TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG,
-                false /* default value */));
-    }
-
-    @Test
-    public void testGetDeviceConfigPropertyBoolean_NotNull() {
-        doReturn("true").when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
-                eq(TEST_EXPERIMENT_FLAG)));
-        assertTrue(NetworkStackUtils.getDeviceConfigPropertyBoolean(
-                TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG,
-                false /* default value */));
-    }
-
-    @Test
-    public void testFeatureIsEnabledWithExceptionsEnabled() {
-        doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
-                eq(TEST_EXPERIMENT_FLAG)));
-        assertTrue(NetworkStackUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
-                TEST_EXPERIMENT_FLAG));
-    }
-
-    @Test
-    public void testFeatureIsNotEnabled() {
-        doReturn(null).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
-                eq(TEST_EXPERIMENT_FLAG)));
-        assertFalse(NetworkStackUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
-                TEST_EXPERIMENT_FLAG));
-    }
-
-    @Test
-    public void testFeatureIsEnabledWithException() throws Exception {
-        doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
-                eq(TEST_EXPERIMENT_FLAG)));
-        doThrow(NameNotFoundException.class).when(mPm).getPackageInfo(anyString(), anyInt());
-        assertFalse(NetworkStackUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
-                TEST_EXPERIMENT_FLAG));
-    }
-
-    @Test
-    public void testIsIPv6ULA() {
-        assertTrue(isIPv6ULA(parseNumericAddress("fc00::")));
-        assertTrue(isIPv6ULA(parseNumericAddress("fc00::1")));
-        assertTrue(isIPv6ULA(parseNumericAddress("fc00:1234::5678")));
-        assertTrue(isIPv6ULA(parseNumericAddress("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
-
-        assertFalse(isIPv6ULA(parseNumericAddress("fe00::")));
-        assertFalse(isIPv6ULA(parseNumericAddress("2480:1248::123:456")));
-    }
-
-    @Test
-    public void testGetResBooleanConfig() {
-        doReturn(true).when(mResources).getBoolean(R.bool.config_no_sim_card_uses_neighbor_mcc);
-        assertTrue(NetworkStackUtils.getResBooleanConfig(mContext,
-                R.bool.config_no_sim_card_uses_neighbor_mcc, false));
-        doReturn(false).when(mResources).getBoolean(R.bool.config_no_sim_card_uses_neighbor_mcc);
-        assertFalse(NetworkStackUtils.getResBooleanConfig(mContext,
-                R.bool.config_no_sim_card_uses_neighbor_mcc, false));
-        doThrow(new Resources.NotFoundException())
-                .when(mResources).getBoolean(eq(R.bool.config_no_sim_card_uses_neighbor_mcc));
-        assertFalse(NetworkStackUtils.getResBooleanConfig(mContext,
-                R.bool.config_no_sim_card_uses_neighbor_mcc, false));
-    }
-}
\ No newline at end of file