[automerger skipped] Merge "Refactor the ISocketNetLinkMonitor to AbstractSocketNetlink" into tm-mainline-prod am: 961b0dd155 -s ours am: ec22caa7d8 -s ours
am skip reason: Merged-In Ie07603ea51dda1ffdeb15f753bda7892d9137766 with SHA-1 46ab01cce9 is already in history
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/22917791
Change-Id: Ib6a97c3fdc2d60394d2cf78dfebb38f8282f879d
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
index b6591a9..b0aa668 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
@@ -39,6 +39,8 @@
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import androidx.annotation.NonNull;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.DeviceConfigUtils;
@@ -158,6 +160,8 @@
public final int activeDataSubId;
+ private final Dependencies mDeps;
+
private final boolean mEnableLegacyDhcpServer;
private final int mOffloadPollInterval;
// TODO: Add to TetheringConfigurationParcel if required.
@@ -170,7 +174,31 @@
private final int mUsbTetheringFunction;
protected final ContentResolver mContentResolver;
- public TetheringConfiguration(Context ctx, SharedLog log, int id) {
+ /**
+ * A class wrapping dependencies of {@link TetheringConfiguration}, useful for testing.
+ */
+ @VisibleForTesting
+ public static class Dependencies {
+ boolean isFeatureEnabled(@NonNull Context context, @NonNull String namespace,
+ @NonNull String name, @NonNull String moduleName, boolean defaultEnabled) {
+ return DeviceConfigUtils.isFeatureEnabled(context, namespace, name,
+ moduleName, defaultEnabled);
+ }
+
+ boolean getDeviceConfigBoolean(@NonNull String namespace, @NonNull String name,
+ boolean defaultValue) {
+ return DeviceConfig.getBoolean(namespace, name, defaultValue);
+ }
+ }
+
+ public TetheringConfiguration(@NonNull Context ctx, @NonNull SharedLog log, int id) {
+ this(ctx, log, id, new Dependencies());
+ }
+
+ @VisibleForTesting
+ public TetheringConfiguration(@NonNull Context ctx, @NonNull SharedLog log, int id,
+ @NonNull Dependencies deps) {
+ mDeps = deps;
final SharedLog configLog = log.forSubComponent("config");
activeDataSubId = id;
@@ -583,17 +611,7 @@
}
private boolean getDeviceConfigBoolean(final String name, final boolean defaultValue) {
- // Due to the limitation of static mock for testing, using #getDeviceConfigProperty instead
- // of DeviceConfig#getBoolean. If using #getBoolean here, the test can't know that the
- // returned boolean value comes from device config or default value (because of null
- // property string). See the test case testBpfOffload{*} in TetheringConfigurationTest.java.
- final String value = getDeviceConfigProperty(name);
- return value != null ? Boolean.parseBoolean(value) : defaultValue;
- }
-
- @VisibleForTesting
- protected String getDeviceConfigProperty(String name) {
- return DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY, name);
+ return mDeps.getDeviceConfigBoolean(NAMESPACE_CONNECTIVITY, name, defaultValue);
}
/**
@@ -610,10 +628,9 @@
return isFeatureEnabled(ctx, NAMESPACE_TETHERING, featureVersionFlag);
}
- @VisibleForTesting
- protected boolean isFeatureEnabled(Context ctx, String namespace, String featureVersionFlag) {
- return DeviceConfigUtils.isFeatureEnabled(ctx, namespace, featureVersionFlag,
- TETHERING_MODULE_NAME, false /* defaultEnabled */);
+ private boolean isFeatureEnabled(Context ctx, String namespace, String featureVersionFlag) {
+ return mDeps.isFeatureEnabled(ctx, namespace, featureVersionFlag, TETHERING_MODULE_NAME,
+ false /* defaultEnabled */);
}
private Resources getResources(Context ctx, int subId) {
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/FakeTetheringConfiguration.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/FakeTetheringConfiguration.java
index 0d686ed..9e287a0 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/FakeTetheringConfiguration.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/FakeTetheringConfiguration.java
@@ -19,22 +19,26 @@
import android.content.Context;
import android.content.res.Resources;
+import androidx.annotation.NonNull;
+
import com.android.net.module.util.SharedLog;
/** FakeTetheringConfiguration is used to override static method for testing. */
public class FakeTetheringConfiguration extends TetheringConfiguration {
FakeTetheringConfiguration(Context ctx, SharedLog log, int id) {
- super(ctx, log, id);
- }
+ super(ctx, log, id, new Dependencies() {
+ @Override
+ boolean isFeatureEnabled(@NonNull Context context, @NonNull String namespace,
+ @NonNull String name, @NonNull String moduleName, boolean defaultEnabled) {
+ return defaultEnabled;
+ }
- @Override
- protected String getDeviceConfigProperty(final String name) {
- return null;
- }
-
- @Override
- protected boolean isFeatureEnabled(Context ctx, String namespace, String featureVersionFlag) {
- return false;
+ @Override
+ boolean getDeviceConfigBoolean(@NonNull String namespace, @NonNull String name,
+ boolean defaultValue) {
+ return defaultValue;
+ }
+ });
}
@Override
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
index f662c02..3382af8 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
@@ -21,14 +21,13 @@
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
import static android.telephony.CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL;
import static android.telephony.CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.networkstack.apishim.ConstantsShim.KEY_CARRIER_SUPPORTS_TETHERING_BOOL;
+import static com.android.networkstack.tethering.TetheringConfiguration.OVERRIDE_TETHER_ENABLE_BPF_OFFLOAD;
+import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER;
import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_FORCE_USB_FUNCTIONS;
import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_USB_NCM_FUNCTION;
import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_USB_RNDIS_FUNCTION;
@@ -39,6 +38,7 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import android.content.Context;
@@ -49,12 +49,13 @@
import android.content.res.Resources;
import android.os.Build;
import android.os.PersistableBundle;
-import android.provider.DeviceConfig;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.TelephonyManager;
import android.test.mock.MockContentResolver;
+import android.util.ArrayMap;
+import androidx.annotation.NonNull;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -73,8 +74,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
+import org.mockito.MockitoAnnotations;
import java.util.Arrays;
import java.util.Iterator;
@@ -102,13 +102,13 @@
@Mock private ModuleInfo mMi;
private Context mMockContext;
private boolean mHasTelephonyManager;
- private MockitoSession mMockingSession;
private MockContentResolver mContentResolver;
private final PersistableBundle mCarrierConfig = new PersistableBundle();
+ private final MockDependencies mDeps = new MockDependencies();
private class MockTetheringConfiguration extends TetheringConfiguration {
MockTetheringConfiguration(Context ctx, SharedLog log, int id) {
- super(ctx, log, id);
+ super(ctx, log, id, mDeps);
}
@Override
@@ -151,19 +151,43 @@
}
}
+ private static class MockDependencies extends TetheringConfiguration.Dependencies {
+ private ArrayMap<String, Boolean> mMockFlags = new ArrayMap<>();
+
+ @Override
+ boolean isFeatureEnabled(@NonNull Context context, @NonNull String namespace,
+ @NonNull String name, @NonNull String moduleName, boolean defaultEnabled) {
+ return isMockFlagEnabled(name, defaultEnabled);
+ }
+
+ @Override
+ boolean getDeviceConfigBoolean(@NonNull String namespace, @NonNull String name,
+ boolean defaultValue) {
+ // Flags should use isFeatureEnabled instead of getBoolean; see comments in
+ // DeviceConfigUtils. getBoolean should only be used for the two legacy flags below.
+ assertTrue(OVERRIDE_TETHER_ENABLE_BPF_OFFLOAD.equals(name)
+ || TETHER_ENABLE_LEGACY_DHCP_SERVER.equals(name));
+
+ // Use the same mocking strategy as isFeatureEnabled for testing
+ return isMockFlagEnabled(name, defaultValue);
+ }
+
+ private boolean isMockFlagEnabled(@NonNull String name, boolean defaultEnabled) {
+ final Boolean flag = mMockFlags.getOrDefault(name, defaultEnabled);
+ // Value in the map can also be null
+ if (flag != null) return flag;
+ return defaultEnabled;
+ }
+
+ void setFeatureEnabled(@NonNull String flag, Boolean enabled) {
+ mMockFlags.put(flag, enabled);
+ }
+ }
+
@Before
public void setUp() throws Exception {
- // TODO: use a dependencies class instead of mock statics.
- mMockingSession = mockitoSession()
- .initMocks(this)
- .mockStatic(DeviceConfig.class)
- .strictness(Strictness.WARN)
- .startMocking();
- DeviceConfigUtils.resetPackageVersionCacheForTest();
- doReturn(null).when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
- setTetherForceUpstreamAutomaticFlagVersion(null);
+ MockitoAnnotations.initMocks(this);
+ setTetherForceUpstreamAutomaticFlagEnabled(null);
final PackageInfo pi = new PackageInfo();
pi.setLongVersionCode(TEST_PACKAGE_VERSION);
@@ -202,7 +226,6 @@
@After
public void tearDown() throws Exception {
- mMockingSession.finishMocking();
DeviceConfigUtils.resetPackageVersionCacheForTest();
// Call {@link #clearSettingsProvider()} before and after using FakeSettingsProvider.
FakeSettingsProvider.clearSettingsProvider();
@@ -211,7 +234,7 @@
private TetheringConfiguration getTetheringConfiguration(int... legacyTetherUpstreamTypes) {
when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(
legacyTetherUpstreamTypes);
- return new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ return new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
}
@Test
@@ -297,7 +320,7 @@
when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false);
final TetheringConfiguration cfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
assertTrue(upstreamIterator.hasNext());
assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue());
@@ -320,7 +343,7 @@
when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false);
final TetheringConfiguration cfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
assertTrue(upstreamIterator.hasNext());
assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue());
@@ -338,7 +361,7 @@
when(mTelephonyManager.isTetheringApnRequired()).thenReturn(false);
final TetheringConfiguration cfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
assertTrue(upstreamIterator.hasNext());
assertEquals(TYPE_WIFI, upstreamIterator.next().intValue());
@@ -350,27 +373,26 @@
}
private void initializeBpfOffloadConfiguration(
- final boolean fromRes, final String fromDevConfig) {
+ final boolean fromRes, final Boolean fromDevConfig) {
when(mResources.getBoolean(R.bool.config_tether_enable_bpf_offload)).thenReturn(fromRes);
- doReturn(fromDevConfig).when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.OVERRIDE_TETHER_ENABLE_BPF_OFFLOAD)));
+ mDeps.setFeatureEnabled(
+ TetheringConfiguration.OVERRIDE_TETHER_ENABLE_BPF_OFFLOAD, fromDevConfig);
}
@Test
public void testBpfOffloadEnabledByResource() {
initializeBpfOffloadConfiguration(true, null /* unset */);
final TetheringConfiguration enableByRes =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertTrue(enableByRes.isBpfOffloadEnabled());
}
@Test
public void testBpfOffloadEnabledByDeviceConfigOverride() {
for (boolean res : new boolean[]{true, false}) {
- initializeBpfOffloadConfiguration(res, "true");
+ initializeBpfOffloadConfiguration(res, true);
final TetheringConfiguration enableByDevConOverride =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertTrue(enableByDevConOverride.isBpfOffloadEnabled());
}
}
@@ -379,16 +401,16 @@
public void testBpfOffloadDisabledByResource() {
initializeBpfOffloadConfiguration(false, null /* unset */);
final TetheringConfiguration disableByRes =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertFalse(disableByRes.isBpfOffloadEnabled());
}
@Test
public void testBpfOffloadDisabledByDeviceConfigOverride() {
for (boolean res : new boolean[]{true, false}) {
- initializeBpfOffloadConfiguration(res, "false");
+ initializeBpfOffloadConfiguration(res, false);
final TetheringConfiguration disableByDevConOverride =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertFalse(disableByDevConOverride.isBpfOffloadEnabled());
}
}
@@ -397,22 +419,18 @@
public void testNewDhcpServerDisabled() {
when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
true);
- doReturn("false").when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
+ mDeps.setFeatureEnabled(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER, false);
final TetheringConfiguration enableByRes =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertTrue(enableByRes.useLegacyDhcpServer());
when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
false);
- doReturn("true").when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
+ mDeps.setFeatureEnabled(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER, true);
final TetheringConfiguration enableByDevConfig =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertTrue(enableByDevConfig.useLegacyDhcpServer());
}
@@ -420,12 +438,10 @@
public void testNewDhcpServerEnabled() {
when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
false);
- doReturn("false").when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
+ mDeps.setFeatureEnabled(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER, false);
final TetheringConfiguration cfg =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertFalse(cfg.useLegacyDhcpServer());
}
@@ -433,7 +449,7 @@
@Test
public void testOffloadIntervalByResource() {
final TetheringConfiguration intervalByDefault =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertEquals(TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS,
intervalByDefault.getOffloadPollInterval());
@@ -442,7 +458,7 @@
when(mResources.getInteger(R.integer.config_tether_offload_poll_interval)).thenReturn(
override);
final TetheringConfiguration overrideByRes =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertEquals(override, overrideByRes.getOffloadPollInterval());
}
}
@@ -451,7 +467,7 @@
public void testGetResourcesBySubId() {
setUpResourceForSubId();
final TetheringConfiguration cfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertTrue(cfg.provisioningApp.length == 0);
final int anyValidSubId = 1;
final MockTetheringConfiguration mockCfg =
@@ -493,7 +509,7 @@
mockService(Context.CARRIER_CONFIG_SERVICE,
CarrierConfigManager.class, null);
final TetheringConfiguration cfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertTrue(cfg.isCarrierSupportTethering);
assertTrue(cfg.isCarrierConfigAffirmsEntitlementCheckRequired);
@@ -506,7 +522,7 @@
CarrierConfigManager.class, mCarrierConfigManager);
when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(null);
final TetheringConfiguration cfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertTrue(cfg.isCarrierSupportTethering);
assertTrue(cfg.isCarrierConfigAffirmsEntitlementCheckRequired);
@@ -521,7 +537,7 @@
mCarrierConfig.putBoolean(KEY_CARRIER_SUPPORTS_TETHERING_BOOL, false);
when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig);
final TetheringConfiguration cfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
if (SdkLevel.isAtLeastT()) {
assertFalse(cfg.isCarrierSupportTethering);
@@ -535,13 +551,13 @@
@Test
public void testEnableLegacyWifiP2PAddress() throws Exception {
final TetheringConfiguration defaultCfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertFalse(defaultCfg.shouldEnableWifiP2pDedicatedIp());
when(mResources.getBoolean(R.bool.config_tether_enable_legacy_wifi_p2p_dedicated_ip))
.thenReturn(true);
final TetheringConfiguration testCfg = new TetheringConfiguration(
- mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertTrue(testCfg.shouldEnableWifiP2pDedicatedIp());
}
@@ -576,16 +592,13 @@
public void testChooseUpstreamAutomatically_FlagOverride() throws Exception {
when(mResources.getBoolean(R.bool.config_tether_upstream_automatic))
.thenReturn(false);
- setTetherForceUpstreamAutomaticFlagVersion(TEST_PACKAGE_VERSION - 1);
- assertTrue(DeviceConfigUtils.isFeatureEnabled(mMockContext, NAMESPACE_CONNECTIVITY,
- TetheringConfiguration.TETHER_FORCE_UPSTREAM_AUTOMATIC_VERSION, APEX_NAME, false));
-
+ setTetherForceUpstreamAutomaticFlagEnabled(true);
assertChooseUpstreamAutomaticallyIs(true);
- setTetherForceUpstreamAutomaticFlagVersion(0L);
+ setTetherForceUpstreamAutomaticFlagEnabled(null);
assertChooseUpstreamAutomaticallyIs(false);
- setTetherForceUpstreamAutomaticFlagVersion(Long.MAX_VALUE);
+ setTetherForceUpstreamAutomaticFlagEnabled(false);
assertChooseUpstreamAutomaticallyIs(false);
}
@@ -593,7 +606,7 @@
public void testChooseUpstreamAutomatically_FlagOverrideOnSAndT() throws Exception {
when(mResources.getBoolean(R.bool.config_tether_upstream_automatic))
.thenReturn(false);
- setTetherForceUpstreamAutomaticFlagVersion(TEST_PACKAGE_VERSION - 1);
+ setTetherForceUpstreamAutomaticFlagEnabled(true);
assertChooseUpstreamAutomaticallyIs(false);
}
@@ -604,28 +617,24 @@
// TETHER_FORCE_UPSTREAM_AUTOMATIC_VERSION is.
when(mResources.getBoolean(R.bool.config_tether_upstream_automatic))
.thenReturn(false);
- setTetherForceUpstreamAutomaticFlagVersion(TEST_PACKAGE_VERSION - 1);
- assertTrue(DeviceConfigUtils.isFeatureEnabled(mMockContext, NAMESPACE_CONNECTIVITY,
- TetheringConfiguration.TETHER_FORCE_UPSTREAM_AUTOMATIC_VERSION, APEX_NAME, false));
-
+ setTetherForceUpstreamAutomaticFlagEnabled(true);
assertChooseUpstreamAutomaticallyIs(true);
- setTetherForceUpstreamAutomaticFlagVersion(0L);
+ setTetherForceUpstreamAutomaticFlagEnabled(null);
assertChooseUpstreamAutomaticallyIs(true);
- setTetherForceUpstreamAutomaticFlagVersion(Long.MAX_VALUE);
+ setTetherForceUpstreamAutomaticFlagEnabled(false);
assertChooseUpstreamAutomaticallyIs(true);
}
- private void setTetherForceUpstreamAutomaticFlagVersion(Long version) {
- doReturn(version == null ? null : Long.toString(version)).when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
- eq(TetheringConfiguration.TETHER_FORCE_UPSTREAM_AUTOMATIC_VERSION)));
+ private void setTetherForceUpstreamAutomaticFlagEnabled(Boolean enabled) {
+ mDeps.setFeatureEnabled(
+ TetheringConfiguration.TETHER_FORCE_UPSTREAM_AUTOMATIC_VERSION, enabled);
}
private void assertChooseUpstreamAutomaticallyIs(boolean value) {
- assertEquals(value, new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)
- .chooseUpstreamAutomatically);
+ assertEquals(value, new TetheringConfiguration(
+ mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps).chooseUpstreamAutomatically);
}
@Test
@@ -654,7 +663,7 @@
private void assertIsUsingNcm(boolean expected) {
final TetheringConfiguration cfg =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertEquals(expected, cfg.isUsingNcm());
}
@@ -704,7 +713,7 @@
private void assertUsbAndNcmRegexs(final String[] usbRegexs, final String[] ncmRegexs) {
final TetheringConfiguration cfg =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertArrayEquals(usbRegexs, cfg.tetherableUsbRegexs);
assertArrayEquals(ncmRegexs, cfg.tetherableNcmRegexs);
}
@@ -716,28 +725,28 @@
final int defaultSubnetPrefixLength = 0;
final TetheringConfiguration defaultCfg =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertEquals(defaultSubnetPrefixLength, defaultCfg.getP2pLeasesSubnetPrefixLength());
final int prefixLengthTooSmall = -1;
when(mResources.getInteger(R.integer.config_p2p_leases_subnet_prefix_length)).thenReturn(
prefixLengthTooSmall);
final TetheringConfiguration tooSmallCfg =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertEquals(defaultSubnetPrefixLength, tooSmallCfg.getP2pLeasesSubnetPrefixLength());
final int prefixLengthTooLarge = 31;
when(mResources.getInteger(R.integer.config_p2p_leases_subnet_prefix_length)).thenReturn(
prefixLengthTooLarge);
final TetheringConfiguration tooLargeCfg =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertEquals(defaultSubnetPrefixLength, tooLargeCfg.getP2pLeasesSubnetPrefixLength());
final int p2pLeasesSubnetPrefixLength = 27;
when(mResources.getInteger(R.integer.config_p2p_leases_subnet_prefix_length)).thenReturn(
p2pLeasesSubnetPrefixLength);
final TetheringConfiguration p2pCfg =
- new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+ new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID, mDeps);
assertEquals(p2pLeasesSubnetPrefixLength, p2pCfg.getP2pLeasesSubnetPrefixLength());
}
}
diff --git a/bpf_progs/block.c b/bpf_progs/block.c
index f2a3e62..3797a38 100644
--- a/bpf_progs/block.c
+++ b/bpf_progs/block.c
@@ -19,8 +19,8 @@
#include <netinet/in.h>
#include <stdint.h>
-// The resulting .o needs to load on the Android T beta 3 bpfloader
-#define BPFLOADER_MIN_VER BPFLOADER_T_BETA3_VERSION
+// The resulting .o needs to load on the Android T bpfloader
+#define BPFLOADER_MIN_VER BPFLOADER_T_VERSION
#include "bpf_helpers.h"
diff --git a/bpf_progs/clatd.c b/bpf_progs/clatd.c
index f05b93e..85ba58e 100644
--- a/bpf_progs/clatd.c
+++ b/bpf_progs/clatd.c
@@ -30,8 +30,8 @@
#define __kernel_udphdr udphdr
#include <linux/udp.h>
-// The resulting .o needs to load on the Android T beta 3 bpfloader
-#define BPFLOADER_MIN_VER BPFLOADER_T_BETA3_VERSION
+// The resulting .o needs to load on the Android T bpfloader
+#define BPFLOADER_MIN_VER BPFLOADER_T_VERSION
#include "bpf_helpers.h"
#include "bpf_net_helpers.h"
diff --git a/bpf_progs/dscpPolicy.c b/bpf_progs/dscpPolicy.c
index 72f63c6..262b65b 100644
--- a/bpf_progs/dscpPolicy.c
+++ b/bpf_progs/dscpPolicy.c
@@ -27,8 +27,8 @@
#include <stdint.h>
#include <string.h>
-// The resulting .o needs to load on the Android T beta 3 bpfloader
-#define BPFLOADER_MIN_VER BPFLOADER_T_BETA3_VERSION
+// The resulting .o needs to load on the Android T bpfloader
+#define BPFLOADER_MIN_VER BPFLOADER_T_VERSION
#include "bpf_helpers.h"
#include "dscpPolicy.h"
diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c
index 39dff7f..839ca40 100644
--- a/bpf_progs/netd.c
+++ b/bpf_progs/netd.c
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-// The resulting .o needs to load on the Android T Beta 3 bpfloader
-#define BPFLOADER_MIN_VER BPFLOADER_T_BETA3_VERSION
+// The resulting .o needs to load on the Android T bpfloader
+#define BPFLOADER_MIN_VER BPFLOADER_T_VERSION
#include <bpf_helpers.h>
#include <linux/bpf.h>
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 381a18a..2315521 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -2535,6 +2535,26 @@
}
/**
+ * Get the supported keepalive count for each transport configured in resource overlays.
+ *
+ * @return An array of supported keepalive count for each transport type.
+ * @hide
+ */
+ @RequiresPermission(anyOf = { android.Manifest.permission.NETWORK_SETTINGS,
+ // CTS 13 used QUERY_ALL_PACKAGES to get the resource value, which was implemented
+ // as below in KeepaliveUtils. Also allow that permission so that KeepaliveUtils can
+ // use this method and avoid breaking released CTS. Apps that have this permission
+ // can query the resource themselves anyway.
+ android.Manifest.permission.QUERY_ALL_PACKAGES })
+ public int[] getSupportedKeepalives() {
+ try {
+ return mService.getSupportedKeepalives();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Ensure that a network route exists to deliver traffic to the specified
* host via the specified network interface. An attempt to add a route that
* already exists is ignored, but treated as successful.
diff --git a/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl
index 1372e9a..ebe8bca 100644
--- a/framework/src/android/net/IConnectivityManager.aidl
+++ b/framework/src/android/net/IConnectivityManager.aidl
@@ -195,6 +195,8 @@
void stopKeepalive(in ISocketKeepaliveCallback cb);
+ int[] getSupportedKeepalives();
+
String getCaptivePortalServerUrl();
byte[] getNetworkWatchlistConfigHash();
diff --git a/framework/src/android/net/apf/ApfCapabilities.java b/framework/src/android/net/apf/ApfCapabilities.java
index 64f14a1..fae2499 100644
--- a/framework/src/android/net/apf/ApfCapabilities.java
+++ b/framework/src/android/net/apf/ApfCapabilities.java
@@ -19,9 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.content.Context;
-import android.content.res.Resources;
-import android.net.ConnectivityResources;
import android.os.Parcel;
import android.os.Parcelable;
@@ -36,8 +33,6 @@
*/
@SystemApi
public final class ApfCapabilities implements Parcelable {
- private static ConnectivityResources sResources;
-
/**
* Version of APF instruction set supported for packet filtering. 0 indicates no support for
* packet filtering using APF programs.
@@ -67,15 +62,6 @@
apfPacketFormat = in.readInt();
}
- @NonNull
- private static synchronized ConnectivityResources getResources(@NonNull Context ctx) {
- if (sResources == null) {
- sResources = new ConnectivityResources(ctx);
- }
- return sResources;
- }
-
-
@Override
public int describeContents() {
return 0;
diff --git a/framework/src/android/net/util/KeepaliveUtils.java b/framework/src/android/net/util/KeepaliveUtils.java
index 8d7a0b3..07b8c45 100644
--- a/framework/src/android/net/util/KeepaliveUtils.java
+++ b/framework/src/android/net/util/KeepaliveUtils.java
@@ -18,11 +18,8 @@
import android.annotation.NonNull;
import android.content.Context;
-import android.content.res.Resources;
-import android.net.ConnectivityResources;
+import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
-import android.text.TextUtils;
-import android.util.AndroidRuntimeException;
/**
* Collection of utilities for socket keepalive offload.
@@ -33,64 +30,20 @@
public static final String TAG = "KeepaliveUtils";
- public static class KeepaliveDeviceConfigurationException extends AndroidRuntimeException {
- public KeepaliveDeviceConfigurationException(final String msg) {
- super(msg);
- }
- }
-
/**
* Read supported keepalive count for each transport type from overlay resource. This should be
* used to create a local variable store of resource customization, and use it as the input for
- * {@link getSupportedKeepalivesForNetworkCapabilities}.
+ * {@link #getSupportedKeepalivesForNetworkCapabilities}.
*
* @param context The context to read resource from.
* @return An array of supported keepalive count for each transport type.
+ * @deprecated This is used by CTS 13, but can be removed after switching it to
+ * {@link ConnectivityManager#getSupportedKeepalives()}.
*/
@NonNull
+ @Deprecated
public static int[] getSupportedKeepalives(@NonNull Context context) {
- String[] res = null;
- try {
- final ConnectivityResources connRes = new ConnectivityResources(context);
- // TODO: use R.id.config_networkSupportedKeepaliveCount directly
- final int id = connRes.get().getIdentifier("config_networkSupportedKeepaliveCount",
- "array", connRes.getResourcesContext().getPackageName());
- res = new ConnectivityResources(context).get().getStringArray(id);
- } catch (Resources.NotFoundException unused) {
- }
- if (res == null) throw new KeepaliveDeviceConfigurationException("invalid resource");
-
- final int[] ret = new int[NetworkCapabilities.MAX_TRANSPORT + 1];
- for (final String row : res) {
- if (TextUtils.isEmpty(row)) {
- throw new KeepaliveDeviceConfigurationException("Empty string");
- }
- final String[] arr = row.split(",");
- if (arr.length != 2) {
- throw new KeepaliveDeviceConfigurationException("Invalid parameter length");
- }
-
- int transport;
- int supported;
- try {
- transport = Integer.parseInt(arr[0]);
- supported = Integer.parseInt(arr[1]);
- } catch (NumberFormatException e) {
- throw new KeepaliveDeviceConfigurationException("Invalid number format");
- }
-
- if (!NetworkCapabilities.isValidTransport(transport)) {
- throw new KeepaliveDeviceConfigurationException("Invalid transport " + transport);
- }
-
- if (supported < 0) {
- throw new KeepaliveDeviceConfigurationException(
- "Invalid supported count " + supported + " for "
- + NetworkCapabilities.transportNameOf(transport));
- }
- ret[transport] = supported;
- }
- return ret;
+ return context.getSystemService(ConnectivityManager.class).getSupportedKeepalives();
}
/**
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java b/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
index 491698d..64985ad 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsDiscoveryManager.java
@@ -16,7 +16,7 @@
package com.android.server.connectivity.mdns;
-import static com.android.server.connectivity.mdns.MdnsSocketProvider.isNetworkMatched;
+import static com.android.server.connectivity.mdns.util.MdnsUtils.isNetworkMatched;
import android.Manifest.permission;
import android.annotation.NonNull;
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsMultinetworkSocketClient.java b/service-t/src/com/android/server/connectivity/mdns/MdnsMultinetworkSocketClient.java
index 7af2231..4504bb6 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsMultinetworkSocketClient.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsMultinetworkSocketClient.java
@@ -16,8 +16,8 @@
package com.android.server.connectivity.mdns;
-import static com.android.server.connectivity.mdns.MdnsSocketProvider.ensureRunningOnHandlerThread;
-import static com.android.server.connectivity.mdns.MdnsSocketProvider.isNetworkMatched;
+import static com.android.server.connectivity.mdns.util.MdnsUtils.ensureRunningOnHandlerThread;
+import static com.android.server.connectivity.mdns.util.MdnsUtils.isNetworkMatched;
import android.annotation.NonNull;
import android.annotation.Nullable;
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsReplySender.java b/service-t/src/com/android/server/connectivity/mdns/MdnsReplySender.java
index f1389ca..8bc598d 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsReplySender.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsReplySender.java
@@ -16,7 +16,7 @@
package com.android.server.connectivity.mdns;
-import static com.android.server.connectivity.mdns.MdnsSocketProvider.ensureRunningOnHandlerThread;
+import static com.android.server.connectivity.mdns.util.MdnsUtils.ensureRunningOnHandlerThread;
import android.annotation.NonNull;
import android.os.Handler;
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java
index bfda535..cd0be67 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsServiceCache.java
@@ -16,7 +16,7 @@
package com.android.server.connectivity.mdns;
-import static com.android.server.connectivity.mdns.MdnsSocketProvider.ensureRunningOnHandlerThread;
+import static com.android.server.connectivity.mdns.util.MdnsUtils.ensureRunningOnHandlerThread;
import static com.android.server.connectivity.mdns.util.MdnsUtils.equalsIgnoreDnsCase;
import static com.android.server.connectivity.mdns.util.MdnsUtils.toDnsLowerCase;
diff --git a/service-t/src/com/android/server/connectivity/mdns/MdnsSocketProvider.java b/service-t/src/com/android/server/connectivity/mdns/MdnsSocketProvider.java
index b45a831..d090a4d 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MdnsSocketProvider.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MdnsSocketProvider.java
@@ -20,6 +20,9 @@
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static com.android.server.connectivity.mdns.util.MdnsUtils.ensureRunningOnHandlerThread;
+import static com.android.server.connectivity.mdns.util.MdnsUtils.isNetworkMatched;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -242,14 +245,6 @@
}
}
- /*** Ensure that current running thread is same as given handler thread */
- public static void ensureRunningOnHandlerThread(Handler handler) {
- if (handler.getLooper().getThread() != Thread.currentThread()) {
- throw new IllegalStateException(
- "Not running on Handler thread: " + Thread.currentThread().getName());
- }
- }
-
/*** Start monitoring sockets by listening callbacks for sockets creation or removal */
public void startMonitoringSockets() {
ensureRunningOnHandlerThread(mHandler);
@@ -317,12 +312,6 @@
maybeStopMonitoringSockets();
}
- /*** Check whether the target network is matched current network */
- public static boolean isNetworkMatched(@Nullable Network targetNetwork,
- @Nullable Network currentNetwork) {
- return targetNetwork == null || targetNetwork.equals(currentNetwork);
- }
-
private boolean matchRequestedNetwork(Network network) {
return hasAllNetworksRequest()
|| mCallbacksToRequestedNetworks.containsValue(network);
diff --git a/service-t/src/com/android/server/connectivity/mdns/MulticastPacketReader.java b/service-t/src/com/android/server/connectivity/mdns/MulticastPacketReader.java
index 0e5a2a4..63119ac 100644
--- a/service-t/src/com/android/server/connectivity/mdns/MulticastPacketReader.java
+++ b/service-t/src/com/android/server/connectivity/mdns/MulticastPacketReader.java
@@ -16,7 +16,7 @@
package com.android.server.connectivity.mdns;
-import static com.android.server.connectivity.mdns.MdnsSocketProvider.ensureRunningOnHandlerThread;
+import static com.android.server.connectivity.mdns.util.MdnsUtils.ensureRunningOnHandlerThread;
import android.annotation.NonNull;
import android.os.Handler;
diff --git a/service-t/src/com/android/server/connectivity/mdns/util/MdnsUtils.java b/service-t/src/com/android/server/connectivity/mdns/util/MdnsUtils.java
index 4b0f2a4..4b9759d 100644
--- a/service-t/src/com/android/server/connectivity/mdns/util/MdnsUtils.java
+++ b/service-t/src/com/android/server/connectivity/mdns/util/MdnsUtils.java
@@ -17,6 +17,9 @@
package com.android.server.connectivity.mdns.util;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.Network;
+import android.os.Handler;
/**
* Mdns utility functions.
@@ -56,4 +59,18 @@
private static char toDnsLowerCase(char a) {
return a >= 'A' && a <= 'Z' ? (char) (a + ('a' - 'A')) : a;
}
+
+ /*** Ensure that current running thread is same as given handler thread */
+ public static void ensureRunningOnHandlerThread(@NonNull Handler handler) {
+ if (handler.getLooper().getThread() != Thread.currentThread()) {
+ throw new IllegalStateException(
+ "Not running on Handler thread: " + Thread.currentThread().getName());
+ }
+ }
+
+ /*** Check whether the target network is matched current network */
+ public static boolean isNetworkMatched(@Nullable Network targetNetwork,
+ @Nullable Network currentNetwork) {
+ return targetNetwork == null || targetNetwork.equals(currentNetwork);
+ }
}
diff --git a/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java b/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
index eed9aeb..6776920 100644
--- a/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
+++ b/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
@@ -20,7 +20,6 @@
import android.annotation.Nullable;
import android.content.Context;
import android.net.ConnectivityManager;
-import android.net.ConnectivityResources;
import android.net.EthernetManager;
import android.net.EthernetNetworkSpecifier;
import android.net.IpConfiguration;
@@ -50,6 +49,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.net.module.util.InterfaceParams;
+import com.android.server.connectivity.ConnectivityResources;
import java.io.FileDescriptor;
import java.util.Objects;
diff --git a/service-t/src/com/android/server/ethernet/EthernetTracker.java b/service-t/src/com/android/server/ethernet/EthernetTracker.java
index d520757..1f22b02 100644
--- a/service-t/src/com/android/server/ethernet/EthernetTracker.java
+++ b/service-t/src/com/android/server/ethernet/EthernetTracker.java
@@ -25,7 +25,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
-import android.net.ConnectivityResources;
import android.net.EthernetManager;
import android.net.IEthernetServiceListener;
import android.net.INetd;
@@ -57,6 +56,7 @@
import com.android.net.module.util.netlink.NetlinkMessage;
import com.android.net.module.util.netlink.RtNetlinkLinkMessage;
import com.android.net.module.util.netlink.StructIfinfoMsg;
+import com.android.server.connectivity.ConnectivityResources;
import java.io.FileDescriptor;
import java.net.InetAddress;
diff --git a/service-t/src/com/android/server/net/NetworkStatsService.java b/service-t/src/com/android/server/net/NetworkStatsService.java
index c660792..f977a27 100644
--- a/service-t/src/com/android/server/net/NetworkStatsService.java
+++ b/service-t/src/com/android/server/net/NetworkStatsService.java
@@ -83,7 +83,6 @@
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
-import android.net.ConnectivityResources;
import android.net.DataUsageRequest;
import android.net.INetd;
import android.net.INetworkStatsService;
@@ -175,6 +174,7 @@
import com.android.networkstack.apishim.ConstantsShim;
import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
import com.android.server.BpfNetMaps;
+import com.android.server.connectivity.ConnectivityResources;
import java.io.File;
import java.io.FileDescriptor;
diff --git a/service/jni/com_android_server_connectivity_ClatCoordinator.cpp b/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
index 059b716..8d909ed 100644
--- a/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
+++ b/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
@@ -485,11 +485,15 @@
static constexpr int WAITPID_ATTEMPTS = 50;
static constexpr int WAITPID_RETRY_INTERVAL_US = 100000;
-static void stopClatdProcess(int pid) {
- int err = kill(pid, SIGTERM);
- if (err) {
- err = errno;
+static void com_android_server_connectivity_ClatCoordinator_stopClatd(JNIEnv* env, jclass clazz,
+ jint pid) {
+ if (pid <= 0) {
+ jniThrowExceptionFmt(env, "java/io/IOException", "Invalid pid");
+ return;
}
+
+ int err = kill(pid, SIGTERM);
+ if (err) err = errno;
if (err == ESRCH) {
ALOGE("clatd child process %d unexpectedly disappeared", pid);
return;
@@ -518,23 +522,6 @@
}
}
-static void com_android_server_connectivity_ClatCoordinator_stopClatd(JNIEnv* env, jclass clazz,
- jstring iface, jstring pfx96,
- jstring v4, jstring v6,
- jint pid) {
- ScopedUtfChars ifaceStr(env, iface);
- ScopedUtfChars pfx96Str(env, pfx96);
- ScopedUtfChars v4Str(env, v4);
- ScopedUtfChars v6Str(env, v6);
-
- if (pid <= 0) {
- jniThrowExceptionFmt(env, "java/io/IOException", "Invalid pid");
- return;
- }
-
- stopClatdProcess(pid);
-}
-
static jlong com_android_server_connectivity_ClatCoordinator_getSocketCookie(
JNIEnv* env, jclass clazz, jobject sockJavaFd) {
int sockFd = netjniutils::GetNativeFileDescriptor(env, sockJavaFd);
@@ -579,8 +566,7 @@
"(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/lang/"
"String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
(void*)com_android_server_connectivity_ClatCoordinator_startClatd},
- {"native_stopClatd",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V",
+ {"native_stopClatd", "(I)V",
(void*)com_android_server_connectivity_ClatCoordinator_stopClatd},
{"native_getSocketCookie", "(Ljava/io/FileDescriptor;)J",
(void*)com_android_server_connectivity_ClatCoordinator_getSocketCookie},
diff --git a/service/jni/onload.cpp b/service/jni/onload.cpp
index 3d15d43..4bbaae6 100644
--- a/service/jni/onload.cpp
+++ b/service/jni/onload.cpp
@@ -22,8 +22,8 @@
namespace android {
int register_com_android_server_TestNetworkService(JNIEnv* env);
-int register_com_android_server_connectivity_ClatCoordinator(JNIEnv* env);
int register_com_android_server_BpfNetMaps(JNIEnv* env);
+int register_com_android_server_connectivity_ClatCoordinator(JNIEnv* env);
int register_android_server_net_NetworkStatsFactory(JNIEnv* env);
int register_android_server_net_NetworkStatsService(JNIEnv* env);
@@ -38,15 +38,15 @@
return JNI_ERR;
}
- if (register_com_android_server_connectivity_ClatCoordinator(env) < 0) {
- return JNI_ERR;
- }
-
if (register_com_android_server_BpfNetMaps(env) < 0) {
return JNI_ERR;
}
if (android::modules::sdklevel::IsAtLeastT()) {
+ if (register_com_android_server_connectivity_ClatCoordinator(env) < 0) {
+ return JNI_ERR;
+ }
+
if (register_android_server_net_NetworkStatsFactory(env) < 0) {
return JNI_ERR;
}
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 6fa2746..c080c59 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -134,7 +134,6 @@
import android.net.ConnectivityManager.BlockedReason;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.ConnectivityManager.RestrictBackgroundStatus;
-import android.net.ConnectivityResources;
import android.net.ConnectivitySettingsManager;
import android.net.DataStallReportParcelable;
import android.net.DnsResolverServiceManager;
@@ -244,6 +243,7 @@
import android.util.LocalLog;
import android.util.Log;
import android.util.Pair;
+import android.util.Range;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -280,11 +280,13 @@
import com.android.server.connectivity.CarrierPrivilegeAuthenticator;
import com.android.server.connectivity.ClatCoordinator;
import com.android.server.connectivity.ConnectivityFlags;
+import com.android.server.connectivity.ConnectivityResources;
import com.android.server.connectivity.DnsManager;
import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
import com.android.server.connectivity.DscpPolicyTracker;
import com.android.server.connectivity.FullScore;
import com.android.server.connectivity.InvalidTagException;
+import com.android.server.connectivity.KeepaliveResourceUtil;
import com.android.server.connectivity.KeepaliveTracker;
import com.android.server.connectivity.LingerMonitor;
import com.android.server.connectivity.MockableSystemProperties;
@@ -310,11 +312,13 @@
import java.io.FileDescriptor;
import java.io.IOException;
+import java.io.InterruptedIOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -1485,6 +1489,18 @@
@NonNull final UserHandle user) {
return CompatChanges.isChangeEnabled(changeId, packageName, user);
}
+
+ /**
+ * Call {@link InetDiagMessage#destroyLiveTcpSockets(Set, Set)}
+ *
+ * @param ranges target uid ranges
+ * @param exemptUids uids to skip close socket
+ */
+ public void destroyLiveTcpSockets(@NonNull final Set<Range<Integer>> ranges,
+ @NonNull final Set<Integer> exemptUids)
+ throws SocketException, InterruptedIOException, ErrnoException {
+ InetDiagMessage.destroyLiveTcpSockets(ranges, exemptUids);
+ }
}
public ConnectivityService(Context context) {
@@ -8459,11 +8475,11 @@
return stableRanges;
}
- private void maybeCloseSockets(NetworkAgentInfo nai, UidRangeParcel[] ranges,
- int[] exemptUids) {
+ private void maybeCloseSockets(NetworkAgentInfo nai, Set<UidRange> ranges,
+ Set<Integer> exemptUids) {
if (nai.isVPN() && !nai.networkAgentConfig.allowBypass) {
try {
- mNetd.socketDestroy(ranges, exemptUids);
+ mDeps.destroyLiveTcpSockets(UidRange.toIntRanges(ranges), exemptUids);
} catch (Exception e) {
loge("Exception in socket destroy: ", e);
}
@@ -8471,16 +8487,16 @@
}
private void updateVpnUidRanges(boolean add, NetworkAgentInfo nai, Set<UidRange> uidRanges) {
- int[] exemptUids = new int[2];
+ final Set<Integer> exemptUids = new ArraySet<>();
// TODO: Excluding VPN_UID is necessary in order to not to kill the TCP connection used
// by PPTP. Fix this by making Vpn set the owner UID to VPN_UID instead of system when
// starting a legacy VPN, and remove VPN_UID here. (b/176542831)
- exemptUids[0] = VPN_UID;
- exemptUids[1] = nai.networkCapabilities.getOwnerUid();
+ exemptUids.add(VPN_UID);
+ exemptUids.add(nai.networkCapabilities.getOwnerUid());
UidRangeParcel[] ranges = toUidRangeStableParcels(uidRanges);
// Close sockets before modifying uid ranges so that RST packets can reach to the server.
- maybeCloseSockets(nai, ranges, exemptUids);
+ maybeCloseSockets(nai, uidRanges, exemptUids);
try {
if (add) {
mNetd.networkAddUidRangesParcel(new NativeUidRangeConfig(
@@ -8494,7 +8510,7 @@
" on netId " + nai.network.netId + ". " + e);
}
// Close sockets that established connection while requesting netd.
- maybeCloseSockets(nai, ranges, exemptUids);
+ maybeCloseSockets(nai, uidRanges, exemptUids);
}
private boolean isProxySetOnAnyDefaultNetwork() {
@@ -10032,6 +10048,16 @@
}
@Override
+ public int[] getSupportedKeepalives() {
+ enforceAnyPermissionOf(mContext, android.Manifest.permission.NETWORK_SETTINGS,
+ // Backwards compatibility with CTS 13
+ android.Manifest.permission.QUERY_ALL_PACKAGES);
+
+ return BinderUtils.withCleanCallingIdentity(() ->
+ KeepaliveResourceUtil.getSupportedKeepalives(mContext));
+ }
+
+ @Override
public void factoryReset() {
enforceSettingsPermission();
diff --git a/service/src/com/android/server/connectivity/ClatCoordinator.java b/service/src/com/android/server/connectivity/ClatCoordinator.java
index 5d04632..fbe706c 100644
--- a/service/src/com/android/server/connectivity/ClatCoordinator.java
+++ b/service/src/com/android/server/connectivity/ClatCoordinator.java
@@ -237,9 +237,8 @@
/**
* Stop clatd.
*/
- public void stopClatd(String iface, String pfx96, String v4, String v6, int pid)
- throws IOException {
- native_stopClatd(iface, pfx96, v4, v6, pid);
+ public void stopClatd(int pid) throws IOException {
+ native_stopClatd(pid);
}
/**
@@ -843,9 +842,7 @@
Log.i(TAG, "Stopping clatd pid=" + mClatdTracker.pid + " on " + mClatdTracker.iface);
maybeStopBpf(mClatdTracker);
- mDeps.stopClatd(mClatdTracker.iface, mClatdTracker.pfx96.getHostAddress(),
- mClatdTracker.v4.getHostAddress(), mClatdTracker.v6.getHostAddress(),
- mClatdTracker.pid);
+ mDeps.stopClatd(mClatdTracker.pid);
untagSocket(mClatdTracker.cookie);
Log.i(TAG, "clatd on " + mClatdTracker.iface + " stopped");
@@ -944,7 +941,6 @@
private static native int native_startClatd(FileDescriptor tunfd, FileDescriptor readsock6,
FileDescriptor writesock6, String iface, String pfx96, String v4, String v6)
throws IOException;
- private static native void native_stopClatd(String iface, String pfx96, String v4, String v6,
- int pid) throws IOException;
+ private static native void native_stopClatd(int pid) throws IOException;
private static native long native_getSocketCookie(FileDescriptor sock) throws IOException;
}
diff --git a/framework/src/android/net/ConnectivityResources.java b/service/src/com/android/server/connectivity/ConnectivityResources.java
similarity index 67%
rename from framework/src/android/net/ConnectivityResources.java
rename to service/src/com/android/server/connectivity/ConnectivityResources.java
index 18f0de0..9089e4a 100644
--- a/framework/src/android/net/ConnectivityResources.java
+++ b/service/src/com/android/server/connectivity/ConnectivityResources.java
@@ -14,22 +14,16 @@
* limitations under the License.
*/
-package android.net;
-
-import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
+package com.android.server.connectivity;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
-import android.content.Intent;
import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.content.res.Resources;
-import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.List;
+import com.android.net.module.util.DeviceConfigUtils;
/**
* Utility to obtain the {@link com.android.server.ConnectivityService} {@link Resources}, in the
@@ -37,10 +31,6 @@
* @hide
*/
public class ConnectivityResources {
- private static final String RESOURCES_APK_INTENT =
- "com.android.server.connectivity.intent.action.SERVICE_CONNECTIVITY_RESOURCES_APK";
- private static final String RES_PKG_DIR = "/apex/com.android.tethering/";
-
@NonNull
private final Context mContext;
@@ -76,21 +66,10 @@
return mResourcesContext;
}
- final List<ResolveInfo> pkgs = mContext.getPackageManager()
- .queryIntentActivities(new Intent(RESOURCES_APK_INTENT), MATCH_SYSTEM_ONLY);
- pkgs.removeIf(pkg -> !pkg.activityInfo.applicationInfo.sourceDir.startsWith(RES_PKG_DIR));
- if (pkgs.size() > 1) {
- Log.wtf(ConnectivityResources.class.getSimpleName(),
- "More than one package found: " + pkgs);
- }
- if (pkgs.isEmpty()) {
- throw new IllegalStateException("No connectivity resource package found");
- }
-
+ final String resPkg = DeviceConfigUtils.getConnectivityResourcesPackageName(mContext);
final Context pkgContext;
try {
- pkgContext = mContext.createPackageContext(
- pkgs.get(0).activityInfo.applicationInfo.packageName, 0 /* flags */);
+ pkgContext = mContext.createPackageContext(resPkg, 0 /* flags */);
} catch (PackageManager.NameNotFoundException e) {
throw new IllegalStateException("Resolved package not found", e);
}
diff --git a/service/src/com/android/server/connectivity/KeepaliveResourceUtil.java b/service/src/com/android/server/connectivity/KeepaliveResourceUtil.java
new file mode 100644
index 0000000..92b080d
--- /dev/null
+++ b/service/src/com/android/server/connectivity/KeepaliveResourceUtil.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2023 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.connectivity;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.NetworkCapabilities;
+import android.text.TextUtils;
+import android.util.AndroidRuntimeException;
+
+import com.android.connectivity.resources.R;
+
+/**
+ * Utilities to fetch keepalive configuration from resources.
+ */
+public abstract class KeepaliveResourceUtil {
+
+ /**
+ * Read supported keepalive count for each transport type from overlay resource.
+ *
+ * @param context The context to read resource from.
+ * @return An array of supported keepalive count for each transport type.
+ */
+ @NonNull
+ public static int[] getSupportedKeepalives(@NonNull Context context) {
+ String[] res = null;
+ try {
+ final ConnectivityResources connRes = new ConnectivityResources(context);
+ res = connRes.get().getStringArray(R.array.config_networkSupportedKeepaliveCount);
+ } catch (Resources.NotFoundException unused) {
+ }
+ if (res == null) throw new KeepaliveDeviceConfigurationException("invalid resource");
+
+ final int[] ret = new int[NetworkCapabilities.MAX_TRANSPORT + 1];
+ for (final String row : res) {
+ if (TextUtils.isEmpty(row)) {
+ throw new KeepaliveDeviceConfigurationException("Empty string");
+ }
+ final String[] arr = row.split(",");
+ if (arr.length != 2) {
+ throw new KeepaliveDeviceConfigurationException("Invalid parameter length");
+ }
+
+ int transport;
+ int supported;
+ try {
+ transport = Integer.parseInt(arr[0]);
+ supported = Integer.parseInt(arr[1]);
+ } catch (NumberFormatException e) {
+ throw new KeepaliveDeviceConfigurationException("Invalid number format");
+ }
+
+ if (!NetworkCapabilities.isValidTransport(transport)) {
+ throw new KeepaliveDeviceConfigurationException("Invalid transport " + transport);
+ }
+
+ if (supported < 0) {
+ throw new KeepaliveDeviceConfigurationException(
+ "Invalid supported count " + supported + " for "
+ + NetworkCapabilities.transportNameOf(transport));
+ }
+ ret[transport] = supported;
+ }
+ return ret;
+ }
+
+ /**
+ * An exception thrown when the keepalive resource configuration is invalid.
+ */
+ public static class KeepaliveDeviceConfigurationException extends AndroidRuntimeException {
+ public KeepaliveDeviceConfigurationException(final String msg) {
+ super(msg);
+ }
+ }
+}
diff --git a/service/src/com/android/server/connectivity/KeepaliveTracker.java b/service/src/com/android/server/connectivity/KeepaliveTracker.java
index 60485b3..8c170bc 100644
--- a/service/src/com/android/server/connectivity/KeepaliveTracker.java
+++ b/service/src/com/android/server/connectivity/KeepaliveTracker.java
@@ -37,7 +37,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
-import android.net.ConnectivityResources;
import android.net.ISocketKeepaliveCallback;
import android.net.InetAddresses;
import android.net.InvalidPacketException;
@@ -111,7 +110,7 @@
mTcpController = new TcpKeepaliveController(handler);
mContext = context;
- mSupportedKeepalives = KeepaliveUtils.getSupportedKeepalives(mContext);
+ mSupportedKeepalives = KeepaliveResourceUtil.getSupportedKeepalives(context);
final ConnectivityResources res = new ConnectivityResources(mContext);
mReservedPrivilegedSlots = res.get().getInteger(
diff --git a/service/src/com/android/server/connectivity/LingerMonitor.java b/service/src/com/android/server/connectivity/LingerMonitor.java
index df34ce7..8503fcc 100644
--- a/service/src/com/android/server/connectivity/LingerMonitor.java
+++ b/service/src/com/android/server/connectivity/LingerMonitor.java
@@ -25,7 +25,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
-import android.net.ConnectivityResources;
import android.net.NetworkCapabilities;
import android.os.SystemClock;
import android.os.UserHandle;
diff --git a/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java b/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java
index 58196f7..93018bb 100644
--- a/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java
+++ b/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java
@@ -28,7 +28,6 @@
import android.content.IntentFilter;
import android.content.res.Resources;
import android.database.ContentObserver;
-import android.net.ConnectivityResources;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
diff --git a/service/src/com/android/server/connectivity/NetworkDiagnostics.java b/service/src/com/android/server/connectivity/NetworkDiagnostics.java
index 509110d..4eba74b 100644
--- a/service/src/com/android/server/connectivity/NetworkDiagnostics.java
+++ b/service/src/com/android/server/connectivity/NetworkDiagnostics.java
@@ -18,6 +18,8 @@
import static android.system.OsConstants.*;
+import static com.android.net.module.util.NetworkStackConstants.ICMP_HEADER_LEN;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.InetAddresses;
@@ -264,7 +266,7 @@
private void prepareIcmpMeasurement(InetAddress target) {
if (!mIcmpChecks.containsKey(target)) {
Measurement measurement = new Measurement();
- measurement.thread = new Thread(new IcmpCheck(target, measurement));
+ measurement.thread = new Thread(new IcmpCheck(target, 0, measurement));
mIcmpChecks.put(target, measurement);
}
}
@@ -276,7 +278,7 @@
Pair<InetAddress, InetAddress> srcTarget = new Pair<>(source, target);
if (!mExplicitSourceIcmpChecks.containsKey(srcTarget)) {
Measurement measurement = new Measurement();
- measurement.thread = new Thread(new IcmpCheck(source, target, measurement));
+ measurement.thread = new Thread(new IcmpCheck(source, target, 0, measurement));
mExplicitSourceIcmpChecks.put(srcTarget, measurement);
}
}
@@ -489,8 +491,11 @@
private static final int PACKET_BUFSIZE = 512;
private final int mProtocol;
private final int mIcmpType;
+ private final int mPayloadSize;
+ // The length parameter is effectively the -s flag to ping/ping6 to specify the number of
+ // data bytes to be sent.
+ IcmpCheck(InetAddress source, InetAddress target, int length, Measurement measurement) {
- public IcmpCheck(InetAddress source, InetAddress target, Measurement measurement) {
super(source, target, measurement);
if (mAddressFamily == AF_INET6) {
@@ -502,12 +507,13 @@
mIcmpType = NetworkConstants.ICMPV4_ECHO_REQUEST_TYPE;
mMeasurement.description = "ICMPv4";
}
-
- mMeasurement.description += " dst{" + mTarget.getHostAddress() + "}";
+ mPayloadSize = length;
+ mMeasurement.description += " payloadLength{" + mPayloadSize + "}"
+ + " dst{" + mTarget.getHostAddress() + "}";
}
- public IcmpCheck(InetAddress target, Measurement measurement) {
- this(null, target, measurement);
+ IcmpCheck(InetAddress target, int length, Measurement measurement) {
+ this(null, target, length, measurement);
}
@Override
@@ -523,9 +529,11 @@
mMeasurement.description += " src{" + socketAddressToString(mSocketAddress) + "}";
// Build a trivial ICMP packet.
- final byte[] icmpPacket = {
- (byte) mIcmpType, 0, 0, 0, 0, 0, 0, 0 // ICMP header
- };
+ // The v4 ICMP header ICMP_HEADER_LEN (which is 8) and v6 is only 4 bytes (4 bytes
+ // message body followed by header before the payload).
+ // Use 8 bytes for both v4 and v6 for simplicity.
+ final byte[] icmpPacket = new byte[ICMP_HEADER_LEN + mPayloadSize];
+ icmpPacket[0] = (byte) mIcmpType;
int count = 0;
mMeasurement.startTime = now();
diff --git a/service/src/com/android/server/connectivity/NetworkNotificationManager.java b/service/src/com/android/server/connectivity/NetworkNotificationManager.java
index cdc0aa9..8b0cb7c 100644
--- a/service/src/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/service/src/com/android/server/connectivity/NetworkNotificationManager.java
@@ -30,7 +30,6 @@
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Icon;
-import android.net.ConnectivityResources;
import android.net.NetworkSpecifier;
import android.net.TelephonyNetworkSpecifier;
import android.net.wifi.WifiInfo;
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
index c28ee64..624acd3 100755
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -154,7 +154,6 @@
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@@ -809,26 +808,12 @@
mOldPrivateDnsSpecifier);
}
- // TODO: replace with CtsNetUtils.awaitPrivateDnsSetting in Q or above.
private void expectPrivateDnsHostname(final String hostname) throws Exception {
- final NetworkRequest request = new NetworkRequest.Builder()
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
- .build();
- final CountDownLatch latch = new CountDownLatch(1);
- final NetworkCallback callback = new NetworkCallback() {
- @Override
- public void onLinkPropertiesChanged(Network network, LinkProperties lp) {
- if (network.equals(mNetwork) &&
- Objects.equals(lp.getPrivateDnsServerName(), hostname)) {
- latch.countDown();
- }
- }
- };
-
- registerNetworkCallback(request, callback);
-
- assertTrue("Private DNS hostname was not " + hostname + " after " + TIMEOUT_MS + "ms",
- latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ for (Network network : mCtsNetUtils.getTestableNetworks()) {
+ // Wait for private DNS setting to propagate.
+ mCtsNetUtils.awaitPrivateDnsSetting("Test wait private DNS setting timeout",
+ network, hostname, false);
+ }
}
private void setAndVerifyPrivateDns(boolean strictMode) throws Exception {
diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml
index 999614c..68e36ff 100644
--- a/tests/cts/net/AndroidManifest.xml
+++ b/tests/cts/net/AndroidManifest.xml
@@ -37,9 +37,6 @@
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
- <!-- TODO (b/186093901): remove after fixing resource querying -->
- <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
-
<!-- This test also uses signature permissions through adopting the shell identity.
The permissions acquired that way include (probably not exhaustive) :
android.permission.MANAGE_TEST_NETWORKS
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 9d234d3..423b2bd 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -1655,7 +1655,8 @@
final NetworkCapabilities nc = mCm.getNetworkCapabilities(network);
// Get number of supported concurrent keepalives for testing network.
- final int[] keepalivesPerTransport = KeepaliveUtils.getSupportedKeepalives(mContext);
+ final int[] keepalivesPerTransport = runAsShell(NETWORK_SETTINGS,
+ () -> mCm.getSupportedKeepalives());
return KeepaliveUtils.getSupportedKeepalivesForNetworkCapabilities(
keepalivesPerTransport, nc);
}
@@ -1670,6 +1671,9 @@
* keepalives is set to 0.
*/
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
+ // getSupportedKeepalives is available in updatable ConnectivityManager (S+)
+ // Also, this feature is not mainlined before S, and it's fine to skip on R- devices.
+ @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) @ConnectivityModuleTest
@Test
public void testKeepaliveWifiUnsupported() throws Exception {
assumeTrue(mPackageManager.hasSystemFeature(FEATURE_WIFI));
@@ -1686,6 +1690,9 @@
}
@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
+ // getSupportedKeepalives is available in updatable ConnectivityManager (S+)
+ // Also, this feature is not mainlined before S, and it's fine to skip on R- devices.
+ @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) @ConnectivityModuleTest
@Test
@RequiresDevice // Keepalive is not supported on virtual hardware
public void testCreateTcpKeepalive() throws Exception {
@@ -2112,7 +2119,12 @@
@AppModeFull(reason = "NETWORK_AIRPLANE_MODE permission can't be granted to instant apps")
@Test
public void testSetAirplaneMode() throws Exception{
- final boolean supportWifi = mPackageManager.hasSystemFeature(FEATURE_WIFI);
+ // Starting from T, wifi supports airplane mode enhancement which may not disconnect wifi
+ // when airplane mode is on. The actual behavior that the device will have could only be
+ // checked with hidden wifi APIs(see Settings.Secure.WIFI_APM_STATE). Thus, stop verifying
+ // wifi on T+ device.
+ final boolean verifyWifi = mPackageManager.hasSystemFeature(FEATURE_WIFI)
+ && !SdkLevel.isAtLeastT();
final boolean supportTelephony = mPackageManager.hasSystemFeature(FEATURE_TELEPHONY);
// store the current state of airplane mode
final boolean isAirplaneModeEnabled = isAirplaneModeEnabled();
@@ -2123,7 +2135,7 @@
// Verify that networks are available as expected if wifi or cell is supported. Continue the
// test if none of them are supported since test should still able to verify the permission
// mechanism.
- if (supportWifi) {
+ if (verifyWifi) {
mCtsNetUtils.ensureWifiConnected();
registerCallbackAndWaitForAvailable(makeWifiNetworkRequest(), wifiCb);
}
@@ -2147,7 +2159,7 @@
// Verify that the enabling airplane mode takes effect as expected to prevent flakiness
// caused by fast airplane mode switches. Ensure network lost before turning off
// airplane mode.
- if (supportWifi) waitForLost(wifiCb);
+ if (verifyWifi) waitForLost(wifiCb);
if (supportTelephony) waitForLost(telephonyCb);
// Verify we can disable Airplane Mode with correct permission:
@@ -2156,7 +2168,7 @@
// Verify that turning airplane mode off takes effect as expected.
// connectToCell only registers a request, it cannot / does not need to be called twice
mCtsNetUtils.ensureWifiConnected();
- if (supportWifi) waitForAvailable(wifiCb);
+ if (verifyWifi) waitForAvailable(wifiCb);
if (supportTelephony) waitForAvailable(telephonyCb);
} finally {
// Restore the previous state of airplane mode and permissions:
diff --git a/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java b/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java
index 691ab99..17a9ca2 100644
--- a/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java
+++ b/tests/cts/net/src/android/net/cts/MultinetworkApiTest.java
@@ -18,21 +18,18 @@
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import android.content.Context;
import android.content.ContentResolver;
+import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkUtils;
import android.net.cts.util.CtsNetUtils;
import android.platform.test.annotations.AppModeFull;
-import android.provider.Settings;
import android.system.ErrnoException;
import android.system.OsConstants;
import android.test.AndroidTestCase;
-import java.util.ArrayList;
-
public class MultinetworkApiTest extends AndroidTestCase {
static {
@@ -75,26 +72,8 @@
super.tearDown();
}
- private Network[] getTestableNetworks() {
- final ArrayList<Network> testableNetworks = new ArrayList<Network>();
- for (Network network : mCM.getAllNetworks()) {
- final NetworkCapabilities nc = mCM.getNetworkCapabilities(network);
- if (nc != null
- && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
- testableNetworks.add(network);
- }
- }
-
- assertTrue(
- "This test requires that at least one network be connected. " +
- "Please ensure that the device is connected to a network.",
- testableNetworks.size() >= 1);
- return testableNetworks.toArray(new Network[0]);
- }
-
public void testGetaddrinfo() throws ErrnoException {
- for (Network network : getTestableNetworks()) {
+ for (Network network : mCtsNetUtils.getTestableNetworks()) {
int errno = runGetaddrinfoCheck(network.getNetworkHandle());
if (errno != 0) {
throw new ErrnoException(
@@ -109,7 +88,7 @@
assertNull(mCM.getProcessDefaultNetwork());
assertEquals(0, NetworkUtils.getBoundNetworkForProcess());
- for (Network network : getTestableNetworks()) {
+ for (Network network : mCtsNetUtils.getTestableNetworks()) {
mCM.setProcessDefaultNetwork(null);
assertNull(mCM.getProcessDefaultNetwork());
@@ -128,7 +107,7 @@
mCM.setProcessDefaultNetwork(null);
}
- for (Network network : getTestableNetworks()) {
+ for (Network network : mCtsNetUtils.getTestableNetworks()) {
NetworkUtils.bindProcessToNetwork(0);
assertNull(mCM.getBoundNetworkForProcess());
@@ -148,7 +127,7 @@
@AppModeFull(reason = "CHANGE_NETWORK_STATE permission can't be granted to instant apps")
public void testSetsocknetwork() throws ErrnoException {
- for (Network network : getTestableNetworks()) {
+ for (Network network : mCtsNetUtils.getTestableNetworks()) {
int errno = runSetsocknetwork(network.getNetworkHandle());
if (errno != 0) {
throw new ErrnoException(
@@ -158,7 +137,7 @@
}
public void testNativeDatagramTransmission() throws ErrnoException {
- for (Network network : getTestableNetworks()) {
+ for (Network network : mCtsNetUtils.getTestableNetworks()) {
int errno = runDatagramCheck(network.getNetworkHandle());
if (errno != 0) {
throw new ErrnoException(
@@ -181,7 +160,7 @@
public void testNetworkHandle() {
// Test Network -> NetworkHandle -> Network results in the same Network.
- for (Network network : getTestableNetworks()) {
+ for (Network network : mCtsNetUtils.getTestableNetworks()) {
long networkHandle = network.getNetworkHandle();
Network newNetwork = Network.fromNetworkHandle(networkHandle);
assertEquals(newNetwork, network);
@@ -203,7 +182,7 @@
}
public void testResNApi() throws Exception {
- final Network[] testNetworks = getTestableNetworks();
+ final Network[] testNetworks = mCtsNetUtils.getTestableNetworks();
for (Network network : testNetworks) {
// Throws AssertionError directly in jni function if test fail.
@@ -229,7 +208,7 @@
// b/144521720
try {
mCtsNetUtils.setPrivateDnsStrictMode(GOOGLE_PRIVATE_DNS_SERVER);
- for (Network network : getTestableNetworks()) {
+ for (Network network : mCtsNetUtils.getTestableNetworks()) {
// Wait for private DNS setting to propagate.
mCtsNetUtils.awaitPrivateDnsSetting("NxDomain test wait private DNS setting timeout",
network, GOOGLE_PRIVATE_DNS_SERVER, true);
diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
index d817630..0c4f794 100644
--- a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
+++ b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
@@ -57,6 +57,8 @@
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.Nullable;
+
import com.android.compatibility.common.util.PollingCheck;
import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.compatibility.common.util.SystemUtil;
@@ -68,6 +70,8 @@
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -506,17 +510,18 @@
* @throws InterruptedException If the thread is interrupted.
*/
public void awaitPrivateDnsSetting(@NonNull String msg, @NonNull Network network,
- @NonNull String server, boolean requiresValidatedServer) throws InterruptedException {
+ @Nullable String server, boolean requiresValidatedServer) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
- NetworkCallback callback = new NetworkCallback() {
+ final NetworkCallback callback = new NetworkCallback() {
@Override
public void onLinkPropertiesChanged(Network n, LinkProperties lp) {
Log.i(TAG, "Link properties of network " + n + " changed to " + lp);
if (requiresValidatedServer && lp.getValidatedPrivateDnsServers().isEmpty()) {
return;
}
- if (network.equals(n) && server.equals(lp.getPrivateDnsServerName())) {
+ Log.i(TAG, "Set private DNS server to " + server);
+ if (network.equals(n) && Objects.equals(server, lp.getPrivateDnsServerName())) {
latch.countDown();
}
}
@@ -539,6 +544,27 @@
}
/**
+ * Get all testable Networks with internet capability.
+ */
+ public Network[] getTestableNetworks() {
+ final ArrayList<Network> testableNetworks = new ArrayList<Network>();
+ for (Network network : mCm.getAllNetworks()) {
+ final NetworkCapabilities nc = mCm.getNetworkCapabilities(network);
+ if (nc != null
+ && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
+ testableNetworks.add(network);
+ }
+ }
+
+ assertTrue("This test requires that at least one public Internet-providing"
+ + " network be connected. Please ensure that the device is connected to"
+ + " a network.",
+ testableNetworks.size() >= 1);
+ return testableNetworks.toArray(new Network[0]);
+ }
+
+ /**
* Receiver that captures the last connectivity change's network type and state. Recognizes
* both {@code CONNECTIVITY_ACTION} and {@code NETWORK_CALLBACK_ACTION} intents.
*/
diff --git a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index 3c1340d..67e1296 100644
--- a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -25,7 +25,6 @@
import android.content.ServiceConnection
import android.content.res.Resources
import android.net.ConnectivityManager
-import android.net.ConnectivityResources
import android.net.IDnsResolver
import android.net.INetd
import android.net.LinkProperties
@@ -50,11 +49,15 @@
import com.android.server.ConnectivityService
import com.android.server.NetworkAgentWrapper
import com.android.server.TestNetIdManager
+import com.android.server.connectivity.ConnectivityResources
import com.android.server.connectivity.MockableSystemProperties
import com.android.server.connectivity.MultinetworkPolicyTracker
import com.android.server.connectivity.ProxyTracker
import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged
import com.android.testutils.TestableNetworkCallback
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+import kotlin.test.fail
import org.junit.After
import org.junit.Before
import org.junit.BeforeClass
@@ -73,9 +76,6 @@
import org.mockito.Mockito.spy
import org.mockito.MockitoAnnotations
import org.mockito.Spy
-import kotlin.test.assertEquals
-import kotlin.test.assertTrue
-import kotlin.test.fail
const val SERVICE_BIND_TIMEOUT_MS = 5_000L
const val TEST_TIMEOUT_MS = 10_000L
@@ -215,8 +215,8 @@
inv.getArgument(2),
object : MultinetworkPolicyTracker.Dependencies() {
override fun getResourcesForActiveSubId(
- connResources: ConnectivityResources,
- activeSubId: Int
+ connResources: ConnectivityResources,
+ activeSubId: Int
) = resources
})
}.`when`(deps).makeMultinetworkPolicyTracker(any(), any(), any())
diff --git a/tests/unit/java/android/net/util/KeepaliveUtilsTest.kt b/tests/unit/java/android/net/util/KeepaliveUtilsTest.kt
index cca0b66..cb3a315 100644
--- a/tests/unit/java/android/net/util/KeepaliveUtilsTest.kt
+++ b/tests/unit/java/android/net/util/KeepaliveUtilsTest.kt
@@ -18,7 +18,6 @@
import android.content.Context
import android.content.res.Resources
-import android.net.ConnectivityResources
import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.MAX_TRANSPORT
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
@@ -27,7 +26,9 @@
import android.net.NetworkCapabilities.TRANSPORT_WIFI
import android.os.Build
import androidx.test.filters.SmallTest
-import com.android.internal.R
+import com.android.connectivity.resources.R
+import com.android.server.connectivity.ConnectivityResources
+import com.android.server.connectivity.KeepaliveResourceUtil
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import org.junit.After
@@ -37,7 +38,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.eq
-import org.mockito.Mockito.any
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
@@ -53,14 +53,9 @@
class KeepaliveUtilsTest {
// Prepare mocked context with given resource strings.
- private fun getMockedContextWithStringArrayRes(
- id: Int,
- name: String,
- res: Array<out String?>?
- ): Context {
+ private fun getMockedContextWithStringArrayRes(id: Int, res: Array<out String?>?): Context {
val mockRes = mock(Resources::class.java)
doReturn(res).`when`(mockRes).getStringArray(eq(id))
- doReturn(id).`when`(mockRes).getIdentifier(eq(name), any(), any())
return mock(Context::class.java).apply {
doReturn(mockRes).`when`(this).getResources()
@@ -79,10 +74,10 @@
try {
val mockContext = getMockedContextWithStringArrayRes(
R.array.config_networkSupportedKeepaliveCount,
- "config_networkSupportedKeepaliveCount", res)
- KeepaliveUtils.getSupportedKeepalives(mockContext)
+ res)
+ KeepaliveResourceUtil.getSupportedKeepalives(mockContext)
fail("Expected KeepaliveDeviceConfigurationException")
- } catch (expected: KeepaliveUtils.KeepaliveDeviceConfigurationException) {
+ } catch (expected: KeepaliveResourceUtil.KeepaliveDeviceConfigurationException) {
}
}
@@ -108,8 +103,8 @@
val mockContext = getMockedContextWithStringArrayRes(
R.array.config_networkSupportedKeepaliveCount,
- "config_networkSupportedKeepaliveCount", validRes)
- val actual = KeepaliveUtils.getSupportedKeepalives(mockContext)
+ validRes)
+ val actual = KeepaliveResourceUtil.getSupportedKeepalives(mockContext)
assertArrayEquals(expectedValidRes, actual)
}
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 32c854b..877df98 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -256,7 +256,6 @@
import android.net.ConnectivityManager.PacketKeepalive;
import android.net.ConnectivityManager.PacketKeepaliveCallback;
import android.net.ConnectivityManager.TooManyRequestsException;
-import android.net.ConnectivityResources;
import android.net.ConnectivitySettingsManager;
import android.net.ConnectivityThread;
import android.net.DataStallReportParcelable;
@@ -389,6 +388,7 @@
import com.android.server.connectivity.CarrierPrivilegeAuthenticator;
import com.android.server.connectivity.ClatCoordinator;
import com.android.server.connectivity.ConnectivityFlags;
+import com.android.server.connectivity.ConnectivityResources;
import com.android.server.connectivity.MultinetworkPolicyTracker;
import com.android.server.connectivity.MultinetworkPolicyTrackerTestDependencies;
import com.android.server.connectivity.Nat464Xlat;
@@ -1858,7 +1858,7 @@
final Context mockResContext = mock(Context.class);
doReturn(mResources).when(mockResContext).getResources();
ConnectivityResources.setResourcesContextForTest(mockResContext);
- mDeps = new ConnectivityServiceDependencies(mockResContext);
+ mDeps = spy(new ConnectivityServiceDependencies(mockResContext));
mAutoOnOffKeepaliveDependencies =
new AutomaticOnOffKeepaliveTrackerDependencies(mServiceContext);
mService = new ConnectivityService(mServiceContext,
@@ -1921,7 +1921,8 @@
R.integer.config_networkWakeupPacketMark);
}
- class ConnectivityServiceDependencies extends ConnectivityService.Dependencies {
+ // ConnectivityServiceDependencies is public to use Mockito.spy
+ public class ConnectivityServiceDependencies extends ConnectivityService.Dependencies {
final ConnectivityResources mConnRes;
ConnectivityServiceDependencies(final Context mockResContext) {
@@ -2157,6 +2158,12 @@
}
}
}
+
+ @Override
+ public void destroyLiveTcpSockets(final Set<Range<Integer>> ranges,
+ final Set<Integer> exemptUids) {
+ // This function is empty since the invocation of this method is verified by mocks
+ }
}
private class AutomaticOnOffKeepaliveTrackerDependencies
@@ -12524,12 +12531,11 @@
private void assertVpnUidRangesUpdated(boolean add, Set<UidRange> vpnRanges, int exemptUid)
throws Exception {
- InOrder inOrder = inOrder(mMockNetd);
- ArgumentCaptor<int[]> exemptUidCaptor = ArgumentCaptor.forClass(int[].class);
+ InOrder inOrder = inOrder(mMockNetd, mDeps);
+ final Set<Integer> exemptUidSet = new ArraySet<>(List.of(exemptUid, Process.VPN_UID));
- inOrder.verify(mMockNetd, times(1)).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)),
- exemptUidCaptor.capture());
- assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid);
+ inOrder.verify(mDeps).destroyLiveTcpSockets(UidRange.toIntRanges(vpnRanges),
+ exemptUidSet);
if (add) {
inOrder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(
@@ -12541,9 +12547,8 @@
toUidRangeStableParcels(vpnRanges), PREFERENCE_ORDER_VPN));
}
- inOrder.verify(mMockNetd, times(1)).socketDestroy(eq(toUidRangeStableParcels(vpnRanges)),
- exemptUidCaptor.capture());
- assertContainsExactly(exemptUidCaptor.getValue(), Process.VPN_UID, exemptUid);
+ inOrder.verify(mDeps).destroyLiveTcpSockets(UidRange.toIntRanges(vpnRanges),
+ exemptUidSet);
}
@Test
@@ -17625,18 +17630,77 @@
});
}
+ private void verifyMtuSetOnWifiInterface(int mtu) throws Exception {
+ verify(mMockNetd, times(1)).interfaceSetMtu(WIFI_IFNAME, mtu);
+ }
+
+ private void verifyMtuNeverSetOnWifiInterface() throws Exception {
+ verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt());
+ }
+
@Test
- public void testSendLinkPropertiesSetInterfaceMtu() throws Exception {
- final int mtu = 1327;
+ public void testSendLinkPropertiesSetInterfaceMtuBeforeConnect() throws Exception {
+ final int mtu = 1281;
LinkProperties lp = new LinkProperties();
lp.setInterfaceName(WIFI_IFNAME);
lp.setMtu(mtu);
mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiAgent.sendLinkProperties(lp);
-
waitForIdle();
- verify(mMockNetd).interfaceSetMtu(eq(WIFI_IFNAME), eq(mtu));
+ verifyMtuSetOnWifiInterface(mtu);
+ reset(mMockNetd);
+
+ mWiFiAgent.connect(false /* validated */);
+ // The MTU is always (re-)applied when the network connects.
+ verifyMtuSetOnWifiInterface(mtu);
+ }
+
+ @Test
+ public void testSendLinkPropertiesUpdateInterfaceMtuBeforeConnect() throws Exception {
+ final int mtu = 1327;
+ LinkProperties lp = new LinkProperties();
+ lp.setInterfaceName(WIFI_IFNAME);
+ lp.setMtu(mtu);
+
+ // Registering an agent with an MTU doesn't set the MTU...
+ mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp);
+ waitForIdle();
+ verifyMtuNeverSetOnWifiInterface();
+ reset(mMockNetd);
+
+ // ... but prevents future updates with the same MTU from setting the MTU.
+ mWiFiAgent.sendLinkProperties(lp);
+ waitForIdle();
+ verifyMtuNeverSetOnWifiInterface();
+
+ // Updating with a different MTU does work.
+ lp.setMtu(mtu + 1);
+ mWiFiAgent.sendLinkProperties(lp);
+ waitForIdle();
+ verifyMtuSetOnWifiInterface(mtu + 1);
+ reset(mMockNetd);
+
+ mWiFiAgent.connect(false /* validated */);
+ // The MTU is always (re-)applied when the network connects.
+ verifyMtuSetOnWifiInterface(mtu + 1);
+ }
+
+ @Test
+ public void testSendLinkPropertiesUpdateInterfaceMtuAfterConnect() throws Exception {
+ final int mtu = 1327;
+ LinkProperties lp = new LinkProperties();
+ lp.setInterfaceName(WIFI_IFNAME);
+ lp.setMtu(mtu);
+
+ mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+ mWiFiAgent.connect(false /* validated */);
+ verifyMtuNeverSetOnWifiInterface();
+
+ mWiFiAgent.sendLinkProperties(lp);
+ waitForIdle();
+ // The MTU is always (re-)applied when the network connects.
+ verifyMtuSetOnWifiInterface(mtu);
}
@Test
@@ -17647,14 +17711,15 @@
lp.setMtu(mtu);
mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp);
+ mWiFiAgent.connect(false /* validated */);
+ verifyMtuSetOnWifiInterface(mtu);
+ reset(mMockNetd);
LinkProperties lp2 = new LinkProperties(lp);
lp2.setMtu(mtu2);
-
mWiFiAgent.sendLinkProperties(lp2);
-
waitForIdle();
- verify(mMockNetd).interfaceSetMtu(eq(WIFI_IFNAME), eq(mtu2));
+ verifyMtuSetOnWifiInterface(mtu2);
}
@Test
@@ -17665,10 +17730,13 @@
lp.setMtu(mtu);
mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp);
- mWiFiAgent.sendLinkProperties(new LinkProperties(lp));
+ mWiFiAgent.connect(false /* validated */);
+ verifyMtuSetOnWifiInterface(mtu);
+ reset(mMockNetd);
+ mWiFiAgent.sendLinkProperties(new LinkProperties(lp));
waitForIdle();
- verify(mMockNetd, never()).interfaceSetMtu(eq(WIFI_IFNAME), anyInt());
+ verifyMtuNeverSetOnWifiInterface();
}
@Test
@@ -17679,15 +17747,15 @@
lp.setMtu(mtu);
mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp);
+ mWiFiAgent.connect(false /* validated */);
+ verifyMtuSetOnWifiInterface(mtu);
+ reset(mMockNetd);
- LinkProperties lp2 = new LinkProperties();
- assertNull(lp2.getInterfaceName());
- lp2.setMtu(mtu);
-
+ LinkProperties lp2 = new LinkProperties(lp);
+ lp2.setInterfaceName(null);
mWiFiAgent.sendLinkProperties(new LinkProperties(lp2));
-
waitForIdle();
- verify(mMockNetd, never()).interfaceSetMtu(any(), anyInt());
+ verifyMtuNeverSetOnWifiInterface();
}
@Test
@@ -17698,16 +17766,18 @@
lp.setMtu(mtu);
mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp);
+ mWiFiAgent.connect(false /* validated */);
+ verifyMtuSetOnWifiInterface(mtu);
+ reset(mMockNetd);
final String ifaceName2 = WIFI_IFNAME + "_2";
- LinkProperties lp2 = new LinkProperties();
+ LinkProperties lp2 = new LinkProperties(lp);
lp2.setInterfaceName(ifaceName2);
- lp2.setMtu(mtu);
mWiFiAgent.sendLinkProperties(new LinkProperties(lp2));
-
waitForIdle();
- verify(mMockNetd).interfaceSetMtu(eq(ifaceName2), eq(mtu));
+ verify(mMockNetd, times(1)).interfaceSetMtu(eq(ifaceName2), eq(mtu));
+ verifyMtuNeverSetOnWifiInterface();
}
@Test
diff --git a/tests/unit/java/com/android/server/connectivity/AutomaticOnOffKeepaliveTrackerTest.java b/tests/unit/java/com/android/server/connectivity/AutomaticOnOffKeepaliveTrackerTest.java
index 3eb1b26..9e0435d 100644
--- a/tests/unit/java/com/android/server/connectivity/AutomaticOnOffKeepaliveTrackerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/AutomaticOnOffKeepaliveTrackerTest.java
@@ -38,7 +38,6 @@
import android.app.AlarmManager;
import android.content.Context;
import android.content.res.Resources;
-import android.net.ConnectivityResources;
import android.net.INetd;
import android.net.ISocketKeepaliveCallback;
import android.net.KeepalivePacketData;
@@ -63,6 +62,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.connectivity.resources.R;
import com.android.server.connectivity.KeepaliveTracker.KeepaliveInfo;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
@@ -235,10 +235,8 @@
anyInt() /* pid */, anyInt() /* uid */);
ConnectivityResources.setResourcesContextForTest(mCtx);
final Resources mockResources = mock(Resources.class);
- doReturn(MOCK_RESOURCE_ID).when(mockResources).getIdentifier(any() /* name */,
- any() /* defType */, any() /* defPackage */);
doReturn(new String[] { "0,3", "3,3" }).when(mockResources)
- .getStringArray(MOCK_RESOURCE_ID);
+ .getStringArray(R.array.config_networkSupportedKeepaliveCount);
doReturn(mockResources).when(mCtx).getResources();
doReturn(mNetd).when(mDependencies).getNetd();
doReturn(mAlarmManager).when(mDependencies).getAlarmManager(any());
diff --git a/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java b/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
index b651c33..4158663 100644
--- a/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
@@ -313,8 +313,7 @@
* Stop clatd.
*/
@Override
- public void stopClatd(@NonNull String iface, @NonNull String pfx96, @NonNull String v4,
- @NonNull String v6, int pid) throws IOException {
+ public void stopClatd(int pid) throws IOException {
if (pid == -1) {
fail("unsupported arg: " + pid);
}
@@ -479,8 +478,7 @@
eq((short) PRIO_CLAT), eq((short) ETH_P_IP));
inOrder.verify(mEgressMap).deleteEntry(eq(EGRESS_KEY));
inOrder.verify(mIngressMap).deleteEntry(eq(INGRESS_KEY));
- inOrder.verify(mDeps).stopClatd(eq(BASE_IFACE), eq(NAT64_PREFIX_STRING),
- eq(XLAT_LOCAL_IPV4ADDR_STRING), eq(XLAT_LOCAL_IPV6ADDR_STRING), eq(CLATD_PID));
+ inOrder.verify(mDeps).stopClatd(eq(CLATD_PID));
inOrder.verify(mCookieTagMap).deleteEntry(eq(COOKIE_TAG_KEY));
assertNull(coordinator.getClatdTrackerForTesting());
inOrder.verifyNoMoreInteractions();
diff --git a/tests/unit/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/unit/java/com/android/server/connectivity/LingerMonitorTest.java
index 0d371fa..e6c0c83 100644
--- a/tests/unit/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -34,7 +34,6 @@
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.ConnectivityManager;
-import android.net.ConnectivityResources;
import android.net.IDnsResolver;
import android.net.INetd;
import android.net.LinkProperties;
diff --git a/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt
index b52e8a8..f19ba4f 100644
--- a/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt
@@ -21,10 +21,8 @@
import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER
import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE
import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY
-import android.net.ConnectivityResources
import android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI
import android.net.ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE
-import com.android.server.connectivity.MultinetworkPolicyTracker.ActiveDataSubscriptionIdListener
import android.os.Build
import android.os.Handler
import android.os.test.TestLooper
@@ -37,6 +35,7 @@
import com.android.connectivity.resources.R
import com.android.internal.util.test.FakeSettingsProvider
import com.android.modules.utils.build.SdkLevel
+import com.android.server.connectivity.MultinetworkPolicyTracker.ActiveDataSubscriptionIdListener
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import org.junit.After
diff --git a/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt
index 744c020..4c82c76 100644
--- a/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt
+++ b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt
@@ -1,7 +1,6 @@
package com.android.server.connectivity
import android.content.res.Resources
-import android.net.ConnectivityResources
import android.provider.DeviceConfig
import android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY
import android.provider.DeviceConfig.OnPropertiesChangedListener
diff --git a/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index e038c44..a27a0bf 100644
--- a/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -51,7 +51,6 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
-import android.net.ConnectivityResources;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.os.Build;
diff --git a/tests/unit/java/com/android/server/connectivity/VpnTest.java b/tests/unit/java/com/android/server/connectivity/VpnTest.java
index 2926c9a..395e2bb 100644
--- a/tests/unit/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/unit/java/com/android/server/connectivity/VpnTest.java
@@ -142,6 +142,7 @@
import android.net.ipsec.ike.exceptions.IkeNonProtocolException;
import android.net.ipsec.ike.exceptions.IkeProtocolException;
import android.net.ipsec.ike.exceptions.IkeTimeoutException;
+import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
@@ -1563,6 +1564,11 @@
}
private NetworkCallback triggerOnAvailableAndGetCallback() throws Exception {
+ return triggerOnAvailableAndGetCallback(new NetworkCapabilities.Builder().build());
+ }
+
+ private NetworkCallback triggerOnAvailableAndGetCallback(
+ @NonNull final NetworkCapabilities caps) throws Exception {
final ArgumentCaptor<NetworkCallback> networkCallbackCaptor =
ArgumentCaptor.forClass(NetworkCallback.class);
verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS))
@@ -1579,7 +1585,7 @@
// if NetworkCapabilities and LinkProperties of underlying network will be sent/cleared or
// not.
// See verifyVpnManagerEvent().
- cb.onCapabilitiesChanged(TEST_NETWORK, new NetworkCapabilities());
+ cb.onCapabilitiesChanged(TEST_NETWORK, caps);
cb.onLinkPropertiesChanged(TEST_NETWORK, new LinkProperties());
return cb;
}
@@ -1903,12 +1909,15 @@
private PlatformVpnSnapshot verifySetupPlatformVpn(VpnProfile vpnProfile,
IkeSessionConfiguration ikeConfig, boolean mtuSupportsIpv6) throws Exception {
- return verifySetupPlatformVpn(vpnProfile, ikeConfig, mtuSupportsIpv6,
- false /* areLongLivedTcpConnectionsExpensive */);
+ return verifySetupPlatformVpn(vpnProfile, ikeConfig,
+ new NetworkCapabilities.Builder().build() /* underlying network caps */,
+ mtuSupportsIpv6, false /* areLongLivedTcpConnectionsExpensive */);
}
private PlatformVpnSnapshot verifySetupPlatformVpn(VpnProfile vpnProfile,
- IkeSessionConfiguration ikeConfig, boolean mtuSupportsIpv6,
+ IkeSessionConfiguration ikeConfig,
+ @NonNull final NetworkCapabilities underlyingNetworkCaps,
+ boolean mtuSupportsIpv6,
boolean areLongLivedTcpConnectionsExpensive) throws Exception {
if (!mtuSupportsIpv6) {
doReturn(IPV6_MIN_MTU - 1).when(mTestDeps).calculateVpnMtu(any(), anyInt(), anyInt(),
@@ -1925,7 +1934,7 @@
.thenReturn(vpnProfile.encode());
vpn.startVpnProfile(TEST_VPN_PKG);
- final NetworkCallback nwCb = triggerOnAvailableAndGetCallback();
+ final NetworkCallback nwCb = triggerOnAvailableAndGetCallback(underlyingNetworkCaps);
verify(mExecutor, atLeastOnce()).schedule(any(Runnable.class), anyLong(), any());
reset(mExecutor);
@@ -2079,15 +2088,16 @@
doTestMigrateIkeSession(ikeProfile.toVpnProfile(),
expectedKeepalive,
ESP_IP_VERSION_AUTO /* expectedIpVersion */,
- ESP_ENCAP_TYPE_AUTO /* expectedEncapType */);
+ ESP_ENCAP_TYPE_AUTO /* expectedEncapType */,
+ new NetworkCapabilities.Builder().build());
}
- private void doTestMigrateIkeSession_FromIkeTunnConnParams(
+ private Ikev2VpnProfile makeIkeV2VpnProfile(
boolean isAutomaticIpVersionSelectionEnabled,
boolean isAutomaticNattKeepaliveTimerEnabled,
int keepaliveInProfile,
int ipVersionInProfile,
- int encapTypeInProfile) throws Exception {
+ int encapTypeInProfile) {
// TODO: Update helper function in IkeSessionTestUtils to support building IkeSessionParams
// with IP version and encap type when mainline-prod branch support these two APIs.
final IkeSessionParams params = getTestIkeSessionParams(true /* testIpv6 */,
@@ -2099,12 +2109,40 @@
final IkeTunnelConnectionParams tunnelParams =
new IkeTunnelConnectionParams(ikeSessionParams, CHILD_PARAMS);
- final Ikev2VpnProfile ikeProfile = new Ikev2VpnProfile.Builder(tunnelParams)
+ return new Ikev2VpnProfile.Builder(tunnelParams)
.setBypassable(true)
.setAutomaticNattKeepaliveTimerEnabled(isAutomaticNattKeepaliveTimerEnabled)
.setAutomaticIpVersionSelectionEnabled(isAutomaticIpVersionSelectionEnabled)
.build();
+ }
+ private void doTestMigrateIkeSession_FromIkeTunnConnParams(
+ boolean isAutomaticIpVersionSelectionEnabled,
+ boolean isAutomaticNattKeepaliveTimerEnabled,
+ int keepaliveInProfile,
+ int ipVersionInProfile,
+ int encapTypeInProfile) throws Exception {
+ doTestMigrateIkeSession_FromIkeTunnConnParams(isAutomaticIpVersionSelectionEnabled,
+ isAutomaticNattKeepaliveTimerEnabled, keepaliveInProfile, ipVersionInProfile,
+ encapTypeInProfile, new NetworkCapabilities.Builder().build());
+ }
+
+ private void doTestMigrateIkeSession_FromIkeTunnConnParams(
+ boolean isAutomaticIpVersionSelectionEnabled,
+ boolean isAutomaticNattKeepaliveTimerEnabled,
+ int keepaliveInProfile,
+ int ipVersionInProfile,
+ int encapTypeInProfile,
+ @NonNull final NetworkCapabilities nc) throws Exception {
+ final Ikev2VpnProfile ikeProfile = makeIkeV2VpnProfile(
+ isAutomaticIpVersionSelectionEnabled,
+ isAutomaticNattKeepaliveTimerEnabled,
+ keepaliveInProfile,
+ ipVersionInProfile,
+ encapTypeInProfile);
+
+ final IkeSessionParams ikeSessionParams =
+ ikeProfile.getIkeTunnelConnectionParams().getIkeSessionParams();
final int expectedKeepalive = isAutomaticNattKeepaliveTimerEnabled
? AUTOMATIC_KEEPALIVE_DELAY_SECONDS
: ikeSessionParams.getNattKeepAliveDelaySeconds();
@@ -2115,22 +2153,48 @@
? ESP_ENCAP_TYPE_AUTO
: ikeSessionParams.getEncapType();
doTestMigrateIkeSession(ikeProfile.toVpnProfile(), expectedKeepalive,
- expectedIpVersion, expectedEncapType);
+ expectedIpVersion, expectedEncapType, nc);
}
- private void doTestMigrateIkeSession(VpnProfile profile,
- int expectedKeepalive, int expectedIpVersion, int expectedEncapType) throws Exception {
+ @Test
+ public void doTestMigrateIkeSession_Vcn() throws Exception {
+ final int expectedKeepalive = 2097; // Any unlikely number will do
+ final NetworkCapabilities vcnNc = new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_CELLULAR)
+ .setTransportInfo(new VcnTransportInfo(TEST_SUB_ID, expectedKeepalive))
+ .build();
+ final Ikev2VpnProfile ikev2VpnProfile = makeIkeV2VpnProfile(
+ true /* isAutomaticIpVersionSelectionEnabled */,
+ true /* isAutomaticNattKeepaliveTimerEnabled */,
+ 234 /* keepaliveInProfile */, // Should be ignored, any value will do
+ ESP_IP_VERSION_IPV4, // Should be ignored
+ ESP_ENCAP_TYPE_UDP // Should be ignored
+ );
+ doTestMigrateIkeSession(
+ ikev2VpnProfile.toVpnProfile(),
+ expectedKeepalive,
+ ESP_IP_VERSION_AUTO /* expectedIpVersion */,
+ ESP_ENCAP_TYPE_AUTO /* expectedEncapType */,
+ vcnNc);
+ }
+
+ private void doTestMigrateIkeSession(
+ @NonNull final VpnProfile profile,
+ final int expectedKeepalive,
+ final int expectedIpVersion,
+ final int expectedEncapType,
+ @NonNull final NetworkCapabilities caps) throws Exception {
final PlatformVpnSnapshot vpnSnapShot =
verifySetupPlatformVpn(profile,
createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */),
+ caps /* underlying network capabilities */,
false /* mtuSupportsIpv6 */,
expectedKeepalive < DEFAULT_LONG_LIVED_TCP_CONNS_EXPENSIVE_TIMEOUT_SEC);
// Simulate a new network coming up
vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2);
verify(mIkeSessionWrapper, never()).setNetwork(any(), anyInt(), anyInt(), anyInt());
- vpnSnapShot.nwCb.onCapabilitiesChanged(
- TEST_NETWORK_2, new NetworkCapabilities.Builder().build());
+ vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2, caps);
// Verify MOBIKE is triggered
verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS)).setNetwork(TEST_NETWORK_2,
expectedIpVersion, expectedEncapType, expectedKeepalive);
@@ -2156,6 +2220,7 @@
final PlatformVpnSnapshot vpnSnapShot =
verifySetupPlatformVpn(ikeProfile.toVpnProfile(),
createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */),
+ new NetworkCapabilities.Builder().build() /* underlying network caps */,
hasV6 /* mtuSupportsIpv6 */,
false /* areLongLivedTcpConnectionsExpensive */);
reset(mExecutor);
@@ -2343,6 +2408,7 @@
final PlatformVpnSnapshot vpnSnapShot =
verifySetupPlatformVpn(ikeProfile.toVpnProfile(),
createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */),
+ new NetworkCapabilities.Builder().build() /* underlying network caps */,
false /* mtuSupportsIpv6 */,
true /* areLongLivedTcpConnectionsExpensive */);
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index 04163fd..99f6d63 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -96,7 +96,6 @@
import android.content.Intent;
import android.content.res.Resources;
import android.database.ContentObserver;
-import android.net.ConnectivityResources;
import android.net.DataUsageRequest;
import android.net.INetd;
import android.net.INetworkStatsSession;
@@ -145,6 +144,7 @@
import com.android.net.module.util.bpf.CookieTagMapKey;
import com.android.net.module.util.bpf.CookieTagMapValue;
import com.android.server.BpfNetMaps;
+import com.android.server.connectivity.ConnectivityResources;
import com.android.server.net.NetworkStatsService.AlertObserver;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;