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

Commit 7f2d6ce0 authored by Zhen Zhang's avatar Zhen Zhang
Browse files

Refactor new tether settings to remove SharedPreferences

Bluetooth, USB and Wifi Disable tether preferences will turn on/off that
type of tethering interface instantly without storing it into
SharedPreferences. They are listening to TetherEnabler to update their
state.
Refactored to remove dependancy on SharedPreferences.

Bug: 151367756
Test: TetherEnablerTest; BluetoothTetherPreferenceControllerTest;
UsbTetherPreferenceControllerTest;
WifiTetherDisablePreferenceControllerTest; AllInOneSettingsTest;
AllInOneTetherPreferenceControllerTest

Change-Id: Ia6cc60bc4de8f08413beb6d41552a18f6fa6a55b
parent f5ff9289
Loading
Loading
Loading
Loading
+20 −23
Original line number Diff line number Diff line
@@ -20,8 +20,6 @@ import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
import static android.net.ConnectivityManager.TETHERING_WIFI;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_CHANGED_ACTION;

import static com.android.settings.network.TetherEnabler.KEY_ENABLE_WIFI_TETHERING;

import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothPan;
@@ -30,7 +28,6 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
@@ -74,8 +71,7 @@ import java.util.concurrent.atomic.AtomicReference;
@SearchIndexable
public class AllInOneTetherSettings extends RestrictedDashboardFragment
        implements DataSaverBackend.Listener,
        WifiTetherBasePreferenceController.OnTetherConfigUpdateListener,
        SharedPreferences.OnSharedPreferenceChangeListener {
        WifiTetherBasePreferenceController.OnTetherConfigUpdateListener {

    // TODO(b/148622133): Should clean up the postfix once this fragment replaced TetherSettings.
    public static final String DEDUP_POSTFIX = "_2";
@@ -114,9 +110,18 @@ public class AllInOneTetherSettings extends RestrictedDashboardFragment
    private WifiTetherApBandPreferenceController mApBandPreferenceController;
    private WifiTetherSecurityPreferenceController mSecurityPreferenceController;
    private PreferenceGroup mWifiTetherGroup;
    private SharedPreferences mSharedPreferences;
    private boolean mWifiTetherChosen;
    private boolean mBluetoothTethering;
    private boolean mUsbTethering;
    private boolean mWifiTethering;
    private TetherEnabler mTetherEnabler;
    private final TetherEnabler.OnTetherStateUpdateListener mStateUpdateListener =
            state -> {
                mBluetoothTethering = TetherEnabler.isBluetoothTethering(state);
                mUsbTethering = TetherEnabler.isUsbTethering(state);
                mWifiTethering = TetherEnabler.isWifiTethering(state);
                mWifiTetherGroup.setVisible(shouldShowWifiConfig());
                reConfigInitialExpandedChildCount();
            };

    private final BroadcastReceiver mTetherChangeReceiver = new BroadcastReceiver() {
        @Override
@@ -136,7 +141,6 @@ public class AllInOneTetherSettings extends RestrictedDashboardFragment

        private void restartWifiTetherIfNeed(int state) {
            if (state == WifiManager.WIFI_AP_STATE_DISABLED
                    && mWifiTetherChosen
                    && mRestartWifiApAfterConfigChange) {
                mRestartWifiApAfterConfigChange = false;
                mTetherEnabler.startTethering(TETHERING_WIFI);
@@ -168,8 +172,6 @@ public class AllInOneTetherSettings extends RestrictedDashboardFragment
    public void onAttach(Context context) {
        super.onAttach(context);
        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        mSharedPreferences =
                context.getSharedPreferences(TetherEnabler.SHARED_PREF, Context.MODE_PRIVATE);

        mSSIDPreferenceController = use(WifiTetherSSIDPreferenceController.class);
        mSecurityPreferenceController = use(WifiTetherSecurityPreferenceController.class);
@@ -199,9 +201,6 @@ public class AllInOneTetherSettings extends RestrictedDashboardFragment

        // Set initial state based on Data Saver mode.
        onDataSaverChanged(mDataSaverBackend.isDataSaverEnabled());

        // Set initial state based on SharedPreferences value.
        onSharedPreferenceChanged(mSharedPreferences, KEY_ENABLE_WIFI_TETHERING);
    }

    @Override
@@ -222,6 +221,9 @@ public class AllInOneTetherSettings extends RestrictedDashboardFragment
        mTetherEnabler = new TetherEnabler(activity,
                new SwitchBarController(switchBar), mBluetoothPan);
        getSettingsLifecycle().addObserver(mTetherEnabler);
        use(UsbTetherPreferenceController.class).setTetherEnabler(mTetherEnabler);
        use(BluetoothTetherPreferenceController.class).setTetherEnabler(mTetherEnabler);
        use(WifiTetherDisablePreferenceController.class).setTetherEnabler(mTetherEnabler);
        switchBar.show();
    }

@@ -247,13 +249,13 @@ public class AllInOneTetherSettings extends RestrictedDashboardFragment
    @Override
    public void onResume() {
        super.onResume();
        mSharedPreferences.registerOnSharedPreferenceChangeListener(this);
        mTetherEnabler.addListener(mStateUpdateListener);
    }

    @Override
    public void onPause() {
        super.onPause();
        mSharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
        mTetherEnabler.removeListener(mStateUpdateListener);
    }

    @Override
@@ -365,13 +367,8 @@ public class AllInOneTetherSettings extends RestrictedDashboardFragment
        mApBandPreferenceController.updateDisplay();
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (TextUtils.equals(key, KEY_ENABLE_WIFI_TETHERING)) {
            mWifiTetherChosen = sharedPreferences.getBoolean(KEY_ENABLE_WIFI_TETHERING, true);
            mWifiTetherGroup.setVisible(mWifiTetherChosen);
            reConfigInitialExpandedChildCount();
        }
    private boolean shouldShowWifiConfig() {
        return mWifiTethering || (!mBluetoothTethering && !mUsbTethering);
    }

    private void reConfigInitialExpandedChildCount() {
@@ -380,7 +377,7 @@ public class AllInOneTetherSettings extends RestrictedDashboardFragment

    @Override
    public int getInitialExpandedChildCount() {
        if (!mWifiTetherChosen) {
        if (!shouldShowWifiConfig()) {
            // Expand all preferences in the screen.
            return getPreferenceScreen().getPreferenceCount();
        }
+29 −34
Original line number Diff line number Diff line
@@ -17,16 +17,12 @@ package com.android.settings.network;

import static android.os.UserManager.DISALLOW_CONFIG_TETHERING;

import static com.android.settings.network.TetherEnabler.BLUETOOTH_TETHER_KEY;
import static com.android.settings.network.TetherEnabler.KEY_ENABLE_WIFI_TETHERING;
import static com.android.settings.network.TetherEnabler.USB_TETHER_KEY;
import static com.android.settingslib.RestrictedLockUtilsInternal.checkIfRestrictionEnforced;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.UserHandle;
import android.util.FeatureFlagUtils;
import android.util.Log;
@@ -56,19 +52,23 @@ public class AllInOneTetherPreferenceController extends BasePreferenceController
        LifecycleObserver, TetherEnabler.OnTetherStateUpdateListener {
    private static final String TAG = "AllInOneTetherPreferenceController";

    private static final byte HOTSPOT_ONLY = 1;
    private static final byte USB_ONLY = 1 << 1;
    private static final byte BLUETOOTH_ONLY = 1 << 2;
    private static final byte HOTSPOT_AND_USB = HOTSPOT_ONLY | USB_ONLY;
    private static final byte HOTSPOT_AND_BLUETOOTH = HOTSPOT_ONLY | BLUETOOTH_ONLY;
    private static final byte USB_AND_BLUETOOTH = USB_ONLY | BLUETOOTH_ONLY;
    private static final byte HOTSPOT_AND_USB_AND_BLUETOOTH =
            HOTSPOT_ONLY | USB_ONLY | BLUETOOTH_ONLY;
    private static final byte TETHERING_TYPE_HOTSPOT_ONLY = 1;
    private static final byte TETHERING_TYPE_USB_ONLY = 1 << 1;
    private static final byte TETHERING_TYPE_BLUETOOTH_ONLY = 1 << 2;
    private static final byte TETHERING_TYPE_HOTSPOT_AND_USB =
            TETHERING_TYPE_HOTSPOT_ONLY | TETHERING_TYPE_USB_ONLY;
    private static final byte TETHERING_TYPE_HOTSPOT_AND_BLUETOOTH =
            TETHERING_TYPE_HOTSPOT_ONLY | TETHERING_TYPE_BLUETOOTH_ONLY;
    private static final byte TETHERING_TYPE_USB_AND_BLUETOOTH =
            TETHERING_TYPE_USB_ONLY | TETHERING_TYPE_BLUETOOTH_ONLY;
    private static final byte TETHERING_TYPE_HOTSPOT_AND_USB_AND_BLUETOOTH =
            TETHERING_TYPE_HOTSPOT_ONLY | TETHERING_TYPE_USB_ONLY | TETHERING_TYPE_BLUETOOTH_ONLY;
    // A bitwise value that stands for the current tethering interface type.
    private int mTetheringType;

    private final boolean mAdminDisallowedTetherConfig;
    private final AtomicReference<BluetoothPan> mBluetoothPan;
    private final BluetoothAdapter mBluetoothAdapter;
    private final SharedPreferences mTetherEnablerSharedPreferences;
    @VisibleForTesting
    final BluetoothProfile.ServiceListener mBtProfileServiceListener =
            new BluetoothProfile.ServiceListener() {
@@ -92,7 +92,6 @@ public class AllInOneTetherPreferenceController extends BasePreferenceController
        mAdminDisallowedTetherConfig = false;
        mBluetoothPan = new AtomicReference<>();
        mBluetoothAdapter = null;
        mTetherEnablerSharedPreferences = null;
    }

    public AllInOneTetherPreferenceController(Context context, String key) {
@@ -101,8 +100,6 @@ public class AllInOneTetherPreferenceController extends BasePreferenceController
        mAdminDisallowedTetherConfig = checkIfRestrictionEnforced(
                context, DISALLOW_CONFIG_TETHERING, UserHandle.myUserId()) != null;
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        mTetherEnablerSharedPreferences =
                context.getSharedPreferences(TetherEnabler.SHARED_PREF, Context.MODE_PRIVATE);
    }

    @Override
@@ -128,29 +125,22 @@ public class AllInOneTetherPreferenceController extends BasePreferenceController
    @Override
    public CharSequence getSummary() {
        if (mPreference != null && mPreference.isChecked()) {
            int chosenType = 0;
            chosenType |= mTetherEnablerSharedPreferences
                .getBoolean(KEY_ENABLE_WIFI_TETHERING, true) ? HOTSPOT_ONLY : 0;
            chosenType |= mTetherEnablerSharedPreferences.getBoolean(USB_TETHER_KEY, false)
                ? USB_ONLY : 0;
            chosenType |= mTetherEnablerSharedPreferences.getBoolean(BLUETOOTH_TETHER_KEY, false)
                ? BLUETOOTH_ONLY : 0;
            switch (chosenType) {
                case HOTSPOT_ONLY:
            switch (mTetheringType) {
                case TETHERING_TYPE_HOTSPOT_ONLY:
                    return mContext.getString(R.string.tether_settings_summary_hotspot_only);
                case USB_ONLY:
                case TETHERING_TYPE_USB_ONLY:
                    return mContext.getString(R.string.tether_settings_summary_usb_tethering_only);
                case BLUETOOTH_ONLY:
                case TETHERING_TYPE_BLUETOOTH_ONLY:
                    return mContext.getString(
                            R.string.tether_settings_summary_bluetooth_tethering_only);
                case HOTSPOT_AND_USB:
                case TETHERING_TYPE_HOTSPOT_AND_USB:
                    return mContext.getString(R.string.tether_settings_summary_hotspot_and_usb);
                case HOTSPOT_AND_BLUETOOTH:
                case TETHERING_TYPE_HOTSPOT_AND_BLUETOOTH:
                    return mContext.getString(
                            R.string.tether_settings_summary_hotspot_and_bluetooth);
                case USB_AND_BLUETOOTH:
                case TETHERING_TYPE_USB_AND_BLUETOOTH:
                    return mContext.getString(R.string.tether_settings_summary_usb_and_bluetooth);
                case HOTSPOT_AND_USB_AND_BLUETOOTH:
                case TETHERING_TYPE_HOTSPOT_AND_USB_AND_BLUETOOTH:
                    return mContext.getString(
                            R.string.tether_settings_summary_hotspot_and_usb_and_bluetooth);
                default:
@@ -174,14 +164,14 @@ public class AllInOneTetherPreferenceController extends BasePreferenceController
    @OnLifecycleEvent(Event.ON_RESUME)
    public void onResume() {
        if (mTetherEnabler != null) {
            mTetherEnabler.setListener(this);
            mTetherEnabler.addListener(this);
        }
    }

    @OnLifecycleEvent(Event.ON_PAUSE)
    public void onPause() {
        if (mTetherEnabler != null) {
            mTetherEnabler.setListener(null);
            mTetherEnabler.removeListener(this);
        }
    }

@@ -206,7 +196,12 @@ public class AllInOneTetherPreferenceController extends BasePreferenceController
    }

    @Override
    public void onTetherStateUpdated(boolean isTethering) {
    public void onTetherStateUpdated(@TetherEnabler.TetheringState int state) {
        mTetheringType = 0;
        mTetheringType |= TetherEnabler.isBluetoothTethering(state) ? TETHERING_TYPE_BLUETOOTH_ONLY
                : 0;
        mTetheringType |= TetherEnabler.isWifiTethering(state) ? TETHERING_TYPE_HOTSPOT_ONLY : 0;
        mTetheringType |= TetherEnabler.isUsbTethering(state) ? TETHERING_TYPE_USB_ONLY : 0;
        updateState(mPreference);
    }
}
+21 −45
Original line number Diff line number Diff line
@@ -21,8 +21,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.TetheringManager;
import android.text.TextUtils;
import android.util.Log;

@@ -30,9 +29,6 @@ import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.settings.core.TogglePreferenceController;

import com.google.common.annotations.VisibleForTesting;

@@ -40,36 +36,33 @@ import com.google.common.annotations.VisibleForTesting;
 * This controller helps to manage the switch state and visibility of bluetooth tether switch
 * preference. It stores preference value when preference changed.
 */
public final class BluetoothTetherPreferenceController extends TogglePreferenceController
        implements LifecycleObserver, SharedPreferences.OnSharedPreferenceChangeListener {
public final class BluetoothTetherPreferenceController extends TetherBasePreferenceController
        implements LifecycleObserver {

    private static final String TAG = "BluetoothTetherPreferenceController";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    private final ConnectivityManager mCm;
    private int mBluetoothState;
    private Preference mPreference;
    private final SharedPreferences mSharedPreferences;
    private boolean mBluetoothTethering;

    public BluetoothTetherPreferenceController(Context context, String prefKey) {
        super(context, prefKey);
        mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        mSharedPreferences =
                context.getSharedPreferences(TetherEnabler.SHARED_PREF, Context.MODE_PRIVATE);
    public BluetoothTetherPreferenceController(Context context, String preferenceKey) {
        super(context, preferenceKey);
    }

    @Override
    public boolean isChecked() {
        return mSharedPreferences.getBoolean(mPreferenceKey, false);
        return mBluetoothTethering;
    }

    @Override
    public boolean setChecked(boolean isChecked) {
        if (DEBUG) {
            Log.d(TAG, "preference changing to " + isChecked);
        if (mTetherEnabler == null) {
            return false;
        }
        if (isChecked) {
            mTetherEnabler.startTethering(TetheringManager.TETHERING_BLUETOOTH);
        } else {
            mTetherEnabler.stopTethering(TetheringManager.TETHERING_BLUETOOTH);
        }
        final SharedPreferences.Editor editor = mSharedPreferences.edit();
        editor.putBoolean(mPreferenceKey, isChecked);
        editor.apply();
        return true;
    }

@@ -80,27 +73,11 @@ public final class BluetoothTetherPreferenceController extends TogglePreferenceC
                new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
        mSharedPreferences.registerOnSharedPreferenceChangeListener(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause() {
        mSharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onStop() {
        mContext.unregisterReceiver(mBluetoothChangeReceiver);
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mPreference = screen.findPreference(mPreferenceKey);
    }

    @Override
    public void updateState(Preference preference) {
        super.updateState(preference);
@@ -133,6 +110,12 @@ public final class BluetoothTetherPreferenceController extends TogglePreferenceC
        }
    }

    @Override
    public void onTetherStateUpdated(int state) {
        mBluetoothTethering = TetherEnabler.isBluetoothTethering(state);
        updateState(mPreference);
    }

    @VisibleForTesting
    final BroadcastReceiver mBluetoothChangeReceiver = new BroadcastReceiver() {
        @Override
@@ -144,11 +127,4 @@ public final class BluetoothTetherPreferenceController extends TogglePreferenceC
            }
        }
    };

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (TextUtils.equals(mPreferenceKey, key)) {
            updateState(mPreference);
        }
    }
}
+74 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.network;

import android.content.Context;
import android.net.ConnectivityManager;
import android.util.Log;

import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.settings.core.TogglePreferenceController;

public abstract class TetherBasePreferenceController extends TogglePreferenceController
        implements LifecycleObserver, TetherEnabler.OnTetherStateUpdateListener {

    private static final String TAG = "TetherBasePreferenceController";
    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    final ConnectivityManager mCm;

    TetherEnabler mTetherEnabler;
    Preference mPreference;

    public TetherBasePreferenceController(Context context, String preferenceKey) {
        super(context, preferenceKey);
        mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    }

    /**
     * Set TetherEnabler for the controller. Call this method to initialize the controller.
     * @param tetherEnabler The tetherEnabler to set for the controller.
     */
    public void setTetherEnabler(TetherEnabler tetherEnabler) {
        mTetherEnabler = tetherEnabler;
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
        // Must call setEnabler() before
        if (mTetherEnabler != null) {
            mTetherEnabler.addListener(this);
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause() {
        if (mTetherEnabler != null) {
            mTetherEnabler.removeListener(this);
        }
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        mPreference = screen.findPreference(mPreferenceKey);
    }
}
+82 −136

File changed.

Preview size limit exceeded, changes collapsed.

Loading