Merge sc-dev-plus-aosp-without-vendor@7634622

Merged-In: I5a33f959c8ae5a34584f57508f392038e44062e7
Change-Id: Ib4e5e75ee8bbe19806bdc2f69590d164fb75774b
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index 859f23a..cf49683 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -52,7 +52,6 @@
 import android.net.util.InterfaceSet;
 import android.net.util.PrefixUtils;
 import android.net.util.SharedLog;
-import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -67,6 +66,7 @@
 import com.android.internal.util.MessageUtils;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.modules.utils.build.SdkLevel;
 import com.android.networkstack.tethering.BpfCoordinator;
 import com.android.networkstack.tethering.BpfCoordinator.ClientInfo;
 import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
@@ -676,9 +676,7 @@
             return false;
         }
 
-        // TODO: use ShimUtils instead of explicitly checking the version here.
-        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R || "S".equals(Build.VERSION.CODENAME)
-                    || "T".equals(Build.VERSION.CODENAME)) {
+        if (SdkLevel.isAtLeastS()) {
             // DAD Proxy starts forwarding packets after IPv6 upstream is present.
             mDadProxy = mDeps.getDadProxy(getHandler(), mInterfaceParams);
         }
diff --git a/framework/src/android/net/NetworkCapabilities.java b/framework/src/android/net/NetworkCapabilities.java
index ec71d3d..5bd0af8 100644
--- a/framework/src/android/net/NetworkCapabilities.java
+++ b/framework/src/android/net/NetworkCapabilities.java
@@ -818,7 +818,7 @@
      * restrictions.
      * @hide
      */
-    public void restrictCapabilitesForTestNetwork(int creatorUid) {
+    public void restrictCapabilitiesForTestNetwork(int creatorUid) {
         final long originalCapabilities = mNetworkCapabilities;
         final long originalTransportTypes = mTransportTypes;
         final NetworkSpecifier originalSpecifier = mNetworkSpecifier;
@@ -828,7 +828,7 @@
         final TransportInfo originalTransportInfo = getTransportInfo();
         final Set<Integer> originalSubIds = getSubscriptionIds();
         clearAll();
-        if (0 != (originalCapabilities & NET_CAPABILITY_NOT_RESTRICTED)) {
+        if (0 != (originalCapabilities & (1 << NET_CAPABILITY_NOT_RESTRICTED))) {
             // If the test network is not restricted, then it is only allowed to declare some
             // specific transports. This is to minimize impact on running apps in case an app
             // run from the shell creates a test a network.
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index f1e451e..c007138 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -3263,7 +3263,7 @@
                         // the Messenger, but if this ever changes, not making a defensive copy
                         // here will give attack vectors to clients using this code path.
                         networkCapabilities = new NetworkCapabilities(networkCapabilities);
-                        networkCapabilities.restrictCapabilitesForTestNetwork(nai.creatorUid);
+                        networkCapabilities.restrictCapabilitiesForTestNetwork(nai.creatorUid);
                     }
                     processCapabilitiesFromAgent(nai, networkCapabilities);
                     updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
@@ -6772,7 +6772,7 @@
             // the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
             // sees capabilities that may be malicious, which might prevent mistakes in the future.
             networkCapabilities = new NetworkCapabilities(networkCapabilities);
-            networkCapabilities.restrictCapabilitesForTestNetwork(uid);
+            networkCapabilities.restrictCapabilitiesForTestNetwork(uid);
         }
 
         LinkProperties lp = new LinkProperties(linkProperties);
@@ -9524,6 +9524,10 @@
             @NonNull IConnectivityDiagnosticsCallback callback,
             @NonNull NetworkRequest request,
             @NonNull String callingPackageName) {
+        Objects.requireNonNull(callback, "callback must not be null");
+        Objects.requireNonNull(request, "request must not be null");
+        Objects.requireNonNull(callingPackageName, "callingPackageName must not be null");
+
         if (request.legacyType != TYPE_NONE) {
             throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated."
                     + " Please use NetworkCapabilities instead.");
@@ -9572,6 +9576,9 @@
     @Override
     public void simulateDataStall(int detectionMethod, long timestampMillis,
             @NonNull Network network, @NonNull PersistableBundle extras) {
+        Objects.requireNonNull(network, "network must not be null");
+        Objects.requireNonNull(extras, "extras must not be null");
+
         enforceAnyPermissionOf(android.Manifest.permission.MANAGE_TEST_NETWORKS,
                 android.Manifest.permission.NETWORK_STACK);
         final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
diff --git a/tests/common/java/android/net/NetworkCapabilitiesTest.java b/tests/common/java/android/net/NetworkCapabilitiesTest.java
index 493a201..3d0cb92 100644
--- a/tests/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/common/java/android/net/NetworkCapabilitiesTest.java
@@ -1167,4 +1167,48 @@
         // Ensure test case fails if new net cap is added into default cap but no update here.
         assertEquals(0, nc.getCapabilities().length);
     }
+
+    @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+    public void testRestrictCapabilitiesForTestNetwork() {
+        final int ownerUid = 1234;
+        final int[] administratorUids = {1001, ownerUid};
+        final NetworkCapabilities nonRestrictedNc = new NetworkCapabilities.Builder()
+                .addTransportType(TRANSPORT_CELLULAR)
+                .addTransportType(TRANSPORT_VPN)
+                .addCapability(NET_CAPABILITY_MMS)
+                .addCapability(NET_CAPABILITY_NOT_METERED)
+                .setAdministratorUids(administratorUids)
+                .setOwnerUid(ownerUid)
+                .setSubscriptionIds(Set.of(TEST_SUBID1)).build();
+
+        nonRestrictedNc.restrictCapabilitiesForTestNetwork(ownerUid);
+        // TRANSPORT_TEST will be appended
+        assertTrue(nonRestrictedNc.hasTransport(TRANSPORT_TEST));
+        assertEquals(Set.of(TEST_SUBID1), nonRestrictedNc.getSubscriptionIds());
+        // Non-UNRESTRICTED_TEST_NETWORKS_ALLOWED_TRANSPORTS will be removed
+        assertFalse(nonRestrictedNc.hasTransport(TRANSPORT_CELLULAR));
+        assertTrue(nonRestrictedNc.hasTransport(TRANSPORT_VPN));
+        // Only TEST_NETWORKS_ALLOWED_CAPABILITIES will be kept
+        assertFalse(nonRestrictedNc.hasCapability(NET_CAPABILITY_MMS));
+        assertTrue(nonRestrictedNc.hasCapability(NET_CAPABILITY_NOT_METERED));
+
+        final NetworkCapabilities restrictedNc = new NetworkCapabilities.Builder(nonRestrictedNc)
+                .removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
+                .addTransportType(TRANSPORT_CELLULAR)
+                .addCapability(NET_CAPABILITY_MMS).build();
+        restrictedNc.restrictCapabilitiesForTestNetwork(ownerUid);
+        // It may declare any transport if the net cap is restricted
+        assertTrue(restrictedNc.hasTransport(TRANSPORT_CELLULAR));
+        // SubIds will be cleared.
+        assertEquals(new ArraySet<>(), restrictedNc.getSubscriptionIds());
+        // Only retain the owner and administrator UIDs if they match the app registering the remote
+        // caller that registered the network.
+        assertEquals(ownerUid, restrictedNc.getOwnerUid());
+        assertArrayEquals(new int[] {ownerUid}, restrictedNc.getAdministratorUids());
+        // The creator UID does not match the owner and administrator UIDs will clear the owner and
+        // administrator UIDs.
+        restrictedNc.restrictCapabilitiesForTestNetwork(5678);
+        assertEquals(INVALID_UID, restrictedNc.getOwnerUid());
+        assertArrayEquals(new int[0], restrictedNc.getAdministratorUids());
+    }
 }
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index e9454cd..1608241 100644
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -204,6 +204,7 @@
 import android.location.LocationManager;
 import android.net.CaptivePortalData;
 import android.net.ConnectionInfo;
+import android.net.ConnectivityDiagnosticsManager.DataStallReport;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.ConnectivityManager.PacketKeepalive;
@@ -285,6 +286,7 @@
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
@@ -10257,6 +10259,35 @@
         assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder));
     }
 
+    @Test(expected = NullPointerException.class)
+    public void testRegisterConnectivityDiagnosticsCallbackNullCallback() {
+        mService.registerConnectivityDiagnosticsCallback(
+                null /* callback */,
+                new NetworkRequest.Builder().build(),
+                mContext.getPackageName());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testRegisterConnectivityDiagnosticsCallbackNullNetworkRequest() {
+        mService.registerConnectivityDiagnosticsCallback(
+                mConnectivityDiagnosticsCallback,
+                null /* request */,
+                mContext.getPackageName());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testRegisterConnectivityDiagnosticsCallbackNullPackageName() {
+        mService.registerConnectivityDiagnosticsCallback(
+                mConnectivityDiagnosticsCallback,
+                new NetworkRequest.Builder().build(),
+                null /* callingPackageName */);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testUnregisterConnectivityDiagnosticsCallbackNullPackageName() {
+        mService.unregisterConnectivityDiagnosticsCallback(null /* callback */);
+    }
+
     public NetworkAgentInfo fakeMobileNai(NetworkCapabilities nc) {
         final NetworkCapabilities cellNc = new NetworkCapabilities.Builder(nc)
                 .addTransportType(TRANSPORT_CELLULAR).build();
@@ -10567,6 +10598,24 @@
                                 areConnDiagCapsRedacted(report.getNetworkCapabilities())));
     }
 
+    @Test(expected = NullPointerException.class)
+    public void testSimulateDataStallNullNetwork() {
+        mService.simulateDataStall(
+                DataStallReport.DETECTION_METHOD_DNS_EVENTS,
+                0L /* timestampMillis */,
+                null /* network */,
+                new PersistableBundle());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testSimulateDataStallNullPersistableBundle() {
+        mService.simulateDataStall(
+                DataStallReport.DETECTION_METHOD_DNS_EVENTS,
+                0L /* timestampMillis */,
+                mock(Network.class),
+                null /* extras */);
+    }
+
     @Test
     public void testRouteAddDeleteUpdate() throws Exception {
         final NetworkRequest request = new NetworkRequest.Builder().build();