Merge "[RFPM03] Check permission by uid."
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 9c994eb..8b9b0c1 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -608,7 +608,7 @@
     public static final int TYPE_BLUETOOTH   = 7;
 
     /**
-     * Dummy data connection.  This should not be used on shipping devices.
+     * Fake data connection.  This should not be used on shipping devices.
      * @deprecated This is not used any more.
      */
     @Deprecated
@@ -1084,9 +1084,9 @@
      *                   to remove an existing always-on VPN configuration.
      * @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or
      *        {@code false} otherwise.
-     * @param lockdownWhitelist The list of packages that are allowed to access network directly
+     * @param lockdownAllowlist The list of packages that are allowed to access network directly
      *         when VPN is in lockdown mode but is not running. Non-existent packages are ignored so
-     *         this method must be called when a package that should be whitelisted is installed or
+     *         this method must be called when a package that should be allowed is installed or
      *         uninstalled.
      * @return {@code true} if the package is set as always-on VPN controller;
      *         {@code false} otherwise.
@@ -1094,10 +1094,10 @@
      */
     @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
     public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
-            boolean lockdownEnabled, @Nullable List<String> lockdownWhitelist) {
+            boolean lockdownEnabled, @Nullable List<String> lockdownAllowlist) {
         try {
             return mService.setAlwaysOnVpnPackage(
-                    userId, vpnPackage, lockdownEnabled, lockdownWhitelist);
+                    userId, vpnPackage, lockdownEnabled, lockdownAllowlist);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java
index e449615..713b688 100644
--- a/core/java/android/net/NetworkState.java
+++ b/core/java/android/net/NetworkState.java
@@ -28,7 +28,7 @@
  * @hide
  */
 public class NetworkState implements Parcelable {
-    private static final boolean SANITY_CHECK_ROAMING = false;
+    private static final boolean VALIDATE_ROAMING_STATE = false;
 
     public static final NetworkState EMPTY = new NetworkState(null, null, null, null, null, null);
 
@@ -52,7 +52,7 @@
 
         // This object is an atomic view of a network, so the various components
         // should always agree on roaming state.
-        if (SANITY_CHECK_ROAMING && networkInfo != null && networkCapabilities != null) {
+        if (VALIDATE_ROAMING_STATE && networkInfo != null && networkCapabilities != null) {
             if (networkInfo.isRoaming() == networkCapabilities
                     .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)) {
                 Slog.wtf("NetworkState", "Roaming state disagreement between " + networkInfo
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 0b92b95..1e004e4 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -476,4 +476,35 @@
 
         return true;
     }
+
+    /**
+     * Safely multiple a value by a rational.
+     * <p>
+     * Internally it uses integer-based math whenever possible, but switches
+     * over to double-based math if values would overflow.
+     * @hide
+     */
+    public static long multiplySafeByRational(long value, long num, long den) {
+        if (den == 0) {
+            throw new ArithmeticException("Invalid Denominator");
+        }
+        long x = value;
+        long y = num;
+
+        // Logic shamelessly borrowed from Math.multiplyExact()
+        long r = x * y;
+        long ax = Math.abs(x);
+        long ay = Math.abs(y);
+        if (((ax | ay) >>> 31 != 0)) {
+            // Some bits greater than 2^31 that might cause overflow
+            // Check the result using the divide operator
+            // and check for the special case of Long.MIN_VALUE * -1
+            if (((y != 0) && (r / y != x)) ||
+                    (x == Long.MIN_VALUE && y == -1)) {
+                // Use double math to avoid overflowing
+                return (long) (((double) num / den) * value);
+            }
+        }
+        return r / den;
+    }
 }
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index bc85374..e6346ea 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -4226,7 +4226,7 @@
             callback.expectError(SocketKeepalive.ERROR_INVALID_IP_ADDRESS);
         }
 
-        // Sanity check before testing started keepalive.
+        // Basic check before testing started keepalive.
         try (SocketKeepalive ka = mCm.createSocketKeepalive(
                 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
             ka.start(validKaInterval);
diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
index 551498f..e83d2a9 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
@@ -23,11 +23,12 @@
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.NetworkStatsHistory.FIELD_ALL;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
+import static android.net.NetworkUtils.multiplySafeByRational;
 import static android.os.Process.myUid;
 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
 
-import static com.android.server.net.NetworkStatsCollection.multiplySafe;
+import static com.android.testutils.MiscAssertsKt.assertThrows;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -505,23 +506,25 @@
     }
 
     @Test
-    public void testMultiplySafe() {
-        assertEquals(25, multiplySafe(50, 1, 2));
-        assertEquals(100, multiplySafe(50, 2, 1));
+    public void testMultiplySafeRational() {
+        assertEquals(25, multiplySafeByRational(50, 1, 2));
+        assertEquals(100, multiplySafeByRational(50, 2, 1));
 
-        assertEquals(-10, multiplySafe(30, -1, 3));
-        assertEquals(0, multiplySafe(30, 0, 3));
-        assertEquals(10, multiplySafe(30, 1, 3));
-        assertEquals(20, multiplySafe(30, 2, 3));
-        assertEquals(30, multiplySafe(30, 3, 3));
-        assertEquals(40, multiplySafe(30, 4, 3));
+        assertEquals(-10, multiplySafeByRational(30, -1, 3));
+        assertEquals(0, multiplySafeByRational(30, 0, 3));
+        assertEquals(10, multiplySafeByRational(30, 1, 3));
+        assertEquals(20, multiplySafeByRational(30, 2, 3));
+        assertEquals(30, multiplySafeByRational(30, 3, 3));
+        assertEquals(40, multiplySafeByRational(30, 4, 3));
 
         assertEquals(100_000_000_000L,
-                multiplySafe(300_000_000_000L, 10_000_000_000L, 30_000_000_000L));
+                multiplySafeByRational(300_000_000_000L, 10_000_000_000L, 30_000_000_000L));
         assertEquals(100_000_000_010L,
-                multiplySafe(300_000_000_000L, 10_000_000_001L, 30_000_000_000L));
+                multiplySafeByRational(300_000_000_000L, 10_000_000_001L, 30_000_000_000L));
         assertEquals(823_202_048L,
-                multiplySafe(4_939_212_288L, 2_121_815_528L, 12_730_893_165L));
+                multiplySafeByRational(4_939_212_288L, 2_121_815_528L, 12_730_893_165L));
+
+        assertThrows(ArithmeticException.class, () -> multiplySafeByRational(30, 3, 0));
     }
 
     /**