Snap for 6618402 from ead41f5ae76a7af85a765e42a332085d3824a55e to mainline-release

Change-Id: Iec11a1ab7242639e7e9c858c1c3bc7e5a516f7e0
diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp
index 2b99a40..112799b 100644
--- a/tests/cts/net/Android.bp
+++ b/tests/cts/net/Android.bp
@@ -36,19 +36,20 @@
         "src/**/*.java",
         "src/**/*.kt",
     ],
-
+    jarjar_rules: "jarjar-rules-shared.txt",
     static_libs: [
         "FrameworksNetCommonTests",
         "TestNetworkStackLib",
-        "core-tests-support",
         "compatibility-device-util-axt",
+        "core-tests-support",
         "cts-net-utils",
         "ctstestrunner-axt",
         "ctstestserver",
-        "mockwebserver",
         "junit",
         "junit-params",
         "libnanohttpd",
+        "mockwebserver",
+        "net-utils-framework-common",
         "truth-prebuilt",
     ],
 
diff --git a/tests/cts/net/jarjar-rules-shared.txt b/tests/cts/net/jarjar-rules-shared.txt
new file mode 100644
index 0000000..11dba74
--- /dev/null
+++ b/tests/cts/net/jarjar-rules-shared.txt
@@ -0,0 +1,2 @@
+# Module library in frameworks/libs/net
+rule com.android.net.module.util.** android.net.cts.util.@1
\ No newline at end of file
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
index d17d8e5..a19ba64 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
@@ -16,6 +16,7 @@
 
 package android.net.cts;
 
+import static android.content.pm.PackageManager.FEATURE_TELEPHONY;
 import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback;
 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK;
@@ -31,9 +32,11 @@
 import static android.net.ConnectivityDiagnosticsManager.persistableBundleEquals;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_TEST;
 import static android.net.cts.util.CtsNetUtils.TestNetworkCallback;
 
+import static com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity;
 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
 
 import static org.junit.Assert.assertEquals;
@@ -41,9 +44,15 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
 
 import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.net.ConnectivityDiagnosticsManager;
 import android.net.ConnectivityManager;
 import android.net.LinkAddress;
@@ -55,13 +64,19 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.platform.test.annotations.AppModeFull;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.util.Pair;
 
 import androidx.test.InstrumentationRegistry;
 
+import com.android.internal.telephony.uicc.IccUtils;
+import com.android.internal.util.ArrayUtils;
 import com.android.testutils.ArrayTrackRecord;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
 import com.android.testutils.DevSdkIgnoreRunner;
@@ -71,7 +86,12 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
 
 @RunWith(DevSdkIgnoreRunner.class)
 @IgnoreUpTo(Build.VERSION_CODES.Q) // ConnectivityDiagnosticsManager did not exist in Q
@@ -85,6 +105,7 @@
     private static final int FAIL_RATE_PERCENTAGE = 100;
     private static final int UNKNOWN_DETECTION_METHOD = 4;
     private static final int FILTERED_UNKNOWN_DETECTION_METHOD = 0;
+    private static final int CARRIER_CONFIG_CHANGED_BROADCAST_TIMEOUT = 5000;
 
     private static final Executor INLINE_EXECUTOR = x -> x.run();
 
@@ -95,44 +116,71 @@
                     .removeCapability(NET_CAPABILITY_NOT_VPN)
                     .build();
 
-    // Callback used to keep TestNetworks up when there are no other outstanding NetworkRequests
-    // for it.
-    private static final TestNetworkCallback TEST_NETWORK_CALLBACK = new TestNetworkCallback();
+    private static final String SHA_256 = "SHA-256";
+
+    private static final NetworkRequest CELLULAR_NETWORK_REQUEST =
+            new NetworkRequest.Builder().addTransportType(TRANSPORT_CELLULAR).build();
 
     private static final IBinder BINDER = new Binder();
 
     private Context mContext;
     private ConnectivityManager mConnectivityManager;
     private ConnectivityDiagnosticsManager mCdm;
+    private CarrierConfigManager mCarrierConfigManager;
+    private PackageManager mPackageManager;
+    private TelephonyManager mTelephonyManager;
+
+    // Callback used to keep TestNetworks up when there are no other outstanding NetworkRequests
+    // for it.
+    private TestNetworkCallback mTestNetworkCallback;
     private Network mTestNetwork;
+    private ParcelFileDescriptor mTestNetworkFD;
+
+    private List<TestConnectivityDiagnosticsCallback> mRegisteredCallbacks;
 
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getContext();
         mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
         mCdm = mContext.getSystemService(ConnectivityDiagnosticsManager.class);
+        mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
+        mPackageManager = mContext.getPackageManager();
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
 
-        mConnectivityManager.requestNetwork(TEST_NETWORK_REQUEST, TEST_NETWORK_CALLBACK);
+        mTestNetworkCallback = new TestNetworkCallback();
+        mConnectivityManager.requestNetwork(TEST_NETWORK_REQUEST, mTestNetworkCallback);
+
+        mRegisteredCallbacks = new ArrayList<>();
     }
 
     @After
     public void tearDown() throws Exception {
-        mConnectivityManager.unregisterNetworkCallback(TEST_NETWORK_CALLBACK);
-
+        mConnectivityManager.unregisterNetworkCallback(mTestNetworkCallback);
         if (mTestNetwork != null) {
             runWithShellPermissionIdentity(() -> {
                 final TestNetworkManager tnm = mContext.getSystemService(TestNetworkManager.class);
                 tnm.teardownTestNetwork(mTestNetwork);
             });
+            mTestNetwork = null;
+        }
+
+        if (mTestNetworkFD != null) {
+            mTestNetworkFD.close();
+            mTestNetworkFD = null;
+        }
+
+        for (TestConnectivityDiagnosticsCallback cb : mRegisteredCallbacks) {
+            mCdm.unregisterConnectivityDiagnosticsCallback(cb);
         }
     }
 
     @Test
     public void testRegisterConnectivityDiagnosticsCallback() throws Exception {
-        mTestNetwork = setUpTestNetwork();
+        mTestNetworkFD = setUpTestNetwork().getFileDescriptor();
+        mTestNetwork = mTestNetworkCallback.waitForAvailable();
 
-        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
-        mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
+        final TestConnectivityDiagnosticsCallback cb =
+                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
 
         final String interfaceName =
                 mConnectivityManager.getLinkProperties(mTestNetwork).getInterfaceName();
@@ -142,9 +190,98 @@
     }
 
     @Test
+    public void testRegisterCallbackWithCarrierPrivileges() throws Exception {
+        assumeTrue(mPackageManager.hasSystemFeature(FEATURE_TELEPHONY));
+
+        final int subId = SubscriptionManager.getDefaultSubscriptionId();
+        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            fail("Need an active subscription. Please ensure that the device has working mobile"
+                    + " data.");
+        }
+
+        final CarrierConfigReceiver carrierConfigReceiver = new CarrierConfigReceiver(subId);
+        mContext.registerReceiver(
+                carrierConfigReceiver,
+                new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+
+        final TestNetworkCallback testNetworkCallback = new TestNetworkCallback();
+
+        try {
+            doBroadcastCarrierConfigsAndVerifyOnConnectivityReportAvailable(
+                    subId, carrierConfigReceiver, testNetworkCallback);
+        } finally {
+            runWithShellPermissionIdentity(
+                    () -> mCarrierConfigManager.overrideConfig(subId, null),
+                    android.Manifest.permission.MODIFY_PHONE_STATE);
+            mConnectivityManager.unregisterNetworkCallback(testNetworkCallback);
+            mContext.unregisterReceiver(carrierConfigReceiver);
+        }
+    }
+
+    private String getCertHashForThisPackage() throws Exception {
+        final PackageInfo pkgInfo =
+                mPackageManager.getPackageInfo(
+                        mContext.getOpPackageName(), PackageManager.GET_SIGNATURES);
+        final MessageDigest md = MessageDigest.getInstance(SHA_256);
+        final byte[] certHash = md.digest(pkgInfo.signatures[0].toByteArray());
+        return IccUtils.bytesToHexString(certHash);
+    }
+
+    private void doBroadcastCarrierConfigsAndVerifyOnConnectivityReportAvailable(
+            int subId,
+            @NonNull CarrierConfigReceiver carrierConfigReceiver,
+            @NonNull TestNetworkCallback testNetworkCallback)
+            throws Exception {
+        final PersistableBundle carrierConfigs = new PersistableBundle();
+        carrierConfigs.putStringArray(
+                CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY,
+                new String[] {getCertHashForThisPackage()});
+
+        runWithShellPermissionIdentity(
+                () -> {
+                    mCarrierConfigManager.overrideConfig(subId, carrierConfigs);
+                    mCarrierConfigManager.notifyConfigChangedForSubId(subId);
+                },
+                android.Manifest.permission.MODIFY_PHONE_STATE);
+
+        // TODO(b/157779832): This should use android.permission.CHANGE_NETWORK_STATE. However, the
+        // shell does not have CHANGE_NETWORK_STATE, so use CONNECTIVITY_INTERNAL until the shell
+        // permissions are updated.
+        runWithShellPermissionIdentity(
+                () -> mConnectivityManager.requestNetwork(
+                        CELLULAR_NETWORK_REQUEST, testNetworkCallback),
+                android.Manifest.permission.CONNECTIVITY_INTERNAL);
+
+        final Network network = testNetworkCallback.waitForAvailable();
+        assertNotNull(network);
+
+        assertTrue("Didn't receive broadcast for ACTION_CARRIER_CONFIG_CHANGED for subId=" + subId,
+                carrierConfigReceiver.waitForCarrierConfigChanged());
+        assertTrue("Don't have Carrier Privileges after adding cert for this package",
+                mTelephonyManager.createForSubscriptionId(subId).hasCarrierPrivileges());
+
+        // Wait for CarrierPrivilegesTracker to receive the ACTION_CARRIER_CONFIG_CHANGED
+        // broadcast. CPT then needs to update the corresponding DataConnection, which then
+        // updates ConnectivityService. Unfortunately, this update to the NetworkCapabilities in
+        // CS does not trigger NetworkCallback#onCapabilitiesChanged as changing the
+        // administratorUids is not a publicly visible change. In lieu of a better signal to
+        // detministically wait for, use Thread#sleep here.
+        Thread.sleep(500);
+
+        final TestConnectivityDiagnosticsCallback connDiagsCallback =
+                createAndRegisterConnectivityDiagnosticsCallback(CELLULAR_NETWORK_REQUEST);
+
+        final String interfaceName =
+                mConnectivityManager.getLinkProperties(network).getInterfaceName();
+        connDiagsCallback.expectOnConnectivityReportAvailable(
+                network, interfaceName, TRANSPORT_CELLULAR);
+        connDiagsCallback.assertNoCallback();
+    }
+
+    @Test
     public void testRegisterDuplicateConnectivityDiagnosticsCallback() {
-        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
-        mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
+        final TestConnectivityDiagnosticsCallback cb =
+                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
 
         try {
             mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
@@ -168,10 +305,11 @@
 
     @Test
     public void testOnConnectivityReportAvailable() throws Exception {
-        mTestNetwork = setUpTestNetwork();
+        final TestConnectivityDiagnosticsCallback cb =
+                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
 
-        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
-        mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
+        mTestNetworkFD = setUpTestNetwork().getFileDescriptor();
+        mTestNetwork = mTestNetworkCallback.waitForAvailable();
 
         final String interfaceName =
                 mConnectivityManager.getLinkProperties(mTestNetwork).getInterfaceName();
@@ -219,10 +357,11 @@
             long timestampMillis,
             @NonNull PersistableBundle extras)
             throws Exception {
-        mTestNetwork = setUpTestNetwork();
+        mTestNetworkFD = setUpTestNetwork().getFileDescriptor();
+        mTestNetwork = mTestNetworkCallback.waitForAvailable();
 
-        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
-        mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
+        final TestConnectivityDiagnosticsCallback cb =
+                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
 
         final String interfaceName =
                 mConnectivityManager.getLinkProperties(mTestNetwork).getInterfaceName();
@@ -250,10 +389,11 @@
     }
 
     private void verifyOnNetworkConnectivityReported(boolean hasConnectivity) throws Exception {
-        mTestNetwork = setUpTestNetwork();
+        mTestNetworkFD = setUpTestNetwork().getFileDescriptor();
+        mTestNetwork = mTestNetworkCallback.waitForAvailable();
 
-        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
-        mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
+        final TestConnectivityDiagnosticsCallback cb =
+                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
 
         // onConnectivityReportAvailable always invoked when the test network is established
         final String interfaceName =
@@ -274,17 +414,12 @@
         cb.assertNoCallback();
     }
 
-    @NonNull
-    private Network waitForConnectivityServiceIdleAndGetNetwork() throws InterruptedException {
-        // Get a new Network. This requires going through the ConnectivityService thread. Once it
-        // completes, all previously enqueued messages on the ConnectivityService main Handler have
-        // completed.
-        final TestNetworkCallback callback = new TestNetworkCallback();
-        mConnectivityManager.requestNetwork(TEST_NETWORK_REQUEST, callback);
-        final Network network = callback.waitForAvailable();
-        mConnectivityManager.unregisterNetworkCallback(callback);
-        assertNotNull(network);
-        return network;
+    private TestConnectivityDiagnosticsCallback createAndRegisterConnectivityDiagnosticsCallback(
+            NetworkRequest request) {
+        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
+        mCdm.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, cb);
+        mRegisteredCallbacks.add(cb);
+        return cb;
     }
 
     /**
@@ -292,16 +427,16 @@
      * to the Network being validated.
      */
     @NonNull
-    private Network setUpTestNetwork() throws Exception {
+    private TestNetworkInterface setUpTestNetwork() throws Exception {
         final int[] administratorUids = new int[] {Process.myUid()};
-        runWithShellPermissionIdentity(
+        return callWithShellPermissionIdentity(
                 () -> {
                     final TestNetworkManager tnm =
                             mContext.getSystemService(TestNetworkManager.class);
                     final TestNetworkInterface tni = tnm.createTunInterface(new LinkAddress[0]);
                     tnm.setupTestNetwork(tni.getInterfaceName(), administratorUids, BINDER);
+                    return tni;
                 });
-        return waitForConnectivityServiceIdleAndGetNetwork();
     }
 
     private static class TestConnectivityDiagnosticsCallback
@@ -326,13 +461,18 @@
 
         public void expectOnConnectivityReportAvailable(
                 @NonNull Network network, @NonNull String interfaceName) {
+            expectOnConnectivityReportAvailable(network, interfaceName, TRANSPORT_TEST);
+        }
+
+        public void expectOnConnectivityReportAvailable(
+                @NonNull Network network, @NonNull String interfaceName, int transportType) {
             final ConnectivityReport result =
                     (ConnectivityReport) mHistory.poll(CALLBACK_TIMEOUT_MILLIS, x -> true);
             assertEquals(network, result.getNetwork());
 
             final NetworkCapabilities nc = result.getNetworkCapabilities();
             assertNotNull(nc);
-            assertTrue(nc.hasTransport(TRANSPORT_TEST));
+            assertTrue(nc.hasTransport(transportType));
             assertNotNull(result.getLinkProperties());
             assertEquals(interfaceName, result.getLinkProperties().getInterfaceName());
 
@@ -386,4 +526,43 @@
                     mHistory.poll(NO_CALLBACK_INVOKED_TIMEOUT, x -> true));
         }
     }
+
+    private class CarrierConfigReceiver extends BroadcastReceiver {
+        private final CountDownLatch mLatch = new CountDownLatch(1);
+        private final int mSubId;
+
+        CarrierConfigReceiver(int subId) {
+            mSubId = subId;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
+                return;
+            }
+
+            final int subId =
+                    intent.getIntExtra(
+                            CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
+                            SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+            if (mSubId != subId) return;
+
+            final PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
+            if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) return;
+
+            final String[] certs =
+                    carrierConfigs.getStringArray(
+                            CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
+            try {
+                if (ArrayUtils.contains(certs, getCertHashForThisPackage())) {
+                    mLatch.countDown();
+                }
+            } catch (Exception e) {
+            }
+        }
+
+        boolean waitForCarrierConfigChanged() throws Exception {
+            return mLatch.await(CARRIER_CONFIG_CHANGED_BROADCAST_TIMEOUT, TimeUnit.MILLISECONDS);
+        }
+    }
 }