Merge "Update VpnTests for adding ESP arguments"
diff --git a/Cronet/tools/import/copy.bara.sky b/Cronet/tools/import/copy.bara.sky
new file mode 100644
index 0000000..64256a0
--- /dev/null
+++ b/Cronet/tools/import/copy.bara.sky
@@ -0,0 +1,110 @@
+# Copyright 2023 Google Inc. All rights reserved.
+#
+# 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.
+
+common_excludes = [
+ # Exclude all Android build files
+ "**/Android.bp",
+ "**/Android.mk",
+
+ # Exclude existing OWNERS files
+ "**/OWNERS",
+]
+
+cronet_origin_files = glob(
+ include = [
+ "base/**",
+ "build/**",
+ "build/buildflag.h",
+ "chrome/VERSION",
+ "components/cronet/**",
+ "components/grpc_suport/**",
+ "components/metrics/**",
+ "components/nacl/**",
+ "components/prefs/**",
+ "crypto/**",
+ "ipc/**",
+ "net/**",
+ "url/**",
+ "LICENSE",
+ ],
+ exclude = common_excludes + [
+ # Per aosp/2367109
+ "build/android/CheckInstallApk-debug.apk",
+ "build/android/unused_resources/**",
+ "build/linux/**",
+
+ # Per aosp/2374766
+ "components/cronet/ios/**",
+ "components/cronet/native/**",
+
+
+ # Exclude all third-party directories. Those are specified explicitly
+ # below, so no dependency can accidentally creep in.
+ "**/third_party/**",
+ ],
+) + glob(
+ # Explicitly include third-party dependencies.
+ # Note: some third-party dependencies include a third_party folder within
+ # them. So far, this has not become a problem.
+ include = [
+ "base/third_party/cityhash/**",
+ "base/third_party/cityhash_v103/**",
+ "base/third_party/double_conversion/**",
+ "base/third_party/dynamic_annotations/**",
+ "base/third_party/icu/**",
+ "base/third_party/nspr/**",
+ "base/third_party/superfasthash/**",
+ # TODO: we should be able to remove this dependency.
+ "base/third_party/symbolize/**",
+ "base/third_party/valgrind/**",
+ "base/third_party/xdg_user_dirs/**",
+ # Not present in source repo; requires gclient sync.
+ "buildtools/third_party/libc++/**",
+ # Not present in source repo; requires gclient sync.
+ "buildtools/third_party/libc++abi/**",
+ "net/third_party/quiche/**",
+ "net/third_party/uri_template/**",
+ "third_party/abseil-cpp/**",
+ "third_party/android_ndk/sources/android/cpufeatures/**",
+ "third_party/ashmem/**",
+ "third_party/boringssl/**",
+ "third_party/brotli/**",
+ # Not present in source repo; requires gclient sync.
+ "third_party/icu/**",
+ "third_party/libevent/**",
+ "third_party/metrics_proto/**",
+ "third_party/modp_b64/**",
+ "third_party/protobuf/**",
+ "third_party/zlib/**",
+ ],
+ exclude = common_excludes,
+)
+
+core.workflow(
+ name = "import_cronet",
+ authoring = authoring.overwrite("Cronet Mainline Eng <cronet-mainline-eng+copybara@google.com>"),
+ origin = git.origin(
+ url = "rpc://chromium/chromium/src",
+ # Source ref is set by the invoking script.
+ ref = "overwritten-by-script",
+ partial_fetch = True,
+ ),
+ origin_files = cronet_origin_files,
+ destination = git.destination(
+ # The destination URL is set by the invoking script.
+ url = "overwritten/by/script",
+ push = "upstream-import",
+ ),
+ mode = "SQUASH",
+)
diff --git a/Cronet/tools/import/import_cronet.sh b/Cronet/tools/import/import_cronet.sh
new file mode 100755
index 0000000..7642914
--- /dev/null
+++ b/Cronet/tools/import/import_cronet.sh
@@ -0,0 +1,76 @@
+#!/bin/bash
+
+# Copyright 2023 Google Inc. All rights reserved.
+#
+# 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.
+
+# Script to invoke copybara locally to import Cronet into Android.
+# Inputs:
+# Environment:
+# ANDROID_BUILD_TOP: path the root of the current Android directory.
+# Arguments:
+# -l: The last revision that was imported.
+# -n: The new revision to import.
+
+OPTSTRING=l:n:
+
+usage() {
+ cat <<EOF
+Usage: import_cronet.sh -l last-rev -n new-rev
+EOF
+ exit 1
+}
+
+#######################################
+# Runs the copybara import of Chromium
+# Globals:
+# ANDROID_BUILD_TOP
+# Arguments:
+# last_rev, string
+# new_rev, string
+#######################################
+do_run_copybara() {
+ local _last_rev=$1
+ local _new_rev=$2
+
+ /google/bin/releases/copybara/public/copybara/copybara \
+ --git-destination-url="file://${ANDROID_BUILD_TOP}/external/cronet" \
+ --last-rev "${_last_rev}" \
+ --repo-timeout 3h \
+ "${ANDROID_BUILD_TOP}/packages/modules/Connectivity/Cronet/tools/import/copy.bara.sky" \
+ import_cronet "${_new_rev}"
+}
+
+while getopts $OPTSTRING opt; do
+ case "${opt}" in
+ l) last_rev="${OPTARG}" ;;
+ n) new_rev="${OPTARG}" ;;
+ ?) usage ;;
+ *) echo "'${opt}' '${OPTARG}'"
+ esac
+done
+
+# TODO: Get last-rev from METADATA file.
+# Setting last-rev may only be required for the first commit.
+if [ -z "${last_rev}" ]; then
+ echo "-l argument required"
+ usage
+fi
+
+if [ -z "${new_rev}" ]; then
+ echo "-n argument required"
+ usage
+fi
+
+do_run_copybara "${last_rev}" "${new_rev}"
+
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 34646e2..4d3ecdf 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -58,6 +58,17 @@
]
},
{
+ "name": "CtsNetTestCasesMaxTargetSdk33",
+ "options": [
+ {
+ "exclude-annotation": "com.android.testutils.SkipPresubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.RequiresDevice"
+ }
+ ]
+ },
+ {
"name": "bpf_existence_test"
},
{
@@ -143,6 +154,17 @@
}
]
},
+ {
+ "name": "CtsNetTestCasesMaxTargetSdk33[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]",
+ "options": [
+ {
+ "exclude-annotation": "com.android.testutils.SkipPresubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.RequiresDevice"
+ }
+ ]
+ },
// Test with APK modules only, in cases where APEX is not supported, or the other modules
// were simply not updated
{
diff --git a/Tethering/AndroidManifest.xml b/Tethering/AndroidManifest.xml
index 23467e7..6a363b0 100644
--- a/Tethering/AndroidManifest.xml
+++ b/Tethering/AndroidManifest.xml
@@ -45,7 +45,6 @@
<!-- Sending non-protected broadcast from system uid is not allowed. -->
<protected-broadcast android:name="com.android.server.connectivity.tethering.DISABLE_TETHERING" />
- <protected-broadcast android:name="com.android.server.connectivity.KeepaliveTracker.TCP_POLLING_ALARM" />
<application
android:process="com.android.networkstack.process"
diff --git a/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java b/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
index cd7a842..76942ff 100644
--- a/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
+++ b/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
@@ -16,6 +16,8 @@
package com.android.server.connectivity;
+import static android.Manifest.permission.NETWORK_STACK;
+import static android.content.Context.RECEIVER_NOT_EXPORTED;
import static android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE;
import static android.net.SocketKeepalive.ERROR_INVALID_SOCKET;
import static android.net.SocketKeepalive.SUCCESS_PAUSED;
@@ -246,6 +248,7 @@
private PendingIntent createTcpPollingAlarmIntent(@NonNull Context context,
@NonNull IBinder token) {
final Intent intent = new Intent(ACTION_TCP_POLLING_ALARM);
+ intent.setPackage(context.getPackageName());
// Intent doesn't expose methods to put extra Binders, but Bundle does.
final Bundle b = new Bundle();
b.putBinder(EXTRA_BINDER_TOKEN, token);
@@ -305,7 +308,7 @@
if (SdkLevel.isAtLeastU()) {
mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_TCP_POLLING_ALARM),
- null, handler);
+ NETWORK_STACK, handler, RECEIVER_NOT_EXPORTED);
}
mAlarmManager = mContext.getSystemService(AlarmManager.class);
}
diff --git a/tests/cts/hostside/Android.bp b/tests/cts/hostside/Android.bp
index 47ea53e..ff9bd31 100644
--- a/tests/cts/hostside/Android.bp
+++ b/tests/cts/hostside/Android.bp
@@ -12,6 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+next_app_data = [ ":CtsHostsideNetworkTestsAppNext" ]
+
+// The above line is put in place to prevent any future automerger merge conflict between aosp,
+// downstream branches. The CtsHostsideNetworkTestsAppNext target will not exist in
+// some downstream branches, but it should exist in aosp and some downstream branches.
+
+
+
+
+
package {
default_applicable_licenses: ["Android-Apache-2.0"],
}
@@ -37,7 +47,6 @@
data: [
":CtsHostsideNetworkTestsApp",
":CtsHostsideNetworkTestsApp2",
- ":CtsHostsideNetworkTestsAppNext",
- ],
+ ] + next_app_data,
per_testcase_directory: true,
}
diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp
index 23cb15c..f9fe5b0 100644
--- a/tests/cts/net/Android.bp
+++ b/tests/cts/net/Android.bp
@@ -114,34 +114,39 @@
],
}
-android_test {
- name: "CtsNetTestCasesMaxTargetSdk31", // Must match CtsNetTestCasesMaxTargetSdk31 annotation.
+java_defaults {
+ name: "CtsNetTestCasesMaxTargetSdkDefaults",
defaults: [
"CtsNetTestCasesDefaults",
"CtsNetTestCasesApiStableDefaults",
],
- target_sdk_version: "31",
- package_name: "android.net.cts.maxtargetsdk31", // CTS package names must be unique.
- instrumentation_target_package: "android.net.cts.maxtargetsdk31",
test_suites: [
"cts",
"general-tests",
- "mts-networking",
+ "mts-tethering",
],
}
android_test {
+ name: "CtsNetTestCasesMaxTargetSdk33", // Must match CtsNetTestCasesMaxTargetSdk33 annotation.
+ defaults: ["CtsNetTestCasesMaxTargetSdkDefaults"],
+ target_sdk_version: "33",
+ package_name: "android.net.cts.maxtargetsdk33",
+ instrumentation_target_package: "android.net.cts.maxtargetsdk33",
+}
+
+android_test {
+ name: "CtsNetTestCasesMaxTargetSdk31", // Must match CtsNetTestCasesMaxTargetSdk31 annotation.
+ defaults: ["CtsNetTestCasesMaxTargetSdkDefaults"],
+ target_sdk_version: "31",
+ package_name: "android.net.cts.maxtargetsdk31", // CTS package names must be unique.
+ instrumentation_target_package: "android.net.cts.maxtargetsdk31",
+}
+
+android_test {
name: "CtsNetTestCasesMaxTargetSdk30", // Must match CtsNetTestCasesMaxTargetSdk30 annotation.
- defaults: [
- "CtsNetTestCasesDefaults",
- "CtsNetTestCasesApiStableDefaults",
- ],
+ defaults: ["CtsNetTestCasesMaxTargetSdkDefaults"],
target_sdk_version: "30",
package_name: "android.net.cts.maxtargetsdk30", // CTS package names must be unique.
instrumentation_target_package: "android.net.cts.maxtargetsdk30",
- test_suites: [
- "cts",
- "general-tests",
- "mts-networking",
- ],
}
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index d2a3f91..9416c66 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -3372,7 +3372,7 @@
}
private void checkFirewallBlocking(final DatagramSocket srcSock, final DatagramSocket dstSock,
- final boolean expectBlock) throws Exception {
+ final boolean expectBlock, final int chain) throws Exception {
final Random random = new Random();
final byte[] sendData = new byte[100];
random.nextBytes(sendData);
@@ -3385,11 +3385,17 @@
if (expectBlock) {
return;
}
- fail("Expect not to be blocked by firewall but sending packet was blocked");
+ fail("Expect not to be blocked by firewall but sending packet was blocked:"
+ + " chain=" + chain
+ + " chainEnabled=" + mCm.getFirewallChainEnabled(chain)
+ + " uidFirewallRule=" + mCm.getUidFirewallRule(chain, Process.myUid()));
}
if (expectBlock) {
- fail("Expect to be blocked by firewall but sending packet was not blocked");
+ fail("Expect to be blocked by firewall but sending packet was not blocked:"
+ + " chain=" + chain
+ + " chainEnabled=" + mCm.getFirewallChainEnabled(chain)
+ + " uidFirewallRule=" + mCm.getUidFirewallRule(chain, Process.myUid()));
}
dstSock.receive(pkt);
@@ -3422,25 +3428,27 @@
dstSock.setSoTimeout(SOCKET_TIMEOUT_MS);
// Chain disabled, UID not on chain.
- checkFirewallBlocking(srcSock, dstSock, EXPECT_PASS);
+ checkFirewallBlocking(srcSock, dstSock, EXPECT_PASS, chain);
// Chain enabled, UID not on chain.
mCm.setFirewallChainEnabled(chain, true /* enable */);
assertTrue(mCm.getFirewallChainEnabled(chain));
- checkFirewallBlocking(srcSock, dstSock, isAllowList ? EXPECT_BLOCK : EXPECT_PASS);
+ checkFirewallBlocking(
+ srcSock, dstSock, isAllowList ? EXPECT_BLOCK : EXPECT_PASS, chain);
// Chain enabled, UID on chain.
mCm.setUidFirewallRule(chain, myUid, ruleToAddMatch);
- checkFirewallBlocking(srcSock, dstSock, isAllowList ? EXPECT_PASS : EXPECT_BLOCK);
+ checkFirewallBlocking(
+ srcSock, dstSock, isAllowList ? EXPECT_PASS : EXPECT_BLOCK, chain);
// Chain disabled, UID on chain.
mCm.setFirewallChainEnabled(chain, false /* enable */);
assertFalse(mCm.getFirewallChainEnabled(chain));
- checkFirewallBlocking(srcSock, dstSock, EXPECT_PASS);
+ checkFirewallBlocking(srcSock, dstSock, EXPECT_PASS, chain);
// Chain disabled, UID not on chain.
mCm.setUidFirewallRule(chain, myUid, ruleToRemoveMatch);
- checkFirewallBlocking(srcSock, dstSock, EXPECT_PASS);
+ checkFirewallBlocking(srcSock, dstSock, EXPECT_PASS, chain);
}, /* cleanup */ () -> {
srcSock.close();
dstSock.close();
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
index 093c7f8..77afe4f 100644
--- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
@@ -20,6 +20,8 @@
import android.net.ConnectivityManager
import android.net.ConnectivityManager.NetworkCallback
import android.net.LinkProperties
+import android.net.LocalSocket
+import android.net.LocalSocketAddress
import android.net.Network
import android.net.NetworkAgentConfig
import android.net.NetworkCapabilities
@@ -63,6 +65,8 @@
import android.util.Log
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.runner.AndroidJUnit4
+import com.android.compatibility.common.util.PollingCheck
+import com.android.compatibility.common.util.PropertyUtil
import com.android.net.module.util.ArrayTrackRecord
import com.android.net.module.util.TrackRecord
import com.android.networkstack.apishim.NsdShimImpl
@@ -72,14 +76,17 @@
import com.android.testutils.TestableNetworkAgent
import com.android.testutils.TestableNetworkCallback
import com.android.testutils.filters.CtsNetTestCasesMaxTargetSdk30
+import com.android.testutils.filters.CtsNetTestCasesMaxTargetSdk33
import com.android.testutils.runAsShell
import com.android.testutils.tryTest
import com.android.testutils.waitForIdle
import java.io.File
+import java.io.IOException
import java.net.ServerSocket
import java.nio.charset.StandardCharsets
import java.util.Random
import java.util.concurrent.Executor
+import kotlin.math.min
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertNotNull
@@ -763,6 +770,69 @@
}
}
+ private fun checkConnectSocketToMdnsd(shouldFail: Boolean) {
+ val discoveryRecord = NsdDiscoveryRecord()
+ val localSocket = LocalSocket()
+ tryTest {
+ // Discover any service from NsdManager to enforce NsdService to start the mdnsd.
+ nsdManager.discoverServices(serviceType, NsdManager.PROTOCOL_DNS_SD, discoveryRecord)
+ discoveryRecord.expectCallback<DiscoveryStarted>()
+
+ // Checks the /dev/socket/mdnsd is created.
+ val socket = File("/dev/socket/mdnsd")
+ val doesSocketExist = PollingCheck.waitFor(
+ TIMEOUT_MS,
+ {
+ socket.exists()
+ },
+ { isSocketExist ->
+ isSocketExist
+ },
+ )
+
+ // If the socket is not created, then no need to check the access.
+ if (doesSocketExist) {
+ // Create a LocalSocket and try to connect to mdnsd.
+ assertFalse("LocalSocket is connected.", localSocket.isConnected)
+ val address = LocalSocketAddress("mdnsd", LocalSocketAddress.Namespace.RESERVED)
+ if (shouldFail) {
+ assertFailsWith<IOException>("Expect fail but socket connected") {
+ localSocket.connect(address)
+ }
+ } else {
+ localSocket.connect(address)
+ assertTrue("LocalSocket is not connected.", localSocket.isConnected)
+ }
+ }
+ } cleanup {
+ localSocket.close()
+ nsdManager.stopServiceDiscovery(discoveryRecord)
+ discoveryRecord.expectCallback<DiscoveryStopped>()
+ }
+ }
+
+ /**
+ * Starting from Android U, the access to the /dev/socket/mdnsd is blocked by the
+ * sepolicy(b/265364111).
+ */
+ @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
+ @Test
+ fun testCannotConnectSocketToMdnsd() {
+ val targetSdkVersion = context.packageManager
+ .getTargetSdkVersion(context.applicationInfo.packageName)
+ assumeTrue(targetSdkVersion >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ val firstApiLevel = min(PropertyUtil.getFirstApiLevel(), PropertyUtil.getVendorApiLevel())
+ // The sepolicy is implemented in the vendor image, so the access may not be blocked if
+ // the vendor image is not update to date.
+ assumeTrue(firstApiLevel >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ checkConnectSocketToMdnsd(shouldFail = true)
+ }
+
+ @Test @CtsNetTestCasesMaxTargetSdk33("mdnsd socket is accessible up to target SDK 33")
+ fun testCanConnectSocketToMdnsd() {
+ checkConnectSocketToMdnsd(shouldFail = false)
+ }
+
@Test @CtsNetTestCasesMaxTargetSdk30("Socket is started with the service up to target SDK 30")
fun testManagerCreatesLegacySocket() {
nsdManager // Ensure the lazy-init member is initialized, so NsdManager is created