Snap for 11659684 from 7f1e36087a520ed8ad13ec200d12491dc13a312f to mainline-healthfitness-release
Change-Id: Ie7afa7db54ddf005360dcf1b39d04bf0192eeda7
diff --git a/framework-t/src/android/net/nsd/NsdServiceInfo.java b/framework-t/src/android/net/nsd/NsdServiceInfo.java
index dba08a1..9491a9c 100644
--- a/framework-t/src/android/net/nsd/NsdServiceInfo.java
+++ b/framework-t/src/android/net/nsd/NsdServiceInfo.java
@@ -16,6 +16,8 @@
package android.net.nsd;
+import static com.android.net.module.util.HexDump.toHexString;
+
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -39,6 +41,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.StringJoiner;
/**
* A class representing service information for network service discovery
@@ -541,11 +544,50 @@
.append(", network: ").append(mNetwork)
.append(", expirationTime: ").append(mExpirationTime);
- byte[] txtRecord = getTxtRecord();
- sb.append(", txtRecord: ").append(new String(txtRecord, StandardCharsets.UTF_8));
+ final StringJoiner txtJoiner =
+ new StringJoiner(", " /* delimiter */, "{" /* prefix */, "}" /* suffix */);
+
+ sb.append(", txtRecord: ");
+ for (int i = 0; i < mTxtRecord.size(); i++) {
+ txtJoiner.add(mTxtRecord.keyAt(i) + "=" + getPrintableTxtValue(mTxtRecord.valueAt(i)));
+ }
+ sb.append(txtJoiner.toString());
return sb.toString();
}
+ /**
+ * Returns printable string for {@code txtValue}.
+ *
+ * If {@code txtValue} contains non-printable ASCII characters, a HEX string with prefix "0x"
+ * will be returned. Otherwise, the ASCII string of {@code txtValue} is returned.
+ *
+ */
+ private static String getPrintableTxtValue(@Nullable byte[] txtValue) {
+ if (txtValue == null) {
+ return "(null)";
+ }
+
+ if (containsNonPrintableChars(txtValue)) {
+ return "0x" + toHexString(txtValue);
+ }
+
+ return new String(txtValue, StandardCharsets.US_ASCII);
+ }
+
+ /**
+ * Returns {@code true} if {@code txtValue} contains non-printable ASCII characters.
+ *
+ * The printable characters are in range of [32, 126].
+ */
+ private static boolean containsNonPrintableChars(byte[] txtValue) {
+ for (int i = 0; i < txtValue.length; i++) {
+ if (txtValue[i] < 32 || txtValue[i] > 126) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/** Implement the Parcelable interface */
public int describeContents() {
return 0;
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 005d617..b1ae019 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -478,6 +478,7 @@
private volatile boolean mLockdownEnabled;
private final boolean mRequestRestrictedWifiEnabled;
+ private final boolean mBackgroundFirewallChainEnabled;
/**
* Stale copy of uid blocked reasons provided by NPMS. As long as they are accessed only in
@@ -1798,6 +1799,8 @@
mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext);
mRequestRestrictedWifiEnabled = mDeps.isAtLeastU()
&& mDeps.isFeatureEnabled(context, REQUEST_RESTRICTED_WIFI);
+ mBackgroundFirewallChainEnabled = mDeps.isAtLeastV() && mDeps.isFeatureNotChickenedOut(
+ context, ConnectivityFlags.BACKGROUND_FIREWALL_CHAIN);
mCarrierPrivilegeAuthenticator = mDeps.makeCarrierPrivilegeAuthenticator(
mContext, mTelephonyManager, mRequestRestrictedWifiEnabled,
this::handleUidCarrierPrivilegesLost, mHandler);
@@ -4152,6 +4155,9 @@
pw.println();
pw.println("Multicast routing supported: " +
(mMulticastRoutingCoordinatorService != null));
+
+ pw.println();
+ pw.println("Background firewall chain enabled: " + mBackgroundFirewallChainEnabled);
}
private void dumpNetworks(IndentingPrintWriter pw) {
@@ -13521,6 +13527,12 @@
public void setUidFirewallRule(final int chain, final int uid, final int rule) {
enforceNetworkStackOrSettingsPermission();
+ if (chain == FIREWALL_CHAIN_BACKGROUND && !mBackgroundFirewallChainEnabled) {
+ Log.i(TAG, "Ignoring operation setUidFirewallRule on the background chain because the"
+ + " feature is disabled.");
+ return;
+ }
+
// There are only two type of firewall rule: FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY
int firewallRule = getFirewallRuleType(chain, rule);
@@ -13593,6 +13605,12 @@
public void setFirewallChainEnabled(final int chain, final boolean enable) {
enforceNetworkStackOrSettingsPermission();
+ if (chain == FIREWALL_CHAIN_BACKGROUND && !mBackgroundFirewallChainEnabled) {
+ Log.i(TAG, "Ignoring operation setFirewallChainEnabled on the background chain because"
+ + " the feature is disabled.");
+ return;
+ }
+
try {
mBpfNetMaps.setChildChain(chain, enable);
} catch (ServiceSpecificException e) {
@@ -13619,6 +13637,12 @@
public void replaceFirewallChain(final int chain, final int[] uids) {
enforceNetworkStackOrSettingsPermission();
+ if (chain == FIREWALL_CHAIN_BACKGROUND && !mBackgroundFirewallChainEnabled) {
+ Log.i(TAG, "Ignoring operation replaceFirewallChain on the background chain because"
+ + " the feature is disabled.");
+ return;
+ }
+
mBpfNetMaps.replaceUidChain(chain, uids);
}
diff --git a/service/src/com/android/server/connectivity/ConnectivityFlags.java b/service/src/com/android/server/connectivity/ConnectivityFlags.java
index a55c683..176307d 100644
--- a/service/src/com/android/server/connectivity/ConnectivityFlags.java
+++ b/service/src/com/android/server/connectivity/ConnectivityFlags.java
@@ -42,6 +42,8 @@
public static final String INGRESS_TO_VPN_ADDRESS_FILTERING =
"ingress_to_vpn_address_filtering";
+ public static final String BACKGROUND_FIREWALL_CHAIN = "background_firewall_chain";
+
private boolean mNoRematchAllRequestsOnRegister;
/**
diff --git a/tests/unit/java/android/net/nsd/NsdServiceInfoTest.kt b/tests/unit/java/android/net/nsd/NsdServiceInfoTest.kt
new file mode 100644
index 0000000..8f86f06
--- /dev/null
+++ b/tests/unit/java/android/net/nsd/NsdServiceInfoTest.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 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.nsd
+
+import android.os.Build
+import androidx.test.filters.SmallTest
+import com.android.testutils.ConnectivityModuleTest
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRunner
+import kotlin.test.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** Unit tests for {@link NsdServiceInfo}. */
+@SmallTest
+@ConnectivityModuleTest
+@RunWith(DevSdkIgnoreRunner::class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
+class NsdServiceInfoTest {
+ @Test
+ fun testToString_txtRecord() {
+ val info = NsdServiceInfo().apply {
+ this.setAttribute("abc", byteArrayOf(0xff.toByte(), 0xfe.toByte()))
+ this.setAttribute("def", null as String?)
+ this.setAttribute("ghi", "猫")
+ this.setAttribute("jkl", byteArrayOf(0, 0x21))
+ this.setAttribute("mno", "Hey Tom! It's you?.~{}")
+ }
+
+ val infoStr = info.toString()
+
+ assertTrue(
+ infoStr.contains("txtRecord: " +
+ "{abc=0xFFFE, def=(null), ghi=0xE78CAB, jkl=0x0021, mno=Hey Tom! It's you?.~{}}"),
+ infoStr)
+ }
+}
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 17c5901..7822fe0 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -172,6 +172,7 @@
import static com.android.server.ConnectivityServiceTestUtils.transportToLegacyType;
import static com.android.server.NetworkAgentWrapper.CallbackType.OnQosCallbackRegister;
import static com.android.server.NetworkAgentWrapper.CallbackType.OnQosCallbackUnregister;
+import static com.android.server.connectivity.ConnectivityFlags.BACKGROUND_FIREWALL_CHAIN;
import static com.android.server.connectivity.ConnectivityFlags.INGRESS_TO_VPN_ADDRESS_FILTERING;
import static com.android.testutils.Cleanup.testAndCleanup;
import static com.android.testutils.ConcurrentUtils.await;
@@ -391,6 +392,7 @@
import com.android.internal.util.WakeupMessage;
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.ArrayTrackRecord;
import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
import com.android.net.module.util.CollectionUtils;
@@ -2171,6 +2173,8 @@
return true;
case INGRESS_TO_VPN_ADDRESS_FILTERING:
return true;
+ case BACKGROUND_FIREWALL_CHAIN:
+ return true;
default:
return super.isFeatureNotChickenedOut(context, name);
}
@@ -10488,7 +10492,10 @@
doTestSetUidFirewallRule(FIREWALL_CHAIN_POWERSAVE, FIREWALL_RULE_DENY);
doTestSetUidFirewallRule(FIREWALL_CHAIN_RESTRICTED, FIREWALL_RULE_DENY);
doTestSetUidFirewallRule(FIREWALL_CHAIN_LOW_POWER_STANDBY, FIREWALL_RULE_DENY);
- doTestSetUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, FIREWALL_RULE_DENY);
+ if (SdkLevel.isAtLeastV()) {
+ // FIREWALL_CHAIN_BACKGROUND is only available on V+.
+ doTestSetUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, FIREWALL_RULE_DENY);
+ }
doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_1, FIREWALL_RULE_ALLOW);
doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_2, FIREWALL_RULE_ALLOW);
doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_3, FIREWALL_RULE_ALLOW);
@@ -10496,16 +10503,19 @@
@Test @IgnoreUpTo(SC_V2)
public void testSetFirewallChainEnabled() throws Exception {
- final List<Integer> firewallChains = Arrays.asList(
+ final List<Integer> firewallChains = new ArrayList<>(Arrays.asList(
FIREWALL_CHAIN_DOZABLE,
FIREWALL_CHAIN_STANDBY,
FIREWALL_CHAIN_POWERSAVE,
FIREWALL_CHAIN_RESTRICTED,
FIREWALL_CHAIN_LOW_POWER_STANDBY,
- FIREWALL_CHAIN_BACKGROUND,
FIREWALL_CHAIN_OEM_DENY_1,
FIREWALL_CHAIN_OEM_DENY_2,
- FIREWALL_CHAIN_OEM_DENY_3);
+ FIREWALL_CHAIN_OEM_DENY_3));
+ if (SdkLevel.isAtLeastV()) {
+ // FIREWALL_CHAIN_BACKGROUND is only available on V+.
+ firewallChains.add(FIREWALL_CHAIN_BACKGROUND);
+ }
for (final int chain: firewallChains) {
mCm.setFirewallChainEnabled(chain, true /* enabled */);
verify(mBpfNetMaps).setChildChain(chain, true /* enable */);
@@ -10552,7 +10562,10 @@
doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_POWERSAVE, allowlist);
doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_RESTRICTED, allowlist);
doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_LOW_POWER_STANDBY, allowlist);
- doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_BACKGROUND, allowlist);
+ if (SdkLevel.isAtLeastV()) {
+ // FIREWALL_CHAIN_BACKGROUND is only available on V+.
+ doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_BACKGROUND, allowlist);
+ }
doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_STANDBY, denylist);
doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_OEM_DENY_1, denylist);
@@ -10574,7 +10587,10 @@
doTestReplaceFirewallChain(FIREWALL_CHAIN_POWERSAVE);
doTestReplaceFirewallChain(FIREWALL_CHAIN_RESTRICTED);
doTestReplaceFirewallChain(FIREWALL_CHAIN_LOW_POWER_STANDBY);
- doTestReplaceFirewallChain(FIREWALL_CHAIN_BACKGROUND);
+ if (SdkLevel.isAtLeastV()) {
+ // FIREWALL_CHAIN_BACKGROUND is only available on V+.
+ doTestReplaceFirewallChain(FIREWALL_CHAIN_BACKGROUND);
+ }
doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_1);
doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_2);
doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_3);
diff --git a/tests/unit/java/com/android/server/connectivityservice/CSFirewallChainTest.kt b/tests/unit/java/com/android/server/connectivityservice/CSFirewallChainTest.kt
new file mode 100644
index 0000000..16de4da
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivityservice/CSFirewallChainTest.kt
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2024 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
+
+import android.net.ConnectivityManager
+import android.os.Build
+import androidx.test.filters.SmallTest
+import com.android.server.connectivity.ConnectivityFlags.BACKGROUND_FIREWALL_CHAIN
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
+import com.android.testutils.DevSdkIgnoreRunner
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mockito.any
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+
+@RunWith(DevSdkIgnoreRunner::class)
+@SmallTest
+@IgnoreUpTo(Build.VERSION_CODES.S_V2)
+class CSFirewallChainTest : CSTest() {
+ @get:Rule
+ val ignoreRule = DevSdkIgnoreRule()
+
+ // Tests for setFirewallChainEnabled on FIREWALL_CHAIN_BACKGROUND
+ @Test
+ @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, false)])
+ fun setFirewallChainEnabled_backgroundChainDisabled() {
+ verifySetFirewallChainEnabledOnBackgroundDoesNothing()
+ }
+
+ @Test
+ @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, true)])
+ @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ fun setFirewallChainEnabled_backgroundChainEnabled_afterU() {
+ cm.setFirewallChainEnabled(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, true)
+ verify(bpfNetMaps).setChildChain(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, true)
+
+ clearInvocations(bpfNetMaps)
+
+ cm.setFirewallChainEnabled(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, false)
+ verify(bpfNetMaps).setChildChain(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, false)
+ }
+
+ @Test
+ @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, true)])
+ @IgnoreAfter(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ fun setFirewallChainEnabled_backgroundChainEnabled_uptoU() {
+ verifySetFirewallChainEnabledOnBackgroundDoesNothing()
+ }
+
+ private fun verifySetFirewallChainEnabledOnBackgroundDoesNothing() {
+ cm.setFirewallChainEnabled(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, true)
+ verify(bpfNetMaps, never()).setChildChain(anyInt(), anyBoolean())
+
+ cm.setFirewallChainEnabled(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, false)
+ verify(bpfNetMaps, never()).setChildChain(anyInt(), anyBoolean())
+ }
+
+ // Tests for replaceFirewallChain on FIREWALL_CHAIN_BACKGROUND
+ @Test
+ @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, false)])
+ fun replaceFirewallChain_backgroundChainDisabled() {
+ verifyReplaceFirewallChainOnBackgroundDoesNothing()
+ }
+
+ @Test
+ @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, true)])
+ @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ fun replaceFirewallChain_backgroundChainEnabled_afterU() {
+ val uids = intArrayOf(53, 42, 79)
+ cm.replaceFirewallChain(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, uids)
+ verify(bpfNetMaps).replaceUidChain(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, uids)
+ }
+
+ @Test
+ @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, true)])
+ @IgnoreAfter(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ fun replaceFirewallChain_backgroundChainEnabled_uptoU() {
+ verifyReplaceFirewallChainOnBackgroundDoesNothing()
+ }
+
+ private fun verifyReplaceFirewallChainOnBackgroundDoesNothing() {
+ val uids = intArrayOf(53, 42, 79)
+ cm.replaceFirewallChain(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, uids)
+ verify(bpfNetMaps, never()).replaceUidChain(anyInt(), any(IntArray::class.java))
+ }
+
+ // Tests for setUidFirewallRule on FIREWALL_CHAIN_BACKGROUND
+ @Test
+ @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, false)])
+ fun setUidFirewallRule_backgroundChainDisabled() {
+ verifySetUidFirewallRuleOnBackgroundDoesNothing()
+ }
+
+ @Test
+ @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, true)])
+ @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ fun setUidFirewallRule_backgroundChainEnabled_afterU() {
+ val uid = 2345
+
+ cm.setUidFirewallRule(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, uid,
+ ConnectivityManager.FIREWALL_RULE_DEFAULT)
+ verify(bpfNetMaps).setUidRule(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, uid,
+ ConnectivityManager.FIREWALL_RULE_DENY)
+
+ clearInvocations(bpfNetMaps)
+
+ cm.setUidFirewallRule(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, uid,
+ ConnectivityManager.FIREWALL_RULE_DENY)
+ verify(bpfNetMaps).setUidRule(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, uid,
+ ConnectivityManager.FIREWALL_RULE_DENY)
+
+ clearInvocations(bpfNetMaps)
+
+ cm.setUidFirewallRule(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, uid,
+ ConnectivityManager.FIREWALL_RULE_ALLOW)
+ verify(bpfNetMaps).setUidRule(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, uid,
+ ConnectivityManager.FIREWALL_RULE_ALLOW)
+ }
+
+ @Test
+ @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, true)])
+ @IgnoreAfter(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ fun setUidFirewallRule_backgroundChainEnabled_uptoU() {
+ verifySetUidFirewallRuleOnBackgroundDoesNothing()
+ }
+
+ private fun verifySetUidFirewallRuleOnBackgroundDoesNothing() {
+ val uid = 2345
+
+ listOf(ConnectivityManager.FIREWALL_RULE_DEFAULT, ConnectivityManager.FIREWALL_RULE_ALLOW,
+ ConnectivityManager.FIREWALL_RULE_DENY).forEach { rule ->
+ cm.setUidFirewallRule(ConnectivityManager.FIREWALL_CHAIN_BACKGROUND, uid, rule)
+ verify(bpfNetMaps, never()).setUidRule(anyInt(), anyInt(), anyInt())
+ }
+ }
+}
diff --git a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt
index bd26c63..3b06ad0 100644
--- a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt
+++ b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt
@@ -161,6 +161,7 @@
it[ConnectivityService.ALLOW_SYSUI_CONNECTIVITY_REPORTS] = true
it[ConnectivityService.ALLOW_SATALLITE_NETWORK_FALLBACK] = true
it[ConnectivityFlags.INGRESS_TO_VPN_ADDRESS_FILTERING] = true
+ it[ConnectivityFlags.BACKGROUND_FIREWALL_CHAIN] = true
}
fun setFeatureEnabled(flag: String, enabled: Boolean) = enabledFeatures.set(flag, enabled)
diff --git a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
index d80dcfb..63cd574 100644
--- a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
+++ b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
@@ -699,6 +699,7 @@
new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_THREAD)
.addCapability(NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
.build();
final NetworkScore score =
diff --git a/thread/tests/cts/src/android/net/thread/cts/ThreadNetworkControllerTest.java b/thread/tests/cts/src/android/net/thread/cts/ThreadNetworkControllerTest.java
index 9a81388..ba7392c 100644
--- a/thread/tests/cts/src/android/net/thread/cts/ThreadNetworkControllerTest.java
+++ b/thread/tests/cts/src/android/net/thread/cts/ThreadNetworkControllerTest.java
@@ -17,6 +17,12 @@
package android.net.thread.cts;
import static android.Manifest.permission.ACCESS_NETWORK_STATE;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
import static android.net.thread.ThreadNetworkController.DEVICE_ROLE_CHILD;
import static android.net.thread.ThreadNetworkController.DEVICE_ROLE_LEADER;
import static android.net.thread.ThreadNetworkController.DEVICE_ROLE_ROUTER;
@@ -805,6 +811,20 @@
assertThat(isAttached(mController)).isTrue();
assertThat(networkFuture.get(NETWORK_CALLBACK_TIMEOUT_MILLIS, MILLISECONDS)).isNotNull();
+ NetworkCapabilities caps =
+ runAsShell(
+ ACCESS_NETWORK_STATE, () -> cm.getNetworkCapabilities(networkFuture.get()));
+ assertThat(caps).isNotNull();
+ assertThat(caps.hasTransport(NetworkCapabilities.TRANSPORT_THREAD)).isTrue();
+ assertThat(caps.getCapabilities())
+ .asList()
+ .containsAtLeast(
+ NET_CAPABILITY_LOCAL_NETWORK,
+ NET_CAPABILITY_NOT_METERED,
+ NET_CAPABILITY_NOT_RESTRICTED,
+ NET_CAPABILITY_NOT_VCN_MANAGED,
+ NET_CAPABILITY_NOT_VPN,
+ NET_CAPABILITY_TRUSTED);
}
private void grantPermissions(String... permissions) {
diff --git a/thread/tests/integration/src/android/net/thread/ServiceDiscoveryTest.java b/thread/tests/integration/src/android/net/thread/ServiceDiscoveryTest.java
index 491331c..5a8d21f 100644
--- a/thread/tests/integration/src/android/net/thread/ServiceDiscoveryTest.java
+++ b/thread/tests/integration/src/android/net/thread/ServiceDiscoveryTest.java
@@ -75,7 +75,6 @@
@RequiresThreadFeature
@RequiresSimulationThreadDevice
@LargeTest
-@Ignore("TODO: b/328527773 - enable the test when it's stable")
public class ServiceDiscoveryTest {
private static final String TAG = ServiceDiscoveryTest.class.getSimpleName();
private static final int NUM_FTD = 3;
@@ -103,11 +102,13 @@
private HandlerThread mHandlerThread;
private NsdManager mNsdManager;
private TapTestNetworkTracker mTestNetworkTracker;
- private List<FullThreadDevice> mFtds;
- private List<RegistrationListener> mRegistrationListeners = new ArrayList<>();
+ private final List<FullThreadDevice> mFtds = new ArrayList<>();
+ private final List<RegistrationListener> mRegistrationListeners = new ArrayList<>();
@Before
public void setUp() throws Exception {
+ mOtCtl.factoryReset();
+ mController.setEnabledAndWait(true);
mController.joinAndWait(DEFAULT_DATASET);
mNsdManager = mContext.getSystemService(NsdManager.class);
@@ -120,7 +121,6 @@
// Create the FTDs in setUp() so that the FTDs can be safely released in tearDown().
// Don't create new FTDs in test cases.
- mFtds = new ArrayList<>();
for (int i = 0; i < NUM_FTD; ++i) {
FullThreadDevice ftd = new FullThreadDevice(10 + i /* node ID */);
ftd.autoStartSrpClient();
@@ -321,6 +321,7 @@
}
@Test
+ @Ignore("TODO: b/332452386 - Enable this test case when it handles the multi-client case well")
public void discoveryProxy_multipleClientsBrowseAndResolveServiceOverMdns() throws Exception {
/*
* <pre>