Merge "Change to REQUEST from LISTEN for mobile data preferred uids feature" into sc-dev
diff --git a/framework/Android.bp b/framework/Android.bp
index a447a9c..5e7262a 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -76,8 +76,6 @@
         ],
     },
     impl_only_libs: [
-        // TODO (b/183097033) remove once module_current includes core_platform
-        "stable.core.platform.api.stubs",
         "framework-tethering.stubs.module_lib",
         "framework-wifi.stubs.module_lib",
         "net-utils-device-common",
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 758c612..2eb5fb7 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -4948,7 +4948,7 @@
                 Log.e(TAG, "Can't set proxy properties", e);
             }
             // Must flush DNS cache as new network may have different DNS resolutions.
-            InetAddressCompat.clearDnsCache();
+            InetAddress.clearDnsCache();
             // Must flush socket pool as idle sockets will be bound to previous network and may
             // cause subsequent fetches to be performed on old network.
             NetworkEventDispatcher.getInstance().dispatchNetworkConfigurationChange();
diff --git a/framework/src/android/net/InetAddressCompat.java b/framework/src/android/net/InetAddressCompat.java
deleted file mode 100644
index 6b7e75c..0000000
--- a/framework/src/android/net/InetAddressCompat.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2021 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;
-
-import android.util.Log;
-
-import java.lang.reflect.InvocationTargetException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * Compatibility utility for InetAddress core platform APIs.
- *
- * Connectivity has access to such APIs, but they are not part of the module_current stubs yet
- * (only core_current). Most stable core platform APIs are included manually in the connectivity
- * build rules, but because InetAddress is also part of the base java SDK that is earlier on the
- * classpath, the extra core platform APIs are not seen.
- *
- * TODO (b/183097033): remove this utility as soon as core_current is part of module_current
- * @hide
- */
-public class InetAddressCompat {
-
-    /**
-     * @see InetAddress#clearDnsCache()
-     */
-    public static void clearDnsCache() {
-        try {
-            InetAddress.class.getMethod("clearDnsCache").invoke(null);
-        } catch (InvocationTargetException e) {
-            if (e.getCause() instanceof RuntimeException) {
-                throw (RuntimeException) e.getCause();
-            }
-            throw new IllegalStateException("Unknown InvocationTargetException", e.getCause());
-        } catch (IllegalAccessException | NoSuchMethodException e) {
-            Log.wtf(InetAddressCompat.class.getSimpleName(), "Error clearing DNS cache", e);
-        }
-    }
-
-    /**
-     * @see InetAddress#getAllByNameOnNet(String, int)
-     */
-    public static InetAddress[] getAllByNameOnNet(String host, int netId) throws
-            UnknownHostException {
-        return (InetAddress[]) callGetByNameMethod("getAllByNameOnNet", host, netId);
-    }
-
-    /**
-     * @see InetAddress#getByNameOnNet(String, int)
-     */
-    public static InetAddress getByNameOnNet(String host, int netId) throws
-            UnknownHostException {
-        return (InetAddress) callGetByNameMethod("getByNameOnNet", host, netId);
-    }
-
-    private static Object callGetByNameMethod(String method, String host, int netId)
-            throws UnknownHostException {
-        try {
-            return InetAddress.class.getMethod(method, String.class, int.class)
-                    .invoke(null, host, netId);
-        } catch (InvocationTargetException e) {
-            if (e.getCause() instanceof UnknownHostException) {
-                throw (UnknownHostException) e.getCause();
-            }
-            if (e.getCause() instanceof RuntimeException) {
-                throw (RuntimeException) e.getCause();
-            }
-            throw new IllegalStateException("Unknown InvocationTargetException", e.getCause());
-        } catch (IllegalAccessException | NoSuchMethodException e) {
-            Log.wtf(InetAddressCompat.class.getSimpleName(), "Error calling " + method, e);
-            throw new IllegalStateException("Error querying via " + method, e);
-        }
-    }
-}
diff --git a/framework/src/android/net/Network.java b/framework/src/android/net/Network.java
index 1f49033..b3770ea 100644
--- a/framework/src/android/net/Network.java
+++ b/framework/src/android/net/Network.java
@@ -142,7 +142,7 @@
      * @throws UnknownHostException if the address lookup fails.
      */
     public InetAddress[] getAllByName(String host) throws UnknownHostException {
-        return InetAddressCompat.getAllByNameOnNet(host, getNetIdForResolv());
+        return InetAddress.getAllByNameOnNet(host, getNetIdForResolv());
     }
 
     /**
@@ -155,7 +155,7 @@
      *             if the address lookup fails.
      */
     public InetAddress getByName(String host) throws UnknownHostException {
-        return InetAddressCompat.getByNameOnNet(host, getNetIdForResolv());
+        return InetAddress.getByNameOnNet(host, getNetIdForResolv());
     }
 
     /**
diff --git a/service/Android.bp b/service/Android.bp
index c4fac90..e3f4aea 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -57,9 +57,6 @@
         ":net-module-utils-srcs",
     ],
     libs: [
-        // TODO (b/183097033) remove once system_server_current includes core_current
-        "stable.core.platform.api.stubs",
-        "android_system_server_stubs_current",
         "framework-annotations-lib",
         "framework-connectivity.impl",
         "framework-tethering.stubs.module_lib",
diff --git a/service/src/com/android/server/connectivity/OsCompat.java b/service/src/com/android/server/connectivity/OsCompat.java
deleted file mode 100644
index 57e3dcd..0000000
--- a/service/src/com/android/server/connectivity/OsCompat.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2021 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 com.android.server.connectivity;
-
-import android.system.ErrnoException;
-import android.system.Os;
-
-import java.io.FileDescriptor;
-
-/**
- * Compatibility utility for android.system.Os core platform APIs.
- *
- * Connectivity has access to such APIs, but they are not part of the module_current stubs yet
- * (only core_current). Most stable core platform APIs are included manually in the connectivity
- * build rules, but because Os is also part of the base java SDK that is earlier on the
- * classpath, the extra core platform APIs are not seen.
- *
- * TODO (b/157639992, b/183097033): remove as soon as core_current is part of system_server_current
- * @hide
- */
-public class OsCompat {
-    // This value should be correct on all architectures supported by Android, but hardcoding ioctl
-    // numbers should be avoided.
-    /**
-     * @see android.system.OsConstants#TIOCOUTQ
-     */
-    public static final int TIOCOUTQ = 0x5411;
-
-    /**
-     * @see android.system.Os#getsockoptInt(FileDescriptor, int, int)
-     */
-    public static int getsockoptInt(FileDescriptor fd, int level, int option) throws
-            ErrnoException {
-        try {
-            return (int) Os.class.getMethod(
-                    "getsockoptInt", FileDescriptor.class, int.class, int.class)
-                    .invoke(null, fd, level, option);
-        } catch (ReflectiveOperationException e) {
-            if (e.getCause() instanceof ErrnoException) {
-                throw (ErrnoException) e.getCause();
-            }
-            throw new IllegalStateException("Error calling getsockoptInt", e);
-        }
-    }
-
-    /**
-     * @see android.system.Os#ioctlInt(FileDescriptor, int)
-     */
-    public static int ioctlInt(FileDescriptor fd, int cmd) throws
-            ErrnoException {
-        try {
-            return (int) Os.class.getMethod(
-                    "ioctlInt", FileDescriptor.class, int.class).invoke(null, fd, cmd);
-        } catch (ReflectiveOperationException e) {
-            if (e.getCause() instanceof ErrnoException) {
-                throw (ErrnoException) e.getCause();
-            }
-            throw new IllegalStateException("Error calling ioctlInt", e);
-        }
-    }
-}
diff --git a/service/src/com/android/server/connectivity/TcpKeepaliveController.java b/service/src/com/android/server/connectivity/TcpKeepaliveController.java
index 73f3475..c480594 100644
--- a/service/src/com/android/server/connectivity/TcpKeepaliveController.java
+++ b/service/src/com/android/server/connectivity/TcpKeepaliveController.java
@@ -27,8 +27,7 @@
 import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.IP_TOS;
 import static android.system.OsConstants.IP_TTL;
-
-import static com.android.server.connectivity.OsCompat.TIOCOUTQ;
+import static android.system.OsConstants.TIOCOUTQ;
 
 import android.annotation.NonNull;
 import android.net.InvalidPacketException;
@@ -176,10 +175,10 @@
             }
             // Query write sequence number from SEND_QUEUE.
             Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_SEND_QUEUE);
-            tcpDetails.seq = OsCompat.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
+            tcpDetails.seq = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
             // Query read sequence number from RECV_QUEUE.
             Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_RECV_QUEUE);
-            tcpDetails.ack = OsCompat.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
+            tcpDetails.ack = Os.getsockoptInt(fd, IPPROTO_TCP, TCP_QUEUE_SEQ);
             // Switch to NO_QUEUE to prevent illegal socket read/write in repair mode.
             Os.setsockoptInt(fd, IPPROTO_TCP, TCP_REPAIR_QUEUE, TCP_NO_QUEUE);
             // Finally, check if socket is still idle. TODO : this check needs to move to
@@ -199,9 +198,9 @@
             tcpDetails.rcvWndScale = trw.rcvWndScale;
             if (tcpDetails.srcAddress.length == 4 /* V4 address length */) {
                 // Query TOS.
-                tcpDetails.tos = OsCompat.getsockoptInt(fd, IPPROTO_IP, IP_TOS);
+                tcpDetails.tos = Os.getsockoptInt(fd, IPPROTO_IP, IP_TOS);
                 // Query TTL.
-                tcpDetails.ttl = OsCompat.getsockoptInt(fd, IPPROTO_IP, IP_TTL);
+                tcpDetails.ttl = Os.getsockoptInt(fd, IPPROTO_IP, IP_TTL);
             }
         } catch (ErrnoException e) {
             Log.e(TAG, "Exception reading TCP state from socket", e);
@@ -306,7 +305,7 @@
 
     private static boolean isReceiveQueueEmpty(FileDescriptor fd)
             throws ErrnoException {
-        final int result = OsCompat.ioctlInt(fd, SIOCINQ);
+        final int result = Os.ioctlInt(fd, SIOCINQ);
         if (result != 0) {
             Log.e(TAG, "Read queue has data");
             return false;
@@ -316,7 +315,7 @@
 
     private static boolean isSendQueueEmpty(FileDescriptor fd)
             throws ErrnoException {
-        final int result = OsCompat.ioctlInt(fd, SIOCOUTQ);
+        final int result = Os.ioctlInt(fd, SIOCOUTQ);
         if (result != 0) {
             Log.e(TAG, "Write queue has data");
             return false;
diff --git a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
index a54fd64..86642ea 100644
--- a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
@@ -35,6 +35,7 @@
 import android.os.Build;
 import android.os.connectivity.CellularBatteryStats;
 import android.os.connectivity.WifiBatteryStats;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -80,6 +81,7 @@
     }
 
     @Test
+    @AppModeFull(reason = "Cannot get CHANGE_NETWORK_STATE to request wifi/cell in instant mode")
     @SkipPresubmit(reason = "Virtual hardware does not support wifi battery stats")
     public void testReportNetworkInterfaceForTransports() throws Exception {
         try {
@@ -132,6 +134,7 @@
     }
 
     @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+    @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
     @Test
     public void testReportNetworkInterfaceForTransports_throwsSecurityException()
             throws Exception {
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index be1efb6..85f0deb 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -1086,7 +1086,7 @@
         final Matcher m = Pattern.compile("^" + ssid + ";(true|false|none)$",
                 Pattern.MULTILINE | Pattern.UNIX_LINES).matcher(policyString);
         if (!m.find()) {
-            fail("Unexpected format from cmd netpolicy");
+            fail("Unexpected format from cmd netpolicy, policyString = " + policyString);
         }
         return m.group(1);
     }
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index ccc9416..7c380e3 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -101,6 +101,7 @@
 import com.android.testutils.TestableNetworkCallback
 import org.junit.After
 import org.junit.Assert.assertArrayEquals
+import org.junit.Assume.assumeFalse
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -1034,6 +1035,9 @@
 
     @Test
     fun testQosCallbackRegisterWithUnregister() {
+        // Instant apps can't bind sockets to localhost
+        // TODO: use @AppModeFull when supported by DevSdkIgnoreRunner
+        assumeFalse(realContext.packageManager.isInstantApp())
         val (agent, socket) = setupForQosCallbackTesting()
 
         val qosCallback = TestableQosCallback()
@@ -1060,6 +1064,9 @@
 
     @Test
     fun testQosCallbackOnQosSession() {
+        // Instant apps can't bind sockets to localhost
+        // TODO: use @AppModeFull when supported by DevSdkIgnoreRunner
+        assumeFalse(realContext.packageManager.isInstantApp())
         val (agent, socket) = setupForQosCallbackTesting()
         val qosCallback = TestableQosCallback()
         Executors.newSingleThreadExecutor().let { executor ->
@@ -1104,6 +1111,9 @@
 
     @Test
     fun testQosCallbackOnError() {
+        // Instant apps can't bind sockets to localhost
+        // TODO: use @AppModeFull when supported by DevSdkIgnoreRunner
+        assumeFalse(realContext.packageManager.isInstantApp())
         val (agent, socket) = setupForQosCallbackTesting()
         val qosCallback = TestableQosCallback()
         Executors.newSingleThreadExecutor().let { executor ->
@@ -1142,6 +1152,9 @@
 
     @Test
     fun testQosCallbackIdsAreMappedCorrectly() {
+        // Instant apps can't bind sockets to localhost
+        // TODO: use @AppModeFull when supported by DevSdkIgnoreRunner
+        assumeFalse(realContext.packageManager.isInstantApp())
         val (agent, socket) = setupForQosCallbackTesting()
         val qosCallback1 = TestableQosCallback()
         val qosCallback2 = TestableQosCallback()
@@ -1182,6 +1195,9 @@
 
     @Test
     fun testQosCallbackWhenNetworkReleased() {
+        // Instant apps can't bind sockets to localhost
+        // TODO: use @AppModeFull when supported by DevSdkIgnoreRunner
+        assumeFalse(realContext.packageManager.isInstantApp())
         val (agent, socket) = setupForQosCallbackTesting()
         Executors.newSingleThreadExecutor().let { executor ->
             try {
diff --git a/tests/cts/net/src/android/net/cts/PacProxyManagerTest.java b/tests/cts/net/src/android/net/cts/PacProxyManagerTest.java
index 7d5e9ff..a20f1cc 100644
--- a/tests/cts/net/src/android/net/cts/PacProxyManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/PacProxyManagerTest.java
@@ -35,6 +35,7 @@
 import android.net.ProxyInfo;
 import android.net.Uri;
 import android.os.Build;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Range;
 
@@ -145,6 +146,7 @@
         }
     }
 
+    @AppModeFull(reason = "Instant apps can't bind sockets to localhost for a test proxy server")
     @Test
     public void testSetCurrentProxyScriptUrl() throws Exception {
         // Register a PacProxyInstalledListener
diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
index 0a5e506..bd1b74a 100644
--- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
+++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
@@ -361,6 +361,7 @@
     @Test
     public void testRequestLatestEntitlementResult() throws Exception {
         assumeTrue(mTM.isTetheringSupported());
+        assumeTrue(mPm.hasSystemFeature(FEATURE_TELEPHONY));
         // Verify that requestLatestTetheringEntitlementResult() can get entitlement
         // result(TETHER_ERROR_ENTITLEMENT_UNKNOWN due to invalid downstream type) via listener.
         assertEntitlementResult(listener -> mTM.requestLatestTetheringEntitlementResult(