Make tether option preferences listen to own SharedPreferences change

The SharedPreferences value could be changed by other classes. This can
help make UI consistent with shared preferences value.

Bug: 148968321
Test: UsbTetherPreferenceControllerTest;
BluetoothTetherPreferenceControllerTest;
WifiTetherDisablePreferenceControllerTest;
CodeInspectionTest.

Change-Id: I11bdad2729e88c07ea1f046d9e95a6a63b398931
This commit is contained in:
Zhen Zhang
2020-02-26 12:54:20 -08:00
parent 4d59bce21b
commit 084875a104
5 changed files with 134 additions and 28 deletions

View File

@@ -42,7 +42,8 @@ import com.google.common.annotations.VisibleForTesting;
* preference. It stores preference value when preference changed. * preference. It stores preference value when preference changed.
*/ */
public final class BluetoothTetherPreferenceController extends BasePreferenceController public final class BluetoothTetherPreferenceController extends BasePreferenceController
implements LifecycleObserver, Preference.OnPreferenceChangeListener { implements LifecycleObserver, Preference.OnPreferenceChangeListener,
SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "BluetoothTetherPreferenceController"; private static final String TAG = "BluetoothTetherPreferenceController";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -65,6 +66,16 @@ public final class BluetoothTetherPreferenceController extends BasePreferenceCon
new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); 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) @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop() { public void onStop() {
mContext.unregisterReceiver(mBluetoothChangeReceiver); mContext.unregisterReceiver(mBluetoothChangeReceiver);
@@ -74,15 +85,15 @@ public final class BluetoothTetherPreferenceController extends BasePreferenceCon
public void displayPreference(PreferenceScreen screen) { public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen); super.displayPreference(screen);
mPreference = screen.findPreference(mPreferenceKey); mPreference = screen.findPreference(mPreferenceKey);
if (mPreference != null && mPreference instanceof SwitchPreference) {
((SwitchPreference) mPreference)
.setChecked(mSharedPreferences.getBoolean(mPreferenceKey, false));
}
} }
@Override @Override
public void updateState(Preference preference) { public void updateState(Preference preference) {
super.updateState(preference); super.updateState(preference);
if (preference == null) {
return;
}
switch (mBluetoothState) { switch (mBluetoothState) {
case BluetoothAdapter.STATE_ON: case BluetoothAdapter.STATE_ON:
case BluetoothAdapter.STATE_OFF: case BluetoothAdapter.STATE_OFF:
@@ -96,6 +107,11 @@ public final class BluetoothTetherPreferenceController extends BasePreferenceCon
default: default:
preference.setEnabled(false); preference.setEnabled(false);
} }
if (preference instanceof SwitchPreference) {
((SwitchPreference) preference)
.setChecked(mSharedPreferences.getBoolean(mPreferenceKey, false));
}
} }
@Override @Override
@@ -131,4 +147,11 @@ public final class BluetoothTetherPreferenceController extends BasePreferenceCon
editor.apply(); editor.apply();
return true; return true;
} }
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (TextUtils.equals(mPreferenceKey, key)) {
updateState(mPreference);
}
}
} }

View File

@@ -44,7 +44,8 @@ import com.android.settings.core.BasePreferenceController;
* *
*/ */
public final class UsbTetherPreferenceController extends BasePreferenceController implements public final class UsbTetherPreferenceController extends BasePreferenceController implements
LifecycleObserver, Preference.OnPreferenceChangeListener { LifecycleObserver, Preference.OnPreferenceChangeListener,
SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "UsbTetherPrefController"; private static final String TAG = "UsbTetherPrefController";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -71,6 +72,17 @@ public final class UsbTetherPreferenceController extends BasePreferenceControlle
mContext.registerReceiver(mUsbChangeReceiver, filter); mContext.registerReceiver(mUsbChangeReceiver, filter);
} }
@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) @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop() { public void onStop() {
mContext.unregisterReceiver(mUsbChangeReceiver); mContext.unregisterReceiver(mUsbChangeReceiver);
@@ -90,22 +102,20 @@ public final class UsbTetherPreferenceController extends BasePreferenceControlle
public void displayPreference(PreferenceScreen screen) { public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen); super.displayPreference(screen);
mPreference = screen.findPreference(mPreferenceKey); mPreference = screen.findPreference(mPreferenceKey);
if (mPreference != null && mPreference instanceof SwitchPreference) {
((SwitchPreference) mPreference)
.setChecked(mSharedPreferences.getBoolean(mPreferenceKey, false));
}
} }
@Override @Override
public void updateState(Preference preference) { public void updateState(Preference preference) {
super.updateState(preference); super.updateState(preference);
if (preference != null) { if (preference == null) {
if (mUsbConnected && !mMassStorageActive) { return;
preference.setEnabled(true);
} else {
preference.setEnabled(false);
} }
if (preference instanceof SwitchPreference) {
((SwitchPreference) preference)
.setChecked(mSharedPreferences.getBoolean(mPreferenceKey, false));
} }
preference.setEnabled(mUsbConnected && !mMassStorageActive);
} }
@VisibleForTesting @VisibleForTesting
@@ -134,4 +144,11 @@ public final class UsbTetherPreferenceController extends BasePreferenceControlle
editor.apply(); editor.apply();
return true; return true;
} }
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (TextUtils.equals(mPreferenceKey, key)) {
updateState(mPreference);
}
}
} }

View File

@@ -111,33 +111,45 @@ public final class WifiTetherDisablePreferenceController extends BasePreferenceC
super.displayPreference(screen); super.displayPreference(screen);
mScreen = screen; mScreen = screen;
mPreference = screen.findPreference(mPreferenceKey); mPreference = screen.findPreference(mPreferenceKey);
if (mPreference != null && mPreference instanceof SwitchPreference) { if (mPreference != null) {
((SwitchPreference) mPreference)
.setChecked(!mSharedPreferences.getBoolean(
TetherEnabler.KEY_ENABLE_WIFI_TETHERING, true));
mPreference.setOnPreferenceChangeListener(this); mPreference.setOnPreferenceChangeListener(this);
} }
updateState(mPreference);
} }
@Override @Override
public void updateState(Preference preference) { public void updateState(Preference preference) {
super.updateState(preference); super.updateState(preference);
if (preference instanceof SwitchPreference) {
((SwitchPreference) preference)
.setChecked(!mSharedPreferences.getBoolean(
TetherEnabler.KEY_ENABLE_WIFI_TETHERING, true));
}
setVisible(mScreen, mPreferenceKey, shouldShow()); setVisible(mScreen, mPreferenceKey, shouldShow());
} }
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) { String key) {
final boolean shouldShowBefore = shouldShow();
if (TextUtils.equals(TetherEnabler.KEY_ENABLE_WIFI_TETHERING, key) && shouldShowBefore) {
updateState(mPreference);
return;
}
boolean shouldUpdateState = false;
if (TextUtils.equals(TetherEnabler.USB_TETHER_KEY, key)) { if (TextUtils.equals(TetherEnabler.USB_TETHER_KEY, key)) {
mUSBTetherEnabled = sharedPreferences.getBoolean(key, false); mUSBTetherEnabled = sharedPreferences.getBoolean(key, false);
shouldUpdateState = true;
} else if (TextUtils.equals(TetherEnabler.BLUETOOTH_TETHER_KEY, key)) { } else if (TextUtils.equals(TetherEnabler.BLUETOOTH_TETHER_KEY, key)) {
mBluetoothTetherEnabled = sharedPreferences.getBoolean(key, false); mBluetoothTetherEnabled = sharedPreferences.getBoolean(key, false);
shouldUpdateState = true;
} }
// Check if we are hiding this preference. If so, make sure the preference is set to // Check if we are hiding this preference. If so, make sure the preference is set to
// unchecked to enable wifi tether. // unchecked to enable wifi tether.
if (mPreference != null && mPreference instanceof SwitchPreference && !shouldShow()) { if (mPreference != null && mPreference instanceof SwitchPreference
&& shouldShowBefore && !shouldShow()) {
final SwitchPreference switchPreference = (SwitchPreference) mPreference; final SwitchPreference switchPreference = (SwitchPreference) mPreference;
if (switchPreference.isChecked()) { if (switchPreference.isChecked()) {
if (DEBUG) { if (DEBUG) {
@@ -151,8 +163,10 @@ public final class WifiTetherDisablePreferenceController extends BasePreferenceC
} }
} }
if (shouldUpdateState) {
updateState(mPreference); updateState(mPreference);
} }
}
@Override @Override
public boolean onPreferenceChange(Preference preference, Object o) { public boolean onPreferenceChange(Preference preference, Object o) {

View File

@@ -27,8 +27,10 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import org.junit.Before; import org.junit.Before;
@@ -37,13 +39,17 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class BluetoothTetherPreferenceControllerTest { public class BluetoothTetherPreferenceControllerTest {
@Mock @Mock
private ConnectivityManager mConnectivityManager; private ConnectivityManager mConnectivityManager;
@Mock
private SharedPreferences mSharedPreferences;
private SwitchPreference mSwitchPreference;
private BluetoothTetherPreferenceController mController; private BluetoothTetherPreferenceController mController;
private Context mContext; private Context mContext;
@@ -52,10 +58,14 @@ public class BluetoothTetherPreferenceControllerTest {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mContext = spy(ApplicationProvider.getApplicationContext()); mContext = spy(ApplicationProvider.getApplicationContext());
mSwitchPreference = spy(SwitchPreference.class);
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn( when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(
mConnectivityManager); mConnectivityManager);
when(mContext.getSharedPreferences(TetherEnabler.SHARED_PREF, Context.MODE_PRIVATE))
.thenReturn(mSharedPreferences);
when(mConnectivityManager.getTetherableBluetoothRegexs()).thenReturn(new String[] {""}); when(mConnectivityManager.getTetherableBluetoothRegexs()).thenReturn(new String[] {""});
mController = new BluetoothTetherPreferenceController(mContext, BLUETOOTH_TETHER_KEY); mController = new BluetoothTetherPreferenceController(mContext, BLUETOOTH_TETHER_KEY);
ReflectionHelpers.setField(mController, "mPreference", mSwitchPreference);
} }
@Test @Test
@@ -84,4 +94,20 @@ public class BluetoothTetherPreferenceControllerTest {
when(mConnectivityManager.getTetherableBluetoothRegexs()).thenReturn(new String[0]); when(mConnectivityManager.getTetherableBluetoothRegexs()).thenReturn(new String[0]);
assertThat(mController.isAvailable()).isFalse(); assertThat(mController.isAvailable()).isFalse();
} }
@Test
public void switch_shouldCheckedWhenSharedPreferenceIsTrue() {
when(mSharedPreferences.getBoolean(BLUETOOTH_TETHER_KEY, false)).thenReturn(true);
mController.onSharedPreferenceChanged(mSharedPreferences, BLUETOOTH_TETHER_KEY);
verify(mSwitchPreference).setChecked(true);
}
@Test
public void switch_shouldUnCheckedWhenSharedPreferenceIsFalse() {
when(mSharedPreferences.getBoolean(BLUETOOTH_TETHER_KEY, false)).thenReturn(false);
mController.onSharedPreferenceChanged(mSharedPreferences, BLUETOOTH_TETHER_KEY);
verify(mSwitchPreference).setChecked(false);
}
} }

View File

@@ -27,8 +27,10 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import org.junit.Before; import org.junit.Before;
@@ -37,15 +39,19 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class UsbTetherPreferenceControllerTest { public class UsbTetherPreferenceControllerTest {
@Mock @Mock
private ConnectivityManager mConnectivityManager; private ConnectivityManager mConnectivityManager;
@Mock
private SharedPreferences mSharedPreferences;
private Context mContext; private Context mContext;
private UsbTetherPreferenceController mController; private UsbTetherPreferenceController mController;
private SwitchPreference mSwitchPreference;
@Before @Before
public void setUp() { public void setUp() {
@@ -55,7 +61,11 @@ public class UsbTetherPreferenceControllerTest {
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn( when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(
mConnectivityManager); mConnectivityManager);
when(mConnectivityManager.getTetherableUsbRegexs()).thenReturn(new String[]{""}); when(mConnectivityManager.getTetherableUsbRegexs()).thenReturn(new String[]{""});
when(mContext.getSharedPreferences(TetherEnabler.SHARED_PREF, Context.MODE_PRIVATE))
.thenReturn(mSharedPreferences);
mController = new UsbTetherPreferenceController(mContext, USB_TETHER_KEY); mController = new UsbTetherPreferenceController(mContext, USB_TETHER_KEY);
mSwitchPreference = spy(SwitchPreference.class);
ReflectionHelpers.setField(mController, "mPreference", mSwitchPreference);
} }
@Test @Test
@@ -81,4 +91,20 @@ public class UsbTetherPreferenceControllerTest {
when(mConnectivityManager.getTetherableUsbRegexs()).thenReturn(new String[0]); when(mConnectivityManager.getTetherableUsbRegexs()).thenReturn(new String[0]);
assertThat(mController.isAvailable()).isFalse(); assertThat(mController.isAvailable()).isFalse();
} }
@Test
public void switch_shouldCheckedWhenSharedPreferencesIsTrue() {
when(mSharedPreferences.getBoolean(USB_TETHER_KEY, false)).thenReturn(true);
mController.onSharedPreferenceChanged(mSharedPreferences, USB_TETHER_KEY);
verify(mSwitchPreference).setChecked(true);
}
@Test
public void switch_shouldUnCheckedWhenSharedPreferencesIsFalse() {
when(mSharedPreferences.getBoolean(USB_TETHER_KEY, false)).thenReturn(false);
mController.onSharedPreferenceChanged(mSharedPreferences, USB_TETHER_KEY);
verify(mSwitchPreference).setChecked(false);
}
} }