From f9b5e046a8187fdaf65904aaf279f1fb548432d5 Mon Sep 17 00:00:00 2001 From: Weng Su Date: Tue, 18 Oct 2022 04:08:13 +0800 Subject: [PATCH] Add config for Wi-Fi Hotspot Settings hidden - Add config_show_wifi_hotspot_settings for Settings customization - Hide Wi-Fi Hotspot preference in Hotspot & tethering Settings - Don't launch Wi-Fi Hotspot Settings (e.g long press on Hotspot in QS-tile) Bug: 213426762 Test: manual test atest -c com.android.settings.wifi.WifiUtilsTest make RunSettingsRoboTests ROBOTEST_FILTER=WifiTetherPreferenceControllerTest make RunSettingsRoboTests ROBOTEST_FILTER=WifiTetherSettingsTest Merged-In: I11f88d0d15d6d5c2766b64b5847ac31ed0f34c25 Change-Id: I11f88d0d15d6d5c2766b64b5847ac31ed0f34c25 (cherry picked from commit 160b5078ed600231da2889d468fc9de08dc2e640) --- res/values/config.xml | 3 + src/com/android/settings/wifi/WifiUtils.java | 68 +++++++++++++++ .../WifiTetherPreferenceController.java | 15 +--- .../wifi/tether/WifiTetherSettings.java | 9 ++ .../WifiTetherPreferenceControllerTest.java | 24 +++--- .../wifi/tether/WifiTetherSettingsTest.java | 26 ++++++ .../android/settings/wifi/WifiUtilsTest.java | 83 +++++++++++++++++++ 7 files changed, 204 insertions(+), 24 deletions(-) diff --git a/res/values/config.xml b/res/values/config.xml index ab7305f4e34..93d82a8c6f3 100755 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -331,6 +331,9 @@ surface in search results or not.--> true + + true + true diff --git a/src/com/android/settings/wifi/WifiUtils.java b/src/com/android/settings/wifi/WifiUtils.java index 4b94c81fda0..a9010acc68c 100644 --- a/src/com/android/settings/wifi/WifiUtils.java +++ b/src/com/android/settings/wifi/WifiUtils.java @@ -22,14 +22,20 @@ import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; import android.net.NetworkCapabilities; +import android.net.TetheringManager; import android.net.wifi.ScanResult; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiManager; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.text.TextUtils; +import android.util.Log; +import androidx.annotation.VisibleForTesting; + +import com.android.settings.R; import com.android.settings.Utils; import com.android.wifitrackerlib.WifiEntry; @@ -38,12 +44,16 @@ import java.nio.charset.StandardCharsets; /** A utility class for Wi-Fi functions. */ public class WifiUtils extends com.android.settingslib.wifi.WifiUtils { + static final String TAG = "WifiUtils"; + private static final int SSID_ASCII_MIN_LENGTH = 1; private static final int SSID_ASCII_MAX_LENGTH = 32; private static final int PSK_PASSPHRASE_ASCII_MIN_LENGTH = 8; private static final int PSK_PASSPHRASE_ASCII_MAX_LENGTH = 63; + private static Boolean sCanShowWifiHotspotCached; + public static boolean isSSIDTooLong(String ssid) { if (TextUtils.isEmpty(ssid)) { return false; @@ -240,4 +250,62 @@ public class WifiUtils extends com.android.settingslib.wifi.WifiUtils { return WifiEntry.SECURITY_NONE; } + + /** + * Check if Wi-Fi hotspot settings can be displayed. + * + * @param context Context of caller + * @return true if Wi-Fi hotspot settings can be displayed + */ + public static boolean checkShowWifiHotspot(Context context) { + if (context == null) return false; + + boolean showWifiHotspotSettings = + context.getResources().getBoolean(R.bool.config_show_wifi_hotspot_settings); + if (!showWifiHotspotSettings) { + Log.w(TAG, "config_show_wifi_hotspot_settings:false"); + return false; + } + + WifiManager wifiManager = context.getSystemService(WifiManager.class); + if (wifiManager == null) { + Log.e(TAG, "WifiManager is null"); + return false; + } + + TetheringManager tetheringManager = context.getSystemService(TetheringManager.class); + if (tetheringManager == null) { + Log.e(TAG, "TetheringManager is null"); + return false; + } + String[] wifiRegexs = tetheringManager.getTetherableWifiRegexs(); + if (wifiRegexs == null || wifiRegexs.length == 0) { + Log.w(TAG, "TetherableWifiRegexs is empty"); + return false; + } + return true; + } + + /** + * Return the cached result to see if Wi-Fi hotspot settings can be displayed. + * + * @param context Context of caller + * @return true if Wi-Fi hotspot settings can be displayed + */ + public static boolean canShowWifiHotspot(Context context) { + if (sCanShowWifiHotspotCached == null) { + sCanShowWifiHotspotCached = checkShowWifiHotspot(context); + } + return sCanShowWifiHotspotCached; + } + + /** + * Sets the sCanShowWifiHotspotCached for testing purposes. + * + * @param cached Cached value for #canShowWifiHotspot() + */ + @VisibleForTesting + public static void setCanShowWifiHotspotCached(Boolean cached) { + sCanShowWifiHotspotCached = cached; + } } diff --git a/src/com/android/settings/wifi/tether/WifiTetherPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherPreferenceController.java index 73ff31d4e47..a9c35594e33 100644 --- a/src/com/android/settings/wifi/tether/WifiTetherPreferenceController.java +++ b/src/com/android/settings/wifi/tether/WifiTetherPreferenceController.java @@ -16,9 +16,10 @@ package com.android.settings.wifi.tether; +import static com.android.settings.wifi.WifiUtils.canShowWifiHotspot; + import android.annotation.NonNull; import android.content.Context; -import android.net.TetheringManager; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiClient; import android.net.wifi.WifiManager; @@ -46,7 +47,6 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController private static final String WIFI_TETHER_SETTINGS = "wifi_tether"; - private boolean mIsWifiTetherable; private WifiManager mWifiManager; private boolean mIsWifiTetheringAllow; private int mSoftApState; @@ -57,8 +57,7 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController public WifiTetherPreferenceController(Context context, Lifecycle lifecycle) { this(context, lifecycle, - context.getSystemService(WifiManager.class), - context.getSystemService(TetheringManager.class), + context.getApplicationContext().getSystemService(WifiManager.class), true /* initSoftApManager */, WifiEnterpriseRestrictionUtils.isWifiTetheringAllowed(context)); } @@ -68,15 +67,9 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController Context context, Lifecycle lifecycle, WifiManager wifiManager, - TetheringManager tetheringManager, boolean initSoftApManager, boolean isWifiTetheringAllow) { super(context); - final String[] wifiRegexs = tetheringManager.getTetherableWifiRegexs(); - if (wifiRegexs != null && wifiRegexs.length != 0) { - mIsWifiTetherable = true; - } - mIsWifiTetheringAllow = isWifiTetheringAllow; if (!isWifiTetheringAllow) return; @@ -92,7 +85,7 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController @Override public boolean isAvailable() { - return mIsWifiTetherable && !Utils.isMonkeyRunning(); + return canShowWifiHotspot(mContext) && !Utils.isMonkeyRunning(); } @Override diff --git a/src/com/android/settings/wifi/tether/WifiTetherSettings.java b/src/com/android/settings/wifi/tether/WifiTetherSettings.java index e6b4bd6e67a..1ff77463460 100644 --- a/src/com/android/settings/wifi/tether/WifiTetherSettings.java +++ b/src/com/android/settings/wifi/tether/WifiTetherSettings.java @@ -18,6 +18,8 @@ package com.android.settings.wifi.tether; import static android.net.wifi.WifiManager.WIFI_AP_STATE_CHANGED_ACTION; +import static com.android.settings.wifi.WifiUtils.canShowWifiHotspot; + import android.app.settings.SettingsEnums; import android.content.BroadcastReceiver; import android.content.Context; @@ -107,6 +109,13 @@ public class WifiTetherSettings extends RestrictedDashboardFragment @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); + if (!canShowWifiHotspot(getContext())) { + Log.e(TAG, "can not launch Wi-Fi hotspot settings" + + " because the config is not set to show."); + finish(); + return; + } + setIfOnlyAvailableForAdmins(true); mUnavailable = isUiRestricted() || !mWifiRestriction.isHotspotAvailable(getContext()); } diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java index e8ee7c3b90e..bc6053b428d 100644 --- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java @@ -16,13 +16,14 @@ package com.android.settings.wifi.tether; +import static com.android.settings.wifi.WifiUtils.setCanShowWifiHotspotCached; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; import android.content.Context; -import android.net.TetheringManager; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiManager; @@ -62,8 +63,6 @@ public class WifiTetherPreferenceControllerTest { @Mock private Lifecycle mLifecycle; @Mock - private TetheringManager mTetheringManager; - @Mock private WifiManager mWifiManager; @Mock private PreferenceScreen mScreen; @@ -74,38 +73,37 @@ public class WifiTetherPreferenceControllerTest { @Before public void setUp() { + setCanShowWifiHotspotCached(true); FakeFeatureFactory.setupForTest(); mPreference = new PrimarySwitchPreference(mContext); - when(mContext.getSystemService(Context.TETHERING_SERVICE)).thenReturn(mTetheringManager); when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager); when(mScreen.findPreference(anyString())).thenReturn(mPreference); mSoftApConfiguration = new SoftApConfiguration.Builder().setSsid(SSID).build(); when(mWifiManager.getSoftApConfiguration()).thenReturn(mSoftApConfiguration); - when(mTetheringManager.getTetherableWifiRegexs()).thenReturn(new String[]{"1", "2"}); mController = new WifiTetherPreferenceController(mContext, mLifecycle, mWifiManager, - mTetheringManager, false /* initSoftApManager */, true /* isWifiTetheringAllow */); + false /* initSoftApManager */, true /* isWifiTetheringAllow */); mController.displayPreference(mScreen); } @Test - public void isAvailable_noTetherRegex_shouldReturnFalse() { - when(mTetheringManager.getTetherableWifiRegexs()).thenReturn(new String[]{}); - mController = new WifiTetherPreferenceController(mContext, mLifecycle, mWifiManager, - mTetheringManager, false /* initSoftApManager */, true /* isWifiTetheringAllow */); + public void isAvailable_canNotShowWifiHotspot_shouldReturnFalse() { + setCanShowWifiHotspotCached(false); assertThat(mController.isAvailable()).isFalse(); } @Test - public void isAvailable_hasTetherRegex_shouldReturnTrue() { + public void isAvailable_canShowWifiHostspot_shouldReturnTrue() { + setCanShowWifiHotspotCached(true); + assertThat(mController.isAvailable()).isTrue(); } @Test public void displayPreference_wifiTetheringNotAllowed_shouldDisable() { mController = new WifiTetherPreferenceController(mContext, mLifecycle, mWifiManager, - mTetheringManager, false /* initSoftApManager */, false /* isWifiTetheringAllow */); + false /* initSoftApManager */, false /* isWifiTetheringAllow */); mController.displayPreference(mScreen); @@ -116,7 +114,7 @@ public class WifiTetherPreferenceControllerTest { @Test public void displayPreference_wifiTetheringAllowed_shouldEnable() { mController = new WifiTetherPreferenceController(mContext, mLifecycle, mWifiManager, - mTetheringManager, false /* initSoftApManager */, true /* isWifiTetheringAllow */); + false /* initSoftApManager */, true /* isWifiTetheringAllow */); mController.displayPreference(mScreen); diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java index d19bc909555..6d3b879188e 100644 --- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java @@ -16,6 +16,8 @@ package com.android.settings.wifi.tether; +import static com.android.settings.wifi.WifiUtils.setCanShowWifiHotspotCached; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -42,6 +44,7 @@ import androidx.preference.PreferenceScreen; import androidx.test.core.app.ApplicationProvider; import com.android.settings.R; +import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowFragment; @@ -55,6 +58,8 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; import org.robolectric.util.ReflectionHelpers; import java.util.List; @@ -88,6 +93,7 @@ public class WifiTetherSettingsTest { @Before public void setUp() { + setCanShowWifiHotspotCached(true); doReturn(mWifiManager).when(mContext).getSystemService(WifiManager.class); doReturn(mConnectivityManager) .when(mContext).getSystemService(Context.CONNECTIVITY_SERVICE); @@ -100,6 +106,17 @@ public class WifiTetherSettingsTest { mWifiTetherSettings = new WifiTetherSettings(mWifiRestriction); } + @Test + @Config(shadows = ShadowRestrictedDashboardFragment.class) + public void onCreate_canNotShowWifiHotspot_shouldFinish() { + setCanShowWifiHotspotCached(false); + mWifiTetherSettings = spy(new WifiTetherSettings(mWifiRestriction)); + + mWifiTetherSettings.onCreate(null); + + verify(mWifiTetherSettings).finish(); + } + @Test @Config(shadows = ShadowFragment.class) public void onStart_uiIsRestricted_removeAllPreferences() { @@ -219,4 +236,13 @@ public class WifiTetherSettingsTest { mWifiTetherSettings.onCreate(Bundle.EMPTY); } + + @Implements(RestrictedDashboardFragment.class) + public static final class ShadowRestrictedDashboardFragment { + + @Implementation + public void onCreate(Bundle icicle) { + // do nothing + } + } } diff --git a/tests/unit/src/com/android/settings/wifi/WifiUtilsTest.java b/tests/unit/src/com/android/settings/wifi/WifiUtilsTest.java index 1a5e8526dc3..282631026be 100644 --- a/tests/unit/src/com/android/settings/wifi/WifiUtilsTest.java +++ b/tests/unit/src/com/android/settings/wifi/WifiUtilsTest.java @@ -21,19 +21,53 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import android.content.Context; +import android.content.res.Resources; +import android.net.TetheringManager; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiManager; +import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.android.settings.R; import com.android.wifitrackerlib.WifiEntry; +import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; @RunWith(AndroidJUnit4.class) public class WifiUtilsTest { + static final String[] WIFI_REGEXS = {"wifi_regexs"}; + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Spy + Context mContext = ApplicationProvider.getApplicationContext(); + @Mock + Resources mResources; + @Mock + WifiManager mWifiManager; + @Mock + TetheringManager mTetheringManager; + + @Before + public void setUp() { + when(mContext.getResources()).thenReturn(mResources); + when(mResources.getBoolean(R.bool.config_show_wifi_hotspot_settings)).thenReturn(true); + when(mContext.getSystemService(WifiManager.class)).thenReturn(mWifiManager); + when(mContext.getSystemService(TetheringManager.class)).thenReturn(mTetheringManager); + when(mTetheringManager.getTetherableWifiRegexs()).thenReturn(WIFI_REGEXS); + } + @Test public void testSSID() { assertThat(WifiUtils.isSSIDTooLong("123")).isFalse(); @@ -108,4 +142,53 @@ public class WifiUtilsTest { WifiConfiguration config = WifiUtils.getWifiConfig(null /* wifiEntry */, null /* scanResult */); } + + @Test + public void checkShowWifiHotspot_allReady_returnTrue() { + assertThat(WifiUtils.checkShowWifiHotspot(mContext)).isTrue(); + } + + @Test + public void checkShowWifiHotspot_contextIsNull_returnFalse() { + assertThat(WifiUtils.checkShowWifiHotspot(null)).isFalse(); + } + + @Test + public void checkShowWifiHotspot_configIsNotShow_returnFalse() { + when(mResources.getBoolean(R.bool.config_show_wifi_hotspot_settings)).thenReturn(false); + + assertThat(WifiUtils.checkShowWifiHotspot(mContext)).isFalse(); + } + + @Test + public void checkShowWifiHotspot_wifiManagerIsNull_returnFalse() { + when(mContext.getSystemService(WifiManager.class)).thenReturn(null); + + assertThat(WifiUtils.checkShowWifiHotspot(mContext)).isFalse(); + } + + @Test + public void checkShowWifiHotspot_tetheringManagerIsNull_returnFalse() { + when(mContext.getSystemService(TetheringManager.class)).thenReturn(null); + + assertThat(WifiUtils.checkShowWifiHotspot(mContext)).isFalse(); + } + + @Test + public void checkShowWifiHotspot_wifiRegexsIsEmpty_returnFalse() { + when(mTetheringManager.getTetherableWifiRegexs()).thenReturn(null); + + assertThat(WifiUtils.checkShowWifiHotspot(mContext)).isFalse(); + } + + @Test + public void canShowWifiHotspot_cachedIsReady_returnCached() { + WifiUtils.setCanShowWifiHotspotCached(true); + + assertThat(WifiUtils.canShowWifiHotspot(null)).isTrue(); + + WifiUtils.setCanShowWifiHotspotCached(false); + + assertThat(WifiUtils.canShowWifiHotspot(null)).isFalse(); + } }