Show restricted message in Wi-Fi hotspot settings

- Remove Wi-Fi hotspot preferences in settings search if Wi-Fi hotspot is disallowed

- See the result screenshot in b/203168953#comment12

Bug: 203168953
Test: manual test
make RunSettingsRoboTests ROBOTEST_FILTER=WifiTetherSettingsTest

Change-Id: Id4416fd0659b596e4e6f31890a139198219f4552
This commit is contained in:
Weng Su
2022-05-03 02:31:39 +08:00
parent 27aa5f9d94
commit e37a553e94
2 changed files with 198 additions and 109 deletions

View File

@@ -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<String> getNonIndexableKeys(Context context) {
final List<String> 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<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null /* listener */);
}
};
@Override
public List<String> getNonIndexableKeys(Context context) {
final List<String> 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<AbstractPreferenceController> 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 {

View File

@@ -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<String> 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<String> 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<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
when(mUserManager.getUserRestrictionSources(
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.of(userId)))
.thenReturn(enforcingUsers);
final List<String> 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<String> 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<String> 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<String> 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);
}
}