Merge "BpfRingbuf: support 32 bit userspace"
diff --git a/staticlibs/device/com/android/net/module/util/FdEventsReader.java b/staticlibs/device/com/android/net/module/util/FdEventsReader.java
index 4825992..f88883b 100644
--- a/staticlibs/device/com/android/net/module/util/FdEventsReader.java
+++ b/staticlibs/device/com/android/net/module/util/FdEventsReader.java
@@ -180,6 +180,17 @@
     }
 
     /**
+     * Called by the subclasses of FdEventsReader, decide whether it should stop reading from the
+     * socket or process the packet and continue to read upon receiving a zero-length packet.
+     *
+     * @return {@code true} if this FdEventsReader should process the zero-length packet.
+     *         {@code false} if it should stop reading from the socket.
+     */
+    protected boolean shouldProcessZeroLengthPacket() {
+        return false; // by default, stop reading upon receiving zero-length packet.
+    }
+
+    /**
      * Called by the main loop to log errors.  In some cases |e| may be null.
      */
     protected void logError(@NonNull String msg, @Nullable Exception e) {}
@@ -235,7 +246,7 @@
 
             try {
                 bytesRead = readPacket(mFd, mBuffer);
-                if (bytesRead < 1) {
+                if (bytesRead == 0 && !shouldProcessZeroLengthPacket()) {
                     if (isRunning()) logError("Socket closed, exiting", null);
                     break;
                 }
diff --git a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
index 70c0f89..65c0b72 100644
--- a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
+++ b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
@@ -99,6 +99,30 @@
 #define KVER(a, b, c) (((a) << 24) + ((b) << 16) + (c))
 #define KVER_INF 0xFFFFFFFFu
 
+/*
+ * BPFFS (ie. /sys/fs/bpf) labelling is as follows:
+ *   subdirectory   selinux context      mainline  usecase / usable by
+ *   /              fs_bpf               no [*]    core operating system (ie. platform)
+ *   /loader        fs_bpf_loader        no, U+    (as yet unused)
+ *   /net_private   fs_bpf_net_private   yes, T+   network_stack
+ *   /net_shared    fs_bpf_net_shared    yes, T+   network_stack & system_server
+ *   /netd_readonly fs_bpf_netd_readonly yes, T+   network_stack & system_server & r/o to netd
+ *   /netd_shared   fs_bpf_netd_shared   yes, T+   network_stack & system_server & netd [**]
+ *   /tethering     fs_bpf_tethering     yes, S+   network_stack
+ *   /vendor        fs_bpf_vendor        no, T+    vendor
+ *
+ * [*] initial support for bpf was added back in P,
+ *     but things worked differently back then with no bpfloader,
+ *     and instead netd doing stuff by hand,
+ *     bpfloader with pinning into /sys/fs/bpf was (I believe) added in Q
+ *     (and was definitely there in R).
+ *
+ * [**] additionally bpf programs are accessible to netutils_wrapper
+ *      for use by iptables xt_bpf extensions.
+ *
+ * See cs/p:aosp-master%20-file:prebuilts/%20file:genfs_contexts%20"genfscon%20bpf"
+ */
+
 /* generic functions */
 
 /*
diff --git a/staticlibs/testutils/Android.bp b/staticlibs/testutils/Android.bp
index 3382156..be4ccfe 100644
--- a/staticlibs/testutils/Android.bp
+++ b/staticlibs/testutils/Android.bp
@@ -83,5 +83,5 @@
     ],
     libs: ["tradefed"],
     test_suites: ["ats", "device-tests", "general-tests", "cts", "mts-networking"],
-    data: [":ConnectivityChecker"],
+    data: [":ConnectivityTestPreparer"],
 }
diff --git a/staticlibs/testutils/app/connectivitychecker/Android.bp b/staticlibs/testutils/app/connectivitychecker/Android.bp
index 58f22db..f7118cf 100644
--- a/staticlibs/testutils/app/connectivitychecker/Android.bp
+++ b/staticlibs/testutils/app/connectivitychecker/Android.bp
@@ -17,7 +17,7 @@
 }
 
 android_test_helper_app {
-    name: "ConnectivityChecker",
+    name: "ConnectivityTestPreparer",
     srcs: ["src/**/*.kt"],
     sdk_version: "system_current",
     // Allow running the test on any device with SDK Q+, even when built from a branch that uses
diff --git a/staticlibs/testutils/app/connectivitychecker/AndroidManifest.xml b/staticlibs/testutils/app/connectivitychecker/AndroidManifest.xml
index 8e5958c..015b41f 100644
--- a/staticlibs/testutils/app/connectivitychecker/AndroidManifest.xml
+++ b/staticlibs/testutils/app/connectivitychecker/AndroidManifest.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.testutils.connectivitychecker">
+          package="com.android.testutils.connectivitypreparer">
 
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@@ -27,6 +27,6 @@
     <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.testutils.connectivitychecker"
-                     android:label="Connectivity checker target preparer" />
+                     android:targetPackage="com.android.testutils.connectivitypreparer"
+                     android:label="Connectivity test target preparer" />
 </manifest>
diff --git a/staticlibs/testutils/app/connectivitychecker/src/com/android/testutils/connectivitychecker/ConnectivityCheckTest.kt b/staticlibs/testutils/app/connectivitychecker/src/com/android/testutils/connectivitypreparer/ConnectivityCheckTest.kt
similarity index 92%
rename from staticlibs/testutils/app/connectivitychecker/src/com/android/testutils/connectivitychecker/ConnectivityCheckTest.kt
rename to staticlibs/testutils/app/connectivitychecker/src/com/android/testutils/connectivitypreparer/ConnectivityCheckTest.kt
index f72938d..6bcb8fc 100644
--- a/staticlibs/testutils/app/connectivitychecker/src/com/android/testutils/connectivitychecker/ConnectivityCheckTest.kt
+++ b/staticlibs/testutils/app/connectivitychecker/src/com/android/testutils/connectivitypreparer/ConnectivityCheckTest.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.testutils.connectivitychecker
+package com.android.testutils.connectivitypreparer
 
 import android.content.pm.PackageManager.FEATURE_TELEPHONY
 import android.content.pm.PackageManager.FEATURE_WIFI
@@ -40,7 +40,7 @@
     val pm by lazy { context.packageManager }
 
     @Test
-    fun testCheckDeviceSetup() {
+    fun testCheckConnectivity() {
         checkWifiSetup()
         checkTelephonySetup()
     }
@@ -57,10 +57,11 @@
 
         val commonError = "Check the test bench. To run the tests anyway for quick & dirty local " +
                 "testing, you can use atest X -- " +
-                "--test-arg com.android.testutils.ConnectivityCheckTargetPreparer:disable:true"
+                "--test-arg com.android.testutils.ConnectivityTestTargetPreparer" +
+                ":ignore-connectivity-check:true"
         // Do not use assertEquals: it outputs "expected X, was Y", which looks like a test failure
         if (tm.simState == TelephonyManager.SIM_STATE_ABSENT) {
-            fail("The device has no SIM card inserted. " + commonError)
+            fail("The device has no SIM card inserted. $commonError")
         } else if (tm.simState != TelephonyManager.SIM_STATE_READY) {
             fail("The device is not setup with a usable SIM card. Sim state was ${tm.simState}. " +
                     commonError)
diff --git a/staticlibs/testutils/host/com/android/testutils/ConnectivityCheckTargetPreparer.kt b/staticlibs/testutils/host/com/android/testutils/ConnectivityCheckTargetPreparer.kt
deleted file mode 100644
index ccc4064..0000000
--- a/staticlibs/testutils/host/com/android/testutils/ConnectivityCheckTargetPreparer.kt
+++ /dev/null
@@ -1,80 +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.testutils
-
-import com.android.ddmlib.testrunner.TestResult
-import com.android.tradefed.invoker.TestInformation
-import com.android.tradefed.result.CollectingTestListener
-import com.android.tradefed.result.ddmlib.DefaultRemoteAndroidTestRunner
-import com.android.tradefed.targetprep.BaseTargetPreparer
-import com.android.tradefed.targetprep.TargetSetupError
-import com.android.tradefed.targetprep.suite.SuiteApkInstaller
-
-private const val CONNECTIVITY_CHECKER_APK = "ConnectivityChecker.apk"
-private const val CONNECTIVITY_PKG_NAME = "com.android.testutils.connectivitychecker"
-// As per the <instrumentation> defined in the checker manifest
-private const val CONNECTIVITY_CHECK_RUNNER_NAME = "androidx.test.runner.AndroidJUnitRunner"
-
-/**
- * A target preparer that verifies that the device was setup correctly for connectivity tests.
- *
- * For quick and dirty local testing, can be disabled by running tests with
- * "atest -- --test-arg com.android.testutils.ConnectivityCheckTargetPreparer:disable:true".
- */
-class ConnectivityCheckTargetPreparer : BaseTargetPreparer() {
-    val installer = SuiteApkInstaller()
-
-    override fun setUp(testInformation: TestInformation) {
-        if (isDisabled) return
-        installer.setCleanApk(true)
-        installer.addTestFileName(CONNECTIVITY_CHECKER_APK)
-        installer.setShouldGrantPermission(true)
-        installer.setUp(testInformation)
-
-        val runner = DefaultRemoteAndroidTestRunner(
-                CONNECTIVITY_PKG_NAME,
-                CONNECTIVITY_CHECK_RUNNER_NAME,
-                testInformation.device.iDevice)
-        runner.runOptions = "--no-hidden-api-checks"
-
-        val receiver = CollectingTestListener()
-        if (!testInformation.device.runInstrumentationTests(runner, receiver)) {
-            throw TargetSetupError("Device state check failed to complete",
-                    testInformation.device.deviceDescriptor)
-        }
-
-        val runResult = receiver.currentRunResults
-        if (runResult.isRunFailure) {
-            throw TargetSetupError("Failed to check device state before the test: " +
-                    runResult.runFailureMessage, testInformation.device.deviceDescriptor)
-        }
-
-        if (!runResult.hasFailedTests()) return
-        val errorMsg = runResult.testResults.mapNotNull { (testDescription, testResult) ->
-            if (TestResult.TestStatus.FAILURE != testResult.status) null
-            else "$testDescription: ${testResult.stackTrace}"
-        }.joinToString("\n")
-
-        throw TargetSetupError("Device setup checks failed. Check the test bench: \n$errorMsg",
-                testInformation.device.deviceDescriptor)
-    }
-
-    override fun tearDown(testInformation: TestInformation?, e: Throwable?) {
-        if (isTearDownDisabled) return
-        installer.tearDown(testInformation, e)
-    }
-}
\ No newline at end of file
diff --git a/staticlibs/testutils/host/com/android/testutils/ConnectivityTestTargetPreparer.kt b/staticlibs/testutils/host/com/android/testutils/ConnectivityTestTargetPreparer.kt
new file mode 100644
index 0000000..3fc74aa
--- /dev/null
+++ b/staticlibs/testutils/host/com/android/testutils/ConnectivityTestTargetPreparer.kt
@@ -0,0 +1,116 @@
+/*
+ * 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.testutils
+
+import com.android.ddmlib.testrunner.TestResult
+import com.android.tradefed.config.Option
+import com.android.tradefed.invoker.TestInformation
+import com.android.tradefed.result.CollectingTestListener
+import com.android.tradefed.result.ddmlib.DefaultRemoteAndroidTestRunner
+import com.android.tradefed.targetprep.BaseTargetPreparer
+import com.android.tradefed.targetprep.TargetSetupError
+import com.android.tradefed.targetprep.suite.SuiteApkInstaller
+
+private const val CONNECTIVITY_CHECKER_APK = "ConnectivityTestPreparer.apk"
+private const val CONNECTIVITY_PKG_NAME = "com.android.testutils.connectivitypreparer"
+private const val CONNECTIVITY_CHECK_CLASS = "$CONNECTIVITY_PKG_NAME.ConnectivityCheckTest"
+// As per the <instrumentation> defined in the checker manifest
+private const val CONNECTIVITY_CHECK_RUNNER_NAME = "androidx.test.runner.AndroidJUnitRunner"
+private const val IGNORE_CONN_CHECK_OPTION = "ignore-connectivity-check"
+
+/**
+ * A target preparer that sets up and verifies a device for connectivity tests.
+ *
+ * For quick and dirty local testing, the connectivity check can be disabled by running tests with
+ * "atest -- \
+ * --test-arg com.android.testutils.ConnectivityTestTargetPreparer:ignore-connectivity-check:true".
+ */
+open class ConnectivityTestTargetPreparer : BaseTargetPreparer() {
+    private val installer = SuiteApkInstaller()
+
+    @Option(name = IGNORE_CONN_CHECK_OPTION,
+            description = "Disables the check for mobile data and wifi")
+    private var ignoreConnectivityCheck = false
+
+    override fun setUp(testInformation: TestInformation) {
+        if (isDisabled) return
+        disableGmsUpdate(testInformation)
+        runPreparerApk(testInformation)
+    }
+
+    private fun runPreparerApk(testInformation: TestInformation) {
+        installer.setCleanApk(true)
+        installer.addTestFileName(CONNECTIVITY_CHECKER_APK)
+        installer.setShouldGrantPermission(true)
+        installer.setUp(testInformation)
+
+        val runner = DefaultRemoteAndroidTestRunner(
+                CONNECTIVITY_PKG_NAME,
+                CONNECTIVITY_CHECK_RUNNER_NAME,
+                testInformation.device.iDevice)
+        runner.runOptions = "--no-hidden-api-checks"
+
+        val receiver = CollectingTestListener()
+        if (!testInformation.device.runInstrumentationTests(runner, receiver)) {
+            throw TargetSetupError("Device state check failed to complete",
+                    testInformation.device.deviceDescriptor)
+        }
+
+        val runResult = receiver.currentRunResults
+        if (runResult.isRunFailure) {
+            throw TargetSetupError("Failed to check device state before the test: " +
+                    runResult.runFailureMessage, testInformation.device.deviceDescriptor)
+        }
+
+        val ignoredTestClasses = mutableSetOf<String>()
+        if (ignoreConnectivityCheck) {
+            ignoredTestClasses.add(CONNECTIVITY_CHECK_CLASS)
+        }
+
+        val errorMsg = runResult.testResults.mapNotNull { (testDescription, testResult) ->
+            if (TestResult.TestStatus.FAILURE != testResult.status ||
+                    ignoredTestClasses.contains(testDescription.className)) {
+                null
+            } else {
+                "$testDescription: ${testResult.stackTrace}"
+            }
+        }.joinToString("\n")
+        if (errorMsg.isBlank()) return
+
+        throw TargetSetupError("Device setup checks failed. Check the test bench: \n$errorMsg",
+                testInformation.device.deviceDescriptor)
+    }
+
+    private fun disableGmsUpdate(testInformation: TestInformation) {
+        // This will be a no-op on devices without root (su) or not using gservices, but that's OK.
+        testInformation.device.executeShellCommand("su 0 am broadcast " +
+                "-a com.google.gservices.intent.action.GSERVICES_OVERRIDE " +
+                "-e finsky.play_services_auto_update_enabled false")
+    }
+
+    private fun clearGmsUpdateOverride(testInformation: TestInformation) {
+        testInformation.device.executeShellCommand("su 0 am broadcast " +
+                "-a com.google.gservices.intent.action.GSERVICES_OVERRIDE " +
+                "--esn finsky.play_services_auto_update_enabled")
+    }
+
+    override fun tearDown(testInformation: TestInformation, e: Throwable?) {
+        if (isTearDownDisabled) return
+        installer.tearDown(testInformation, e)
+        clearGmsUpdateOverride(testInformation)
+    }
+}