diff options
author | markchien <markchien@google.com> | 2020-10-15 09:42:31 +0800 |
---|---|---|
committer | markchien <markchien@google.com> | 2020-10-19 19:15:18 +0800 |
commit | 53487145a16ae4d2e4bd8967bbe62bf919a5a17a (patch) | |
tree | 1da3f294abf2b6d50d07205cc2cb3b2364235ca6 | |
parent | f1ad3b3416fdcbd4ff53d6e1024cb927fdb1c503 (diff) | |
download | base-53487145a16ae4d2e4bd8967bbe62bf919a5a17a.tar.gz |
Add the flag and default enable selectAllPrefixRange
Also add MtsTetheringTest which only run if tethering mainline
module is installed.
Bug: 166057846
Bug: 170265597
Test: atest TetheringTests
Change-Id: I434dda81eb5fab700d873a8ff3429b4222f0c7e6
Merged-In: I434dda81eb5fab700d873a8ff3429b4222f0c7e6
9 files changed, 365 insertions, 14 deletions
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java index 9fc1d7e5bcd0..4f616cdff086 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java @@ -80,11 +80,6 @@ public class PrivateAddressCoordinator { private final SparseArray<LinkAddress> mCachedAddresses; public PrivateAddressCoordinator(Context context, TetheringConfiguration config) { - this(context, config, new ArrayList<>(Arrays.asList(new IpPrefix("192.168.0.0/16")))); - } - - public PrivateAddressCoordinator(Context context, TetheringConfiguration config, - List<IpPrefix> prefixPools) { mDownstreams = new ArraySet<>(); mUpstreamPrefixMap = new ArrayMap<>(); mConnectivityMgr = (ConnectivityManager) context.getSystemService( @@ -95,7 +90,11 @@ public class PrivateAddressCoordinator { mCachedAddresses.put(TETHERING_BLUETOOTH, new LinkAddress(LEGACY_BLUETOOTH_IFACE_ADDRESS)); mCachedAddresses.put(TETHERING_WIFI_P2P, new LinkAddress(LEGACY_WIFI_P2P_IFACE_ADDRESS)); - mTetheringPrefixes = prefixPools; + mTetheringPrefixes = new ArrayList<>(Arrays.asList(new IpPrefix("192.168.0.0/16"))); + if (config.isSelectAllPrefixRangeEnabled()) { + mTetheringPrefixes.add(new IpPrefix("172.16.0.0/12")); + mTetheringPrefixes.add(new IpPrefix("10.0.0.0/8")); + } } /** diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java index 5783805861a3..799637c9b1c5 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java @@ -40,7 +40,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.StringJoiner; - /** * A utility class to encapsulate the various tethering configuration elements. * @@ -88,6 +87,13 @@ public class TetheringConfiguration { "use_legacy_wifi_p2p_dedicated_ip"; /** + * Flag use to enable select all prefix ranges feature. + * TODO: Remove this flag if there are no problems after M-2020-12 rolls out. + */ + public static final String TETHER_ENABLE_SELECT_ALL_PREFIX_RANGES = + "tether_enable_select_all_prefix_ranges"; + + /** * Default value that used to periodic polls tether offload stats from tethering offload HAL * to make the data warnings work. */ @@ -118,6 +124,8 @@ public class TetheringConfiguration { private final boolean mEnableBpfOffload; private final boolean mEnableWifiP2pDedicatedIp; + private final boolean mEnableSelectAllPrefixRange; + public TetheringConfiguration(Context ctx, SharedLog log, int id) { final SharedLog configLog = log.forSubComponent("config"); @@ -164,6 +172,11 @@ public class TetheringConfiguration { R.bool.config_tether_enable_legacy_wifi_p2p_dedicated_ip, false /* defaultValue */); + // Flags should normally not be booleans, but this is a kill-switch flag that is only used + // to turn off the feature, so binary rollback problems do not apply. + mEnableSelectAllPrefixRange = getDeviceConfigBoolean( + TETHER_ENABLE_SELECT_ALL_PREFIX_RANGES, true /* defaultValue */); + configLog.log(toString()); } @@ -249,6 +262,9 @@ public class TetheringConfiguration { pw.print("enableWifiP2pDedicatedIp: "); pw.println(mEnableWifiP2pDedicatedIp); + + pw.print("mEnableSelectAllPrefixRange: "); + pw.println(mEnableSelectAllPrefixRange); } /** Returns the string representation of this object.*/ @@ -310,6 +326,10 @@ public class TetheringConfiguration { return mEnableBpfOffload; } + public boolean isSelectAllPrefixRangeEnabled() { + return mEnableSelectAllPrefixRange; + } + private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) { final int[] ifaceTypes = res.getIntArray(R.array.config_tether_upstream_types); final ArrayList<Integer> upstreamIfaceTypes = new ArrayList<>(ifaceTypes.length); diff --git a/packages/Tethering/tests/mts/Android.bp b/packages/Tethering/tests/mts/Android.bp new file mode 100644 index 000000000000..f925b0a53f32 --- /dev/null +++ b/packages/Tethering/tests/mts/Android.bp @@ -0,0 +1,56 @@ +// Copyright (C) 2020 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. + +android_test { + // This tests for functionality that is not required for devices that + // don't use Tethering mainline module. + name: "MtsTetheringTest", + + libs: [ + "android.test.base", + ], + + srcs: [ + "src/**/*.java", + ], + + static_libs: [ + "androidx.test.rules", + // mockito-target-extended-minus-junit4 used in this lib have dependency with + // jni_libs libdexmakerjvmtiagent and libstaticjvmtiagent. + "cts-net-utils", + // This is needed for androidx.test.runner.AndroidJUnitRunner. + "ctstestrunner-axt", + "junit", + "junit-params", + ], + + jni_libs: [ + // For mockito extended which is pulled in from -net-utils -> net-tests-utils + // (mockito-target-extended-minus-junit4). + "libdexmakerjvmtiagent", + "libstaticjvmtiagent", + ], + + platform_apis: true, + + // Tag this module as a mts test artifact + test_suites: [ + "general-tests", + "mts", + ], + + // Include both the 32 and 64 bit versions + compile_multilib: "both", +} diff --git a/packages/Tethering/tests/mts/AndroidManifest.xml b/packages/Tethering/tests/mts/AndroidManifest.xml new file mode 100644 index 000000000000..6d2abcad42a3 --- /dev/null +++ b/packages/Tethering/tests/mts/AndroidManifest.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (C) 2020 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. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="android.tethering.mts"> + + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.INTERNET"/> + + <application android:debuggable="true"> + <uses-library android:name="android.test.runner" /> + </application> + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="android.tethering.mts" + android:label="MTS tests of android.tethering"> + <meta-data android:name="listener" + android:value="com.android.cts.runner.CtsTestRunListener" /> + </instrumentation> + +</manifest> diff --git a/packages/Tethering/tests/mts/AndroidTest.xml b/packages/Tethering/tests/mts/AndroidTest.xml new file mode 100644 index 000000000000..80788dfa6f40 --- /dev/null +++ b/packages/Tethering/tests/mts/AndroidTest.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2019 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. +--> +<configuration description="Config for MTS Tethering test cases"> + <option name="test-suite-tag" value="mts" /> + <option name="config-descriptor:metadata" key="component" value="networking" /> + <!-- Instant app do not have INTERNET permission. --> + <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" /> + <!-- Feature is not backed by native code. --> + <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <!-- Allow running this against a secondary user. --> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="MtsTetheringTest.apk" /> + </target_preparer> + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="android.tethering.mts" /> + </test> + + <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController"> + <option name="mainline-module-package-name" value="com.google.android.tethering" /> + </object> +</configuration> diff --git a/packages/Tethering/tests/mts/src/android/tethering/mts/TetheringModuleTest.java b/packages/Tethering/tests/mts/src/android/tethering/mts/TetheringModuleTest.java new file mode 100644 index 000000000000..7ffe37ad648d --- /dev/null +++ b/packages/Tethering/tests/mts/src/android/tethering/mts/TetheringModuleTest.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.tethering.mts; + +import static android.Manifest.permission.MANAGE_TEST_NETWORKS; +import static android.Manifest.permission.NETWORK_SETTINGS; +import static android.Manifest.permission.READ_DEVICE_CONFIG; +import static android.Manifest.permission.TETHER_PRIVILEGED; +import static android.Manifest.permission.WRITE_SETTINGS; +import static android.net.cts.util.CtsTetheringUtils.isWifiTetheringSupported; +import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY; + +import static com.android.testutils.TestNetworkTrackerKt.initTestNetwork; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import android.app.UiAutomation; +import android.content.Context; +import android.net.IpPrefix; +import android.net.LinkAddress; +import android.net.TetheringManager; +import android.net.cts.util.CtsTetheringUtils; +import android.net.cts.util.CtsTetheringUtils.TestTetheringEventCallback; +import android.provider.DeviceConfig; + +import androidx.annotation.NonNull; +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import com.android.testutils.TestNetworkTracker; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.InterfaceAddress; +import java.net.NetworkInterface; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@RunWith(AndroidJUnit4.class) +public class TetheringModuleTest { + private Context mContext; + private TetheringManager mTm; + private CtsTetheringUtils mCtsTetheringUtils; + + private UiAutomation mUiAutomation = + InstrumentationRegistry.getInstrumentation().getUiAutomation(); + + @Before + public void setUp() throws Exception { + mUiAutomation.adoptShellPermissionIdentity(MANAGE_TEST_NETWORKS, NETWORK_SETTINGS, + WRITE_SETTINGS, READ_DEVICE_CONFIG, TETHER_PRIVILEGED); + mContext = InstrumentationRegistry.getContext(); + mTm = mContext.getSystemService(TetheringManager.class); + mCtsTetheringUtils = new CtsTetheringUtils(mContext); + } + + @After + public void tearDown() throws Exception { + mUiAutomation.dropShellPermissionIdentity(); + } + + private static final String TETHER_ENABLE_SELECT_ALL_PREFIX_RANGES = + "tether_enable_select_all_prefix_ranges"; + @Test + public void testSwitchBasePrefixRangeWhenConflict() throws Exception { + assumeTrue(isFeatureEnabled(TETHER_ENABLE_SELECT_ALL_PREFIX_RANGES, true)); + + addressConflictTest(true); + } + + @Test + public void testSwitchPrefixRangeWhenConflict() throws Exception { + addressConflictTest(false); + } + + private void addressConflictTest(final boolean wholeRangeConflict) throws Exception { + final TestTetheringEventCallback tetherEventCallback = + mCtsTetheringUtils.registerTetheringEventCallback(); + + TestNetworkTracker tnt = null; + try { + tetherEventCallback.assumeTetheringSupported(); + assumeTrue(isWifiTetheringSupported(tetherEventCallback)); + + mCtsTetheringUtils.startWifiTethering(tetherEventCallback); + + final List<String> tetheredIfaces = tetherEventCallback.getTetheredInterfaces(); + assertEquals(1, tetheredIfaces.size()); + final String wifiTetheringIface = tetheredIfaces.get(0); + + NetworkInterface nif = NetworkInterface.getByName(wifiTetheringIface); + // Tethering downstream only have one ipv4 address. + final LinkAddress hotspotAddr = getFirstIpv4Address(nif); + assertNotNull(hotspotAddr); + + final IpPrefix testPrefix = getConflictingPrefix(hotspotAddr, wholeRangeConflict); + assertNotNull(testPrefix); + + tnt = setUpTestNetwork( + new LinkAddress(testPrefix.getAddress(), testPrefix.getPrefixLength())); + + tetherEventCallback.expectTetheredInterfacesChanged(null); + final List<String> wifiRegexs = + tetherEventCallback.getTetheringInterfaceRegexps().getTetherableWifiRegexs(); + + tetherEventCallback.expectTetheredInterfacesChanged(wifiRegexs); + nif = NetworkInterface.getByName(wifiTetheringIface); + final LinkAddress newHotspotAddr = getFirstIpv4Address(nif); + assertNotNull(newHotspotAddr); + + assertFalse(testPrefix.containsPrefix( + new IpPrefix(newHotspotAddr.getAddress(), newHotspotAddr.getPrefixLength()))); + + mCtsTetheringUtils.stopWifiTethering(tetherEventCallback); + } finally { + if (tnt != null) { + tnt.teardown(); + } + mTm.stopAllTethering(); + mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback); + } + } + + private LinkAddress getFirstIpv4Address(final NetworkInterface nif) { + for (InterfaceAddress ia : nif.getInterfaceAddresses()) { + final LinkAddress addr = new LinkAddress(ia.getAddress(), ia.getNetworkPrefixLength()); + if (addr.isIpv4()) return addr; + } + return null; + } + + @NonNull + private IpPrefix getConflictingPrefix(final LinkAddress address, + final boolean wholeRangeConflict) { + if (!wholeRangeConflict) { + return new IpPrefix(address.getAddress(), address.getPrefixLength()); + } + + final ArrayList<IpPrefix> prefixPool = new ArrayList<>(Arrays.asList( + new IpPrefix("192.168.0.0/16"), + new IpPrefix("172.16.0.0/12"), + new IpPrefix("10.0.0.0/8"))); + + for (IpPrefix prefix : prefixPool) { + if (prefix.contains(address.getAddress())) return prefix; + } + + fail("Could not find sutiable conflict prefix"); + + // Never go here. + return null; + } + + private TestNetworkTracker setUpTestNetwork(final LinkAddress address) throws Exception { + return initTestNetwork(mContext, address, 10_000L /* test timeout ms*/); + + } + + public static boolean isFeatureEnabled(final String name, final boolean defaultValue) { + return DeviceConfig.getBoolean(NAMESPACE_CONNECTIVITY, name, defaultValue); + } +} diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java index 8cb80bad809c..41d46e522ca4 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java @@ -99,9 +99,9 @@ public final class PrivateAddressCoordinatorTest { when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mConnectivityMgr); when(mConnectivityMgr.getAllNetworks()).thenReturn(mAllNetworks); when(mConfig.shouldEnableWifiP2pDedicatedIp()).thenReturn(false); + when(mConfig.isSelectAllPrefixRangeEnabled()).thenReturn(true); setUpIpServers(); - mPrivateAddressCoordinator = spy(new PrivateAddressCoordinator(mContext, mConfig, - mTetheringPrefixes)); + mPrivateAddressCoordinator = spy(new PrivateAddressCoordinator(mContext, mConfig)); } private LinkAddress requestDownstreamAddress(final IpServer ipServer, boolean useLastAddress) { diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java index dc0940cc0222..237e2c27bfa1 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java @@ -131,6 +131,7 @@ public class TetheringConfigurationTest { when(mResources.getBoolean(R.bool.config_tether_enable_legacy_wifi_p2p_dedicated_ip)) .thenReturn(false); initializeBpfOffloadConfiguration(true, null /* unset */); + initEnableSelectAllPrefixRangeFlag(null /* unset */); mHasTelephonyManager = true; mMockContext = new MockContext(mContext); @@ -428,4 +429,30 @@ public class TetheringConfigurationTest { mMockContext, mLog, INVALID_SUBSCRIPTION_ID); assertTrue(testCfg.shouldEnableWifiP2pDedicatedIp()); } + + private void initEnableSelectAllPrefixRangeFlag(final String value) { + doReturn(value).when( + () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY), + eq(TetheringConfiguration.TETHER_ENABLE_SELECT_ALL_PREFIX_RANGES))); + } + + @Test + public void testSelectAllPrefixRangeFlag() throws Exception { + // Test default value. + final TetheringConfiguration defaultCfg = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); + assertTrue(defaultCfg.isSelectAllPrefixRangeEnabled()); + + // Test disable flag. + initEnableSelectAllPrefixRangeFlag("false"); + final TetheringConfiguration testDisable = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); + assertFalse(testDisable.isSelectAllPrefixRangeEnabled()); + + // Test enable flag. + initEnableSelectAllPrefixRangeFlag("true"); + final TetheringConfiguration testEnable = new TetheringConfiguration( + mMockContext, mLog, INVALID_SUBSCRIPTION_ID); + assertTrue(testEnable.isSelectAllPrefixRangeEnabled()); + } } diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java index 993a37d6abe9..fed0a550e4f2 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java @@ -448,11 +448,7 @@ public class TetheringTest { @Override public PrivateAddressCoordinator getPrivateAddressCoordinator(Context ctx, TetheringConfiguration cfg) { - final ArrayList<IpPrefix> prefixPool = new ArrayList<>(Arrays.asList( - new IpPrefix("192.168.0.0/16"), - new IpPrefix("172.16.0.0/12"), - new IpPrefix("10.0.0.0/8"))); - mPrivateAddressCoordinator = spy(new PrivateAddressCoordinator(ctx, cfg, prefixPool)); + mPrivateAddressCoordinator = super.getPrivateAddressCoordinator(ctx, cfg); return mPrivateAddressCoordinator; } } |