[MS19.2] Add constrain and total into utils

Test: atest FrameworksNetTests NetworkStaticLibTests
Bug: 204830222
Change-Id: Ib98a5d3acdec2988cebd5d184982e8b968b67b17
diff --git a/staticlibs/framework/com/android/net/module/util/CollectionUtils.java b/staticlibs/framework/com/android/net/module/util/CollectionUtils.java
index 6e1af55..312ca48 100644
--- a/staticlibs/framework/com/android/net/module/util/CollectionUtils.java
+++ b/staticlibs/framework/com/android/net/module/util/CollectionUtils.java
@@ -180,4 +180,17 @@
         }
         return matches;
     }
+
+    /**
+     * Return sum of the given long array.
+     */
+    public static long total(@Nullable long[] array) {
+        long total = 0;
+        if (array != null) {
+            for (long value : array) {
+                total += value;
+            }
+        }
+        return total;
+    }
 }
diff --git a/staticlibs/framework/com/android/net/module/util/NetworkStatsUtils.java b/staticlibs/framework/com/android/net/module/util/NetworkStatsUtils.java
index 7ea40a1..d4ad1f2 100644
--- a/staticlibs/framework/com/android/net/module/util/NetworkStatsUtils.java
+++ b/staticlibs/framework/com/android/net/module/util/NetworkStatsUtils.java
@@ -66,4 +66,20 @@
      * @hide
      */
     public static final int SUBSCRIBER_ID_MATCH_RULE_ALL = 1;
+
+    /**
+     * Return the constrained value by given the lower and upper bounds.
+     */
+    public static int constrain(int amount, int low, int high) {
+        if (low > high) throw new IllegalArgumentException("low(" + low + ") > high(" + high + ")");
+        return amount < low ? low : (amount > high ? high : amount);
+    }
+
+    /**
+     * Return the constrained value by given the lower and upper bounds.
+     */
+    public static long constrain(long amount, long low, long high) {
+        if (low > high) throw new IllegalArgumentException("low(" + low + ") > high(" + high + ")");
+        return amount < low ? low : (amount > high ? high : amount);
+    }
 }
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt b/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt
index 96648a5..911483a 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt
@@ -77,4 +77,13 @@
         assertFalse(CollectionUtils.contains(arrayOf("A", "B", "C"), "D"))
         assertFalse(CollectionUtils.contains(null, "A"))
     }
+
+    @Test
+    fun testTotal() {
+        assertEquals(10, CollectionUtils.total(longArrayOf(3, 6, 1)))
+        assertEquals(10, CollectionUtils.total(longArrayOf(6, 1, 3)))
+        assertEquals(10, CollectionUtils.total(longArrayOf(1, 3, 6)))
+        assertEquals(3, CollectionUtils.total(longArrayOf(1, 1, 1)))
+        assertEquals(0, CollectionUtils.total(null))
+    }
 }
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/NetworkStatsUtilsTest.kt b/staticlibs/tests/unit/src/com/android/net/module/util/NetworkStatsUtilsTest.kt
index 820eb9b..ff839fe 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/NetworkStatsUtilsTest.kt
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/NetworkStatsUtilsTest.kt
@@ -18,10 +18,10 @@
 
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.testutils.assertThrows
 import org.junit.Test
 import org.junit.runner.RunWith
 import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
@@ -37,10 +37,10 @@
         assertEquals(0 * 0 / 1, NetworkStatsUtils.multiplySafeByRational(0, 0, 1))
         assertEquals(0, NetworkStatsUtils.multiplySafeByRational(0, Long.MAX_VALUE, Long.MAX_VALUE))
         assertEquals(0, NetworkStatsUtils.multiplySafeByRational(Long.MAX_VALUE, 0, Long.MAX_VALUE))
-        assertThrows(ArithmeticException::class.java) {
+        assertFailsWith<ArithmeticException> {
             NetworkStatsUtils.multiplySafeByRational(7, 3, 0)
         }
-        assertThrows(ArithmeticException::class.java) {
+        assertFailsWith<ArithmeticException> {
             NetworkStatsUtils.multiplySafeByRational(0, 0, 0)
         }
 
@@ -51,8 +51,24 @@
                 Long.MAX_VALUE, 721, Long.MAX_VALUE))
         assertEquals(Long.MAX_VALUE, NetworkStatsUtils.multiplySafeByRational(
                 Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE))
-        assertThrows(ArithmeticException::class.java) {
+        assertFailsWith<ArithmeticException> {
             NetworkStatsUtils.multiplySafeByRational(Long.MAX_VALUE, Long.MAX_VALUE, 0)
         }
     }
+
+    @Test
+    fun testConstrain() {
+        assertFailsWith<IllegalArgumentException> {
+            NetworkStatsUtils.constrain(5, 6, 3) // low > high
+        }
+        assertEquals(3, NetworkStatsUtils.constrain(5, 1, 3))
+        assertEquals(3, NetworkStatsUtils.constrain(3, 1, 3))
+        assertEquals(2, NetworkStatsUtils.constrain(2, 1, 3))
+        assertEquals(1, NetworkStatsUtils.constrain(1, 1, 3))
+        assertEquals(1, NetworkStatsUtils.constrain(0, 1, 3))
+
+        assertEquals(11, NetworkStatsUtils.constrain(15, 11, 11))
+        assertEquals(11, NetworkStatsUtils.constrain(11, 11, 11))
+        assertEquals(11, NetworkStatsUtils.constrain(1, 11, 11))
+    }
 }
\ No newline at end of file