From 259d5c08a8cdce305452d33fd49234e2c9b404b5 Mon Sep 17 00:00:00 2001 From: markchien Date: Thu, 6 Jan 2022 21:41:56 +0800 Subject: [PATCH] Make isTetheringSupported respect all tethering downstreams Currently if wifi, usb and bluetooth tethering is not supported, isTetheringSupported would return false. Then ethernet, ncm tethering and wifi p2p would also not be supported anymore. Make isTetheringSupported respect all tethering downstreams after T. Also remove redundant code: 1. tethering always has upstream configuration, checking whether has upstream configuration for isTetheringSupported is useless. 2. Remove TetheringDependencies#isTetheringSupported because it don't have any caller. Test: atest TetheringTests Change-Id: I3db5ce410c064d37c9e9e704fce2a2b68705834e --- .../networkstack/tethering/Tethering.java | 32 +++++++--- .../tethering/TetheringDependencies.java | 7 --- .../networkstack/tethering/TetheringTest.java | 62 +++++++++++++++++-- 3 files changed, 78 insertions(+), 23 deletions(-) diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java index 07fce08995..bb9b6fbeaa 100644 --- a/Tethering/src/com/android/networkstack/tethering/Tethering.java +++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -1533,16 +1533,28 @@ public class Tethering { return mConfig; } - boolean hasTetherableConfiguration() { - final TetheringConfiguration cfg = mConfig; - final boolean hasDownstreamConfiguration = - (cfg.tetherableUsbRegexs.length != 0) - || (cfg.tetherableWifiRegexs.length != 0) - || (cfg.tetherableBluetoothRegexs.length != 0); - final boolean hasUpstreamConfiguration = !cfg.preferredUpstreamIfaceTypes.isEmpty() - || cfg.chooseUpstreamAutomatically; + boolean hasAnySupportedDownstream() { + if ((mConfig.tetherableUsbRegexs.length != 0) + || (mConfig.tetherableWifiRegexs.length != 0) + || (mConfig.tetherableBluetoothRegexs.length != 0)) { + return true; + } - return hasDownstreamConfiguration && hasUpstreamConfiguration; + // Before T, isTetheringSupported would return true if wifi, usb and bluetooth tethering are + // disabled (whole tethering settings would be hidden). This means tethering would also not + // support wifi p2p, ethernet tethering and mirrorlink. This is wrong but probably there are + // some devices in the field rely on this to disable tethering entirely. + if (!SdkLevel.isAtLeastT()) return false; + + return (mConfig.tetherableWifiP2pRegexs.length != 0) + || (mConfig.tetherableNcmRegexs.length != 0) + || isEthernetSupported(); + } + + // TODO: using EtherentManager new API to check whether ethernet is supported when the API is + // ready to use. + private boolean isEthernetSupported() { + return mContext.getSystemService(Context.ETHERNET_SERVICE) != null; } void setUsbTethering(boolean enable, IIntResultListener listener) { @@ -2463,7 +2475,7 @@ public class Tethering { final boolean tetherEnabledInSettings = tetherSupported && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING); - return tetherEnabledInSettings && hasTetherableConfiguration() + return tetherEnabledInSettings && hasAnySupportedDownstream() && !isProvisioningNeededButUnavailable(); } diff --git a/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java b/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java index c1a747e673..9224213f0e 100644 --- a/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java +++ b/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java @@ -93,13 +93,6 @@ public abstract class TetheringDependencies { */ public abstract IpServer.Dependencies getIpServerDependencies(); - /** - * Indicates whether tethering is supported on the device. - */ - public boolean isTetheringSupported() { - return true; - } - /** * Get a reference to the EntitlementManager to be used by tethering. */ diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java index e4dbc7d83a..8acbb8ae8f 100644 --- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java +++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java @@ -297,6 +297,7 @@ public class TetheringTest { private TetheredInterfaceCallbackShim mTetheredInterfaceCallbackShim; private TestConnectivityManager mCm; + private boolean mForceEthernetServiceUnavailable = false; private class TestContext extends BroadcastInterceptingContext { TestContext(Context base) { @@ -331,7 +332,11 @@ public class TetheringTest { if (Context.USER_SERVICE.equals(name)) return mUserManager; if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; - if (Context.ETHERNET_SERVICE.equals(name)) return mEm; + if (Context.ETHERNET_SERVICE.equals(name)) { + if (mForceEthernetServiceUnavailable) return null; + + return mEm; + } return super.getSystemService(name); } @@ -451,11 +456,6 @@ public class TetheringTest { return mEntitleMgr; } - @Override - public boolean isTetheringSupported() { - return true; - } - @Override public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log, int subId) { @@ -680,6 +680,7 @@ public class TetheringTest { .thenReturn(new String[] {TEST_BT_REGEX}); when(mResources.getStringArray(R.array.config_tether_ncm_regexs)) .thenReturn(new String[] {TEST_NCM_REGEX}); + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)).thenReturn(true); when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn( new int[] {TYPE_WIFI, TYPE_MOBILE_DUN}); when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true); @@ -2834,6 +2835,55 @@ public class TetheringTest { runDualStackUsbTethering(TEST_RNDIS_IFNAME); runStopUSBTethering(); } + + @Test + public void testTetheringSupported() throws Exception { + setTetheringSupported(true /* supported */); + updateConfigAndVerifySupported(true /* supported */); + + // Could disable tethering supported by settings. + Settings.Global.putInt(mContentResolver, Settings.Global.TETHER_SUPPORTED, 0); + updateConfigAndVerifySupported(false /* supported */); + + // Could disable tethering supported by user restriction. + setTetheringSupported(true /* supported */); + when(mUserManager.hasUserRestriction( + UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(true); + updateConfigAndVerifySupported(false /* supported */); + + // Tethering is supported if it has any supported downstream. + setTetheringSupported(true /* supported */); + when(mResources.getStringArray(R.array.config_tether_usb_regexs)) + .thenReturn(new String[0]); + updateConfigAndVerifySupported(true /* supported */); + when(mResources.getStringArray(R.array.config_tether_wifi_regexs)) + .thenReturn(new String[0]); + updateConfigAndVerifySupported(true /* supported */); + + + if (isAtLeastT()) { + when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs)) + .thenReturn(new String[0]); + updateConfigAndVerifySupported(true /* supported */); + when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs)) + .thenReturn(new String[0]); + updateConfigAndVerifySupported(true /* supported */); + when(mResources.getStringArray(R.array.config_tether_ncm_regexs)) + .thenReturn(new String[0]); + updateConfigAndVerifySupported(true /* supported */); + mForceEthernetServiceUnavailable = true; + updateConfigAndVerifySupported(false /* supported */); + } else { + when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs)) + .thenReturn(new String[0]); + updateConfigAndVerifySupported(false /* supported */); + } + } + + private void updateConfigAndVerifySupported(boolean supported) { + sendConfigurationChanged(); + assertEquals(supported, mTethering.isTetheringSupported()); + } // TODO: Test that a request for hotspot mode doesn't interfere with an // already operating tethering mode interface. }