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

Commit ec966cb7 authored by Zhen Zhang's avatar Zhen Zhang
Browse files

Add tether preferences into AllInOneTetherSettings

These preferences are for user to toggle a specific tethering option,
like USB, BT or WIFI.

Bug: 147323306
Test: CodeInspectionTest, AllInOneTetherSettingsTest, TetherEnablerTest
Change-Id: I1229ffd2dd12b39e9c6e48dc29c6e46ce9ad7634
parent 5610db5a
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -53,6 +53,31 @@
            android:title="@string/wifi_hotspot_ap_band_title"/>
    </PreferenceCategory>

    <PreferenceCategory
        android:key="tethering_options_group"
        android:title="Tethering"
        settings:searchable="false">
        <SwitchPreference
            android:key="enable_usb_tethering"
            android:title="@string/usb_tethering_button_text"
            android:summary="@string/usb_tethering_subtext"
            settings:controller="com.android.settings.network.UsbTetherPreferenceController"
            settings:keywords="@string/keywords_hotspot_tethering" />

        <SwitchPreference
            android:key="enable_bluetooth_tethering_2"
            android:title="@string/bluetooth_tether_checkbox_text"
            android:summary="@string/bluetooth_tethering_subtext"
            settings:controller="com.android.settings.network.BluetoothTetherPreferenceController"
            settings:keywords="@string/keywords_hotspot_tethering" />

        <SwitchPreference
            android:key="disable_wifi_tethering"
            android:title="Don't use Wi-Fi hotspot"
            settings:controller="com.android.settings.network.WifiTetherDisablePreferenceController"
            settings:keywords="@string/keywords_hotspot_tethering" />
    </PreferenceCategory>

    <Preference
        android:key="disabled_on_data_saver_2"
        android:summary="@string/tether_settings_disabled_on_data_saver"
+14 −13
Original line number Diff line number Diff line
@@ -120,24 +120,25 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment
        public void onReceive(Context content, Intent intent) {
            String action = intent.getAction();
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "updating display config due to receiving broadcast action " + action);
                Log.d(TAG,
                        "updating display config due to receiving broadcast action " + action);
            }
            updateDisplayWithNewConfig();
            if (TextUtils.equals(action, ACTION_TETHER_STATE_CHANGED)) {
                if (mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_DISABLED
                        && mRestartWifiApAfterConfigChange) {
                    mRestartWifiApAfterConfigChange = false;
                    mTetherEnabler.startTethering(TETHERING_WIFI);
                }
                restartWifiTetherIfNeed(mWifiManager.getWifiApState());
            } else if (TextUtils.equals(action, WIFI_AP_STATE_CHANGED_ACTION)) {
                int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE, 0);
                restartWifiTetherIfNeed(intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE, 0));
            }
        }

        private void restartWifiTetherIfNeed(int state) {
            if (state == WifiManager.WIFI_AP_STATE_DISABLED
                    && mWifiTetherChosen
                    && mRestartWifiApAfterConfigChange) {
                mRestartWifiApAfterConfigChange = false;
                mTetherEnabler.startTethering(TETHERING_WIFI);
            }
        }
        }
    };

    private final BluetoothProfile.ServiceListener mProfileServiceListener =
@@ -418,7 +419,7 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment
                @Override
                public List<AbstractPreferenceController> createPreferenceControllers(
                        Context context) {
                    return buildPreferenceControllers(context, null /* AllTetherSettings */);
                    return buildPreferenceControllers(context, null /*listener*/);
                }
            };
}
+23 −15
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import static android.net.ConnectivityManager.TETHERING_BLUETOOTH;
import static android.net.ConnectivityManager.TETHERING_USB;
import static android.net.ConnectivityManager.TETHERING_WIFI;

import static com.android.settings.AllInOneTetherSettings.DEDUP_POSTFIX;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothPan;
import android.content.BroadcastReceiver;
@@ -34,6 +36,7 @@ import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
@@ -50,9 +53,11 @@ import java.util.concurrent.atomic.AtomicReference;
 * TetherEnabler is a helper to manage Tethering switch on/off state. It turns on/off
 * different types of tethering based on stored values in {@link SharedPreferences} and ensures
 * tethering state updated by data saver state.
 *
 * This class is not designed for extending. It's extendable solely for the test purpose.
 */

public final class TetherEnabler implements SwitchWidgetController.OnSwitchChangeListener,
public class TetherEnabler implements SwitchWidgetController.OnSwitchChangeListener,
        DataSaverBackend.Listener, LifecycleObserver,
        SharedPreferences.OnSharedPreferenceChangeListener {

@@ -63,12 +68,9 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang

    // This KEY is used for a shared preference value, not for any displayed preferences.
    public static final String KEY_ENABLE_WIFI_TETHERING = "enable_wifi_tethering";
    @VisibleForTesting
    static final String WIFI_TETHER_DISABLE_KEY = "disable_wifi_tethering";
    @VisibleForTesting
    static final String USB_TETHER_KEY = "enable_usb_tethering";
    @VisibleForTesting
    static final String BLUETOOTH_TETHER_KEY = "enable_bluetooth_tethering";
    public static final String WIFI_TETHER_DISABLE_KEY = "disable_wifi_tethering";
    public static final String USB_TETHER_KEY = "enable_usb_tethering";
    public static final String BLUETOOTH_TETHER_KEY = "enable_bluetooth_tethering" + DEDUP_POSTFIX;

    private final SwitchWidgetController mSwitchWidgetController;
    private final WifiManager mWifiManager;
@@ -113,7 +115,7 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang
        mContext.registerReceiver(mTetherChangeReceiver, filter);

        mOnStartTetheringCallback = new OnStartTetheringCallback(this);
        updateState();
        updateState(null/*tethered*/);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
@@ -133,14 +135,20 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang
        mContext.unregisterReceiver(mTetherChangeReceiver);
    }

    private void updateState() {
        mSwitchWidgetController.setChecked(isTethering());
    @VisibleForTesting
    void updateState(@Nullable String[] tethered) {
        boolean isTethering = tethered == null ? isTethering() : isTethering(tethered);
        if (DEBUG) {
            Log.d(TAG, "updateState: " + isTethering);
        }
        setSwitchCheckedInternal(isTethering);
        mSwitchWidgetController.setEnabled(!mDataSaverEnabled);
    }

    private void updateState(String[] tethered) {
        mSwitchWidgetController.setChecked(isTethering(tethered));
        mSwitchWidgetController.setEnabled(!mDataSaverEnabled);
    private void setSwitchCheckedInternal(boolean checked) {
        mSwitchWidgetController.stopListening();
        mSwitchWidgetController.setChecked(checked);
        mSwitchWidgetController.startListening();
    }

    private boolean isTethering() {
@@ -269,7 +277,7 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang
                if (active != null) {
                    updateState(active.toArray(new String[0]));
                } else {
                    updateState();
                    updateState(null/*tethered*/);
                }
            }
        }
@@ -371,7 +379,7 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang
        private void update() {
            TetherEnabler enabler = mTetherEnabler.get();
            if (enabler != null) {
                enabler.updateState();
                enabler.updateState(null/*tethered*/);
            }
        }
    }
+3 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import androidx.preference.SwitchPreference;

import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.TetherUtil;

/**
 * This controller helps to manage the switch state and visibility of wifi tether disable switch
@@ -84,7 +85,8 @@ public final class WifiTetherDisablePreferenceController extends BasePreferenceC
    @Override
    public int getAvailabilityStatus() {
        final String[] wifiRegexs = mCm.getTetherableWifiRegexs();
        if (wifiRegexs == null || wifiRegexs.length == 0 || !shouldShow()) {
        if (wifiRegexs == null || wifiRegexs.length == 0 || !shouldShow()
                || !TetherUtil.isTetherAvailable(mContext)) {
            return CONDITIONALLY_UNAVAILABLE;
        } else {
            return AVAILABLE;
+48 −15
Original line number Diff line number Diff line
@@ -16,9 +16,14 @@

package com.android.settings;

import static com.android.settings.network.TetherEnabler.BLUETOOTH_TETHER_KEY;
import static com.android.settings.network.TetherEnabler.USB_TETHER_KEY;
import static com.android.settings.network.TetherEnabler.WIFI_TETHER_DISABLE_KEY;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

@@ -31,6 +36,7 @@ import android.util.FeatureFlagUtils;
import com.android.settings.core.FeatureFlags;
import com.android.settings.testutils.shadow.ShadowWifiManager;
import com.android.settings.wifi.tether.WifiTetherAutoOffPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;

import org.junit.Before;
import org.junit.Test;
@@ -40,6 +46,7 @@ import org.mockito.MockitoAnnotations;
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;
@@ -48,6 +55,8 @@ import java.util.List;
@Config(shadows = {ShadowWifiManager.class})
public class AllInOneTetherSettingsTest {
    private static final String[] WIFI_REGEXS = {"wifi_regexs"};
    private static final String[] USB_REGEXS = {"usb_regexs"};
    private static final String[] BT_REGEXS = {"bt_regexs"};

    private Context mContext;
    private AllInOneTetherSettings mAllInOneTetherSettings;
@@ -65,33 +74,54 @@ public class AllInOneTetherSettingsTest {
        doReturn(mConnectivityManager)
                .when(mContext).getSystemService(Context.CONNECTIVITY_SERVICE);
        doReturn(WIFI_REGEXS).when(mConnectivityManager).getTetherableWifiRegexs();
        doReturn(USB_REGEXS).when(mConnectivityManager).getTetherableUsbRegexs();
        doReturn(BT_REGEXS).when(mConnectivityManager).getTetherableBluetoothRegexs();
        doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE);
        // Assume the feature is enabled for most test cases.
        FeatureFlagUtils.setEnabled(mContext, FeatureFlags.TETHER_ALL_IN_ONE, true);

        mAllInOneTetherSettings = new AllInOneTetherSettings();
        ReflectionHelpers.setField(mAllInOneTetherSettings, "mLifecycle", mock(Lifecycle.class));
    }

    @Test
    public void getNonIndexableKeys_tetherAvailable_keysNotReturned() {
    public void getNonIndexableKeys_tetherAvailable_featureEnabled_keysReturnedCorrectly() {
        // To let TetherUtil.isTetherAvailable return true, select one of the combinations
        setupIsTetherAvailable(true);

        FeatureFlagUtils.setEnabled(mContext, FeatureFlags.TETHER_ALL_IN_ONE, true);
        final List<String> niks =
                AllInOneTetherSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);

        if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.TETHER_ALL_IN_ONE)) {
        assertThat(niks).doesNotContain(AllInOneTetherSettings.KEY_WIFI_TETHER_NETWORK_NAME);
        assertThat(niks).doesNotContain(
                AllInOneTetherSettings.KEY_WIFI_TETHER_NETWORK_PASSWORD);
        assertThat(niks).doesNotContain(AllInOneTetherSettings.KEY_WIFI_TETHER_AUTO_OFF);
        assertThat(niks).doesNotContain(AllInOneTetherSettings.KEY_WIFI_TETHER_NETWORK_AP_BAND);
        assertThat(niks).doesNotContain(AllInOneTetherSettings.KEY_WIFI_TETHER_SECURITY);
        } else {
        assertThat(niks).doesNotContain(BLUETOOTH_TETHER_KEY);
        assertThat(niks).doesNotContain(USB_TETHER_KEY);

        // This key should be returned because it's not visible by default.
        assertThat(niks).contains(WIFI_TETHER_DISABLE_KEY);
    }

    @Test
    public void getNonIndexableKeys_tetherAvailable_featureDisabled_keysReturned() {
        setupIsTetherAvailable(true);
        FeatureFlagUtils.setEnabled(mContext, FeatureFlags.TETHER_ALL_IN_ONE, false);

        final List<String> niks =
                AllInOneTetherSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);

        assertThat(niks).contains(AllInOneTetherSettings.KEY_WIFI_TETHER_NETWORK_NAME);
        assertThat(niks).contains(AllInOneTetherSettings.KEY_WIFI_TETHER_NETWORK_PASSWORD);
        assertThat(niks).contains(AllInOneTetherSettings.KEY_WIFI_TETHER_AUTO_OFF);
        assertThat(niks).contains(AllInOneTetherSettings.KEY_WIFI_TETHER_NETWORK_AP_BAND);
        assertThat(niks).contains(AllInOneTetherSettings.KEY_WIFI_TETHER_SECURITY);
        }
        assertThat(niks).contains(WIFI_TETHER_DISABLE_KEY);
        assertThat(niks).contains(BLUETOOTH_TETHER_KEY);
        assertThat(niks).contains(USB_TETHER_KEY);
    }

    @Test
@@ -107,6 +137,9 @@ public class AllInOneTetherSettingsTest {
        assertThat(niks).contains(AllInOneTetherSettings.KEY_WIFI_TETHER_AUTO_OFF);
        assertThat(niks).contains(AllInOneTetherSettings.KEY_WIFI_TETHER_NETWORK_AP_BAND);
        assertThat(niks).contains(AllInOneTetherSettings.KEY_WIFI_TETHER_SECURITY);
        assertThat(niks).contains(WIFI_TETHER_DISABLE_KEY);
        assertThat(niks).doesNotContain(BLUETOOTH_TETHER_KEY);
        assertThat(niks).doesNotContain(USB_TETHER_KEY);
    }

    @Test
Loading