diff --git a/src/com/android/settings/wifi/tether/WifiTetherSettings.java b/src/com/android/settings/wifi/tether/WifiTetherSettings.java index 93d267b74a1..aea7078f144 100644 --- a/src/com/android/settings/wifi/tether/WifiTetherSettings.java +++ b/src/com/android/settings/wifi/tether/WifiTetherSettings.java @@ -30,6 +30,7 @@ import android.os.UserManager; import android.util.FeatureFlagUtils; import android.util.Log; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.settings.R; @@ -41,6 +42,7 @@ import com.android.settings.widget.SettingsMainSwitchBar; import com.android.settingslib.TetherUtil; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.search.SearchIndexable; +import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils; import java.util.ArrayList; import java.util.List; @@ -56,6 +58,8 @@ public class WifiTetherSettings extends RestrictedDashboardFragment @VisibleForTesting static final String KEY_WIFI_TETHER_NETWORK_NAME = "wifi_tether_network_name"; @VisibleForTesting + static final String KEY_WIFI_TETHER_SECURITY = "wifi_tether_security"; + @VisibleForTesting static final String KEY_WIFI_TETHER_NETWORK_PASSWORD = "wifi_tether_network_password"; @VisibleForTesting static final String KEY_WIFI_TETHER_AUTO_OFF = "wifi_tether_auto_turn_off"; @@ -72,7 +76,7 @@ public class WifiTetherSettings extends RestrictedDashboardFragment private WifiManager mWifiManager; private boolean mRestartWifiApAfterConfigChange; private boolean mUnavailable; - + private WifiRestriction mWifiRestriction; @VisibleForTesting TetherChangeReceiver mTetherChangeReceiver; @@ -82,6 +86,12 @@ public class WifiTetherSettings extends RestrictedDashboardFragment public WifiTetherSettings() { super(UserManager.DISALLOW_CONFIG_TETHERING); + mWifiRestriction = new WifiRestriction(); + } + + public WifiTetherSettings(WifiRestriction wifiRestriction) { + super(UserManager.DISALLOW_CONFIG_TETHERING); + mWifiRestriction = wifiRestriction; } @Override @@ -98,9 +108,7 @@ public class WifiTetherSettings extends RestrictedDashboardFragment public void onCreate(Bundle icicle) { super.onCreate(icicle); setIfOnlyAvailableForAdmins(true); - if (isUiRestricted()) { - mUnavailable = true; - } + mUnavailable = isUiRestricted() || !mWifiRestriction.isHotspotAvailable(getContext()); } @Override @@ -135,6 +143,11 @@ public class WifiTetherSettings extends RestrictedDashboardFragment @Override public void onStart() { super.onStart(); + if (!mWifiRestriction.isHotspotAvailable(getContext())) { + getEmptyTextView().setText(R.string.not_allowed_by_ent); + getPreferenceScreen().removeAll(); + return; + } if (mUnavailable) { if (!isUiRestrictedByOnlyAdmin()) { getEmptyTextView().setText(R.string.tethering_settings_not_available); @@ -228,36 +241,67 @@ public class WifiTetherSettings extends RestrictedDashboardFragment use(WifiTetherMaximizeCompatibilityPreferenceController.class).updateDisplay(); } - public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.wifi_tether_settings) { + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new SearchIndexProvider(R.xml.wifi_tether_settings); - @Override - public List getNonIndexableKeys(Context context) { - final List keys = super.getNonIndexableKeys(context); + @VisibleForTesting + static class SearchIndexProvider extends BaseSearchIndexProvider { - if (!TetherUtil.isTetherAvailable(context)) { - keys.add(KEY_WIFI_TETHER_NETWORK_NAME); - keys.add(KEY_WIFI_TETHER_NETWORK_PASSWORD); - keys.add(KEY_WIFI_TETHER_AUTO_OFF); - keys.add(KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY); - } + private final WifiRestriction mWifiRestriction; - // Remove duplicate - keys.add(KEY_WIFI_TETHER_SCREEN); - return keys; - } + SearchIndexProvider(int xmlRes) { + super(xmlRes); + mWifiRestriction = new WifiRestriction(); + } - @Override - protected boolean isPageSearchEnabled(Context context) { - return !FeatureFlagUtils.isEnabled(context, FeatureFlags.TETHER_ALL_IN_ONE); - } + @VisibleForTesting + SearchIndexProvider(int xmlRes, WifiRestriction wifiRestriction) { + super(xmlRes); + mWifiRestriction = wifiRestriction; + } - @Override - public List createPreferenceControllers( - Context context) { - return buildPreferenceControllers(context, null /* listener */); - } - }; + @Override + public List getNonIndexableKeys(Context context) { + final List keys = super.getNonIndexableKeys(context); + + if (!mWifiRestriction.isTetherAvailable(context) + || !mWifiRestriction.isHotspotAvailable(context)) { + keys.add(KEY_WIFI_TETHER_NETWORK_NAME); + keys.add(KEY_WIFI_TETHER_SECURITY); + keys.add(KEY_WIFI_TETHER_NETWORK_PASSWORD); + keys.add(KEY_WIFI_TETHER_AUTO_OFF); + keys.add(KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY); + } + + // Remove duplicate + keys.add(KEY_WIFI_TETHER_SCREEN); + return keys; + } + + @Override + protected boolean isPageSearchEnabled(Context context) { + return !FeatureFlagUtils.isEnabled(context, FeatureFlags.TETHER_ALL_IN_ONE); + } + + @Override + public List createPreferenceControllers( + Context context) { + return buildPreferenceControllers(context, null /* listener */); + } + } + + @VisibleForTesting + static class WifiRestriction { + public boolean isTetherAvailable(@Nullable Context context) { + if (context == null) return true; + return TetherUtil.isTetherAvailable(context); + } + + public boolean isHotspotAvailable(@Nullable Context context) { + if (context == null) return true; + return WifiEnterpriseRestrictionUtils.isWifiTetheringAllowed(context); + } + } @VisibleForTesting class TetherChangeReceiver extends BroadcastReceiver { 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 e0cd780950d..d19bc909555 100644 --- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java @@ -19,6 +19,7 @@ package com.android.settings.wifi.tether; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -33,38 +34,41 @@ import android.net.ConnectivityManager; import android.net.TetheringManager; import android.net.wifi.WifiManager; import android.os.Bundle; -import android.os.UserHandle; import android.os.UserManager; -import android.util.FeatureFlagUtils; import android.widget.TextView; import androidx.fragment.app.FragmentActivity; import androidx.preference.PreferenceScreen; +import androidx.test.core.app.ApplicationProvider; -import com.android.settings.core.FeatureFlags; +import com.android.settings.R; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowFragment; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; -import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) public class WifiTetherSettingsTest { + + private static final int XML_RES = R.xml.wifi_tether_settings; private static final String[] WIFI_REGEXS = {"wifi_regexs"}; - private Context mContext; - private WifiTetherSettings mWifiTetherSettings; - + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Spy + Context mContext = ApplicationProvider.getApplicationContext(); @Mock private WifiManager mWifiManager; @Mock @@ -73,81 +77,55 @@ public class WifiTetherSettingsTest { private UserManager mUserManager; @Mock private TetheringManager mTetheringManager; + @Mock + private WifiTetherSettings.WifiRestriction mWifiRestriction; + @Mock + private PreferenceScreen mPreferenceScreen; + @Mock + private TextView mEmptyTextView; + + private WifiTetherSettings mWifiTetherSettings; @Before public void setUp() { - mContext = spy(RuntimeEnvironment.application); - - MockitoAnnotations.initMocks(this); doReturn(mWifiManager).when(mContext).getSystemService(WifiManager.class); doReturn(mConnectivityManager) .when(mContext).getSystemService(Context.CONNECTIVITY_SERVICE); doReturn(mTetheringManager).when(mContext).getSystemService(Context.TETHERING_SERVICE); doReturn(WIFI_REGEXS).when(mTetheringManager).getTetherableWifiRegexs(); doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE); + when(mWifiRestriction.isTetherAvailable(mContext)).thenReturn(true); + when(mWifiRestriction.isHotspotAvailable(mContext)).thenReturn(true); - mWifiTetherSettings = new WifiTetherSettings(); - } - - @Test - public void wifiTetherNonIndexableKeys_tetherAvailable_keysNotReturned() { - FeatureFlagUtils.setEnabled(mContext, FeatureFlags.TETHER_ALL_IN_ONE, false); - // To let TetherUtil.isTetherAvailable return true, select one of the combinations - setupIsTetherAvailable(true); - - final List niks = - WifiTetherSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); - - assertThat(niks).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_NAME); - assertThat(niks).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_PASSWORD); - assertThat(niks).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_AUTO_OFF); - assertThat(niks).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY); - } - - @Test - public void wifiTetherNonIndexableKeys_tetherNotAvailable_keysReturned() { - // To let TetherUtil.isTetherAvailable return false, select one of the combinations - setupIsTetherAvailable(false); - - final List niks = - WifiTetherSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); - - assertThat(niks).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_NAME); - assertThat(niks).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_PASSWORD); - assertThat(niks).contains(WifiTetherSettings.KEY_WIFI_TETHER_AUTO_OFF); - assertThat(niks).contains(WifiTetherSettings.KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY); - } - - @Test - public void createPreferenceControllers_notEmpty() { - assertThat(WifiTetherSettings.SEARCH_INDEX_DATA_PROVIDER.getPreferenceControllers(mContext)) - .isNotEmpty(); + mWifiTetherSettings = new WifiTetherSettings(mWifiRestriction); } @Test @Config(shadows = ShadowFragment.class) - public void startFragment_notAdminUser_shouldRemoveAllPreferences() { - final WifiTetherSettings settings = spy(new WifiTetherSettings()); - final FragmentActivity activity = mock(FragmentActivity.class); - when(settings.getActivity()).thenReturn(activity); - when(settings.getContext()).thenReturn(mContext); - final Resources.Theme theme = mContext.getTheme(); - when(activity.getTheme()).thenReturn(theme); - when(activity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); - doNothing().when(settings) - .onCreatePreferences(any(Bundle.class), nullable(String.class)); - final FakeFeatureFactory fakeFeatureFactory = FakeFeatureFactory.setupForTest(); - ReflectionHelpers.setField(settings, "mDashboardFeatureProvider", - fakeFeatureFactory.dashboardFeatureProvider); - final TextView emptyTextView = mock(TextView.class); - ReflectionHelpers.setField(settings, "mEmptyTextView", emptyTextView); - final PreferenceScreen screen = mock(PreferenceScreen.class); - doReturn(screen).when(settings).getPreferenceScreen(); - settings.onCreate(Bundle.EMPTY); + public void onStart_uiIsRestricted_removeAllPreferences() { + spyWifiTetherSettings(); - settings.onStart(); + mWifiTetherSettings.onStart(); - verify(screen).removeAll(); + verify(mPreferenceScreen).removeAll(); + } + + @Test + @Config(shadows = ShadowFragment.class) + public void onStart_hotspotNotAvailable_removeAllPreferences() { + spyWifiTetherSettings(); + when(mWifiRestriction.isHotspotAvailable(mContext)).thenReturn(false); + + mWifiTetherSettings.onStart(); + + verify(mPreferenceScreen).removeAll(); + verify(mEmptyTextView).setText(anyInt()); + } + + @Test + public void createPreferenceControllers_getPreferenceControllersNotEmpty() { + assertThat(WifiTetherSettings.SEARCH_INDEX_DATA_PROVIDER.getPreferenceControllers(mContext)) + .isNotEmpty(); } @Test @@ -159,19 +137,86 @@ public class WifiTetherSettingsTest { .isEqualTo(1); } - private void setupIsTetherAvailable(boolean returnValue) { - when(mConnectivityManager.isTetheringSupported()).thenReturn(true); + @Test + public void getNonIndexableKeys_tetherAvailable_keysNotReturned() { + when(mWifiRestriction.isTetherAvailable(mContext)).thenReturn(true); + when(mWifiRestriction.isHotspotAvailable(mContext)).thenReturn(true); + WifiTetherSettings.SearchIndexProvider searchIndexProvider = + new WifiTetherSettings.SearchIndexProvider(XML_RES, mWifiRestriction); - // For RestrictedLockUtils.checkIfRestrictionEnforced - final int userId = UserHandle.myUserId(); - List enforcingUsers = new ArrayList<>(); - when(mUserManager.getUserRestrictionSources( - UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.of(userId))) - .thenReturn(enforcingUsers); + final List keys = searchIndexProvider.getNonIndexableKeys(mContext); - // For RestrictedLockUtils.hasBaseUserRestriction - when(mUserManager.hasBaseUserRestriction( - UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.of(userId))) - .thenReturn(!returnValue); + assertThat(keys).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_NAME); + assertThat(keys).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_SECURITY); + assertThat(keys).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_PASSWORD); + assertThat(keys).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_AUTO_OFF); + assertThat(keys).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY); + } + + @Test + public void getNonIndexableKeys_tetherNotAvailable_keysReturned() { + when(mWifiRestriction.isTetherAvailable(mContext)).thenReturn(false); + when(mWifiRestriction.isHotspotAvailable(mContext)).thenReturn(true); + WifiTetherSettings.SearchIndexProvider searchIndexProvider = + new WifiTetherSettings.SearchIndexProvider(XML_RES, mWifiRestriction); + + final List keys = searchIndexProvider.getNonIndexableKeys(mContext); + + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_NAME); + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_SECURITY); + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_PASSWORD); + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_AUTO_OFF); + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY); + } + + @Test + public void getNonIndexableKeys_hotspotNotAvailable_keysReturned() { + when(mWifiRestriction.isTetherAvailable(mContext)).thenReturn(true); + when(mWifiRestriction.isHotspotAvailable(mContext)).thenReturn(false); + WifiTetherSettings.SearchIndexProvider searchIndexProvider = + new WifiTetherSettings.SearchIndexProvider(XML_RES, mWifiRestriction); + + final List keys = searchIndexProvider.getNonIndexableKeys(mContext); + + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_NAME); + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_SECURITY); + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_PASSWORD); + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_AUTO_OFF); + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY); + } + + @Test + public void getNonIndexableKeys_tetherAndHotspotNotAvailable_keysReturned() { + when(mWifiRestriction.isTetherAvailable(mContext)).thenReturn(false); + when(mWifiRestriction.isHotspotAvailable(mContext)).thenReturn(false); + WifiTetherSettings.SearchIndexProvider searchIndexProvider = + new WifiTetherSettings.SearchIndexProvider(XML_RES, mWifiRestriction); + + final List keys = searchIndexProvider.getNonIndexableKeys(mContext); + + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_NAME); + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_SECURITY); + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_PASSWORD); + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_AUTO_OFF); + assertThat(keys).contains(WifiTetherSettings.KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY); + } + + private void spyWifiTetherSettings() { + mWifiTetherSettings = spy(new WifiTetherSettings(mWifiRestriction)); + final FragmentActivity activity = mock(FragmentActivity.class); + when(mWifiTetherSettings.getActivity()).thenReturn(activity); + when(mWifiTetherSettings.getContext()).thenReturn(mContext); + final Resources.Theme theme = mContext.getTheme(); + when(activity.getTheme()).thenReturn(theme); + when(activity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); + doNothing().when(mWifiTetherSettings) + .onCreatePreferences(any(Bundle.class), nullable(String.class)); + final FakeFeatureFactory fakeFeatureFactory = FakeFeatureFactory.setupForTest(); + ReflectionHelpers.setField(mWifiTetherSettings, "mDashboardFeatureProvider", + fakeFeatureFactory.dashboardFeatureProvider); + ReflectionHelpers.setField(mWifiTetherSettings, "mEmptyTextView", mEmptyTextView); + doReturn(mPreferenceScreen).when(mWifiTetherSettings).getPreferenceScreen(); + + mWifiTetherSettings.onCreate(Bundle.EMPTY); } }