Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf52a8ea authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Show restricted message in Wi-Fi hotspot settings" into tm-dev

parents e99683f0 e37a553e
Loading
Loading
Loading
Loading
+73 −29
Original line number Diff line number Diff line
@@ -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,15 +241,33 @@ 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);

    @VisibleForTesting
    static class SearchIndexProvider extends BaseSearchIndexProvider {

        private final WifiRestriction mWifiRestriction;

        SearchIndexProvider(int xmlRes) {
            super(xmlRes);
            mWifiRestriction = new WifiRestriction();
        }

        @VisibleForTesting
        SearchIndexProvider(int xmlRes, WifiRestriction wifiRestriction) {
            super(xmlRes);
            mWifiRestriction = wifiRestriction;
        }

        @Override
        public List<String> getNonIndexableKeys(Context context) {
            final List<String> keys = super.getNonIndexableKeys(context);

                    if (!TetherUtil.isTetherAvailable(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);
@@ -257,7 +288,20 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
                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 {
+118 −73
Original line number Diff line number Diff line
@@ -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 String[] WIFI_REGEXS = {"wifi_regexs"};

    private Context mContext;
    private WifiTetherSettings mWifiTetherSettings;
    private static final int XML_RES = R.xml.wifi_tether_settings;
    private static final String[] WIFI_REGEXS = {"wifi_regexs"};

    @Rule
    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
    @Spy
    Context mContext = ApplicationProvider.getApplicationContext();
    @Mock
    private WifiManager mWifiManager;
    @Mock
@@ -73,83 +77,57 @@ 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();
        mWifiTetherSettings = new WifiTetherSettings(mWifiRestriction);
    }

    @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);
    @Config(shadows = ShadowFragment.class)
    public void onStart_uiIsRestricted_removeAllPreferences() {
        spyWifiTetherSettings();

        mWifiTetherSettings.onStart();

        verify(mPreferenceScreen).removeAll();
    }

    @Test
    public void wifiTetherNonIndexableKeys_tetherNotAvailable_keysReturned() {
        // To let TetherUtil.isTetherAvailable return false, select one of the combinations
        setupIsTetherAvailable(false);
    @Config(shadows = ShadowFragment.class)
    public void onStart_hotspotNotAvailable_removeAllPreferences() {
        spyWifiTetherSettings();
        when(mWifiRestriction.isHotspotAvailable(mContext)).thenReturn(false);

        final List<String> niks =
                WifiTetherSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
        mWifiTetherSettings.onStart();

        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);
        verify(mPreferenceScreen).removeAll();
        verify(mEmptyTextView).setText(anyInt());
    }

    @Test
    public void createPreferenceControllers_notEmpty() {
    public void createPreferenceControllers_getPreferenceControllersNotEmpty() {
        assertThat(WifiTetherSettings.SEARCH_INDEX_DATA_PROVIDER.getPreferenceControllers(mContext))
                .isNotEmpty();
    }

    @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);

        settings.onStart();

        verify(screen).removeAll();
    }

    @Test
    public void createPreferenceControllers_hasAutoOffPreference() {
        assertThat(mWifiTetherSettings.createPreferenceControllers(mContext)
@@ -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);

        final List<String> keys = searchIndexProvider.getNonIndexableKeys(mContext);

        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);
    }

        // 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);
    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();

        // For RestrictedLockUtils.hasBaseUserRestriction
        when(mUserManager.hasBaseUserRestriction(
                UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.of(userId)))
                .thenReturn(!returnValue);
        mWifiTetherSettings.onCreate(Bundle.EMPTY);
    }
}