Update SharedPreference values based on tethering state
TetherEnabler need to update tethering state of each tethering interfaces to make sure other preferences that depends on these SharedPreferences be consistent with UI. Bug: 148968321 Test: TetherEnablerTest; CodeInspectionTest. Manully test, built and flashed to crosshatch device. Change-Id: Ie0be7748adf20e6fb0ff5489795b0ca0664b6323
This commit is contained in:
@@ -22,6 +22,9 @@ import static android.net.ConnectivityManager.TETHERING_WIFI;
|
|||||||
|
|
||||||
import static com.android.settings.AllInOneTetherSettings.DEDUP_POSTFIX;
|
import static com.android.settings.AllInOneTetherSettings.DEDUP_POSTFIX;
|
||||||
|
|
||||||
|
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothPan;
|
import android.bluetooth.BluetoothPan;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
@@ -45,6 +48,7 @@ import com.android.internal.annotations.VisibleForTesting;
|
|||||||
import com.android.settings.datausage.DataSaverBackend;
|
import com.android.settings.datausage.DataSaverBackend;
|
||||||
import com.android.settings.widget.SwitchWidgetController;
|
import com.android.settings.widget.SwitchWidgetController;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
@@ -78,6 +82,18 @@ public class TetherEnabler implements SwitchWidgetController.OnSwitchChangeListe
|
|||||||
private static final String TAG = "TetherEnabler";
|
private static final String TAG = "TetherEnabler";
|
||||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||||
|
|
||||||
|
|
||||||
|
@Retention(SOURCE)
|
||||||
|
@IntDef(
|
||||||
|
flag = true,
|
||||||
|
value = {TETHERING_OFF, TETHERING_WIFI_ON, TETHERING_USB_ON, TETHERING_BLUETOOTH_ON}
|
||||||
|
)
|
||||||
|
@interface TetheringState {}
|
||||||
|
private static final int TETHERING_OFF = 0;
|
||||||
|
private static final int TETHERING_WIFI_ON = 1;
|
||||||
|
private static final int TETHERING_USB_ON = 1 << 1;
|
||||||
|
private static final int TETHERING_BLUETOOTH_ON = 1 << 2;
|
||||||
|
|
||||||
public static final String SHARED_PREF = "tether_options";
|
public static final String SHARED_PREF = "tether_options";
|
||||||
|
|
||||||
// This KEY is used for a shared preference value, not for any displayed preferences.
|
// This KEY is used for a shared preference value, not for any displayed preferences.
|
||||||
@@ -155,14 +171,15 @@ public class TetherEnabler implements SwitchWidgetController.OnSwitchChangeListe
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void updateState(@Nullable String[] tethered) {
|
void updateState(@Nullable String[] tethered) {
|
||||||
boolean isTethering = tethered == null ? isTethering() : isTethering(tethered);
|
int tetherState = getTetheringState(tethered);
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "updateState: " + isTethering);
|
Log.d(TAG, "updateState: " + tetherState);
|
||||||
}
|
}
|
||||||
setSwitchCheckedInternal(isTethering);
|
setSwitchCheckedInternal(tetherState != TETHERING_OFF);
|
||||||
|
setSharedPreferencesInternal(tetherState);
|
||||||
mSwitchWidgetController.setEnabled(!mDataSaverEnabled);
|
mSwitchWidgetController.setEnabled(!mDataSaverEnabled);
|
||||||
if (mListener != null) {
|
if (mListener != null) {
|
||||||
mListener.onTetherStateUpdated(isTethering);
|
mListener.onTetherStateUpdated(tetherState != TETHERING_OFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,32 +189,54 @@ public class TetherEnabler implements SwitchWidgetController.OnSwitchChangeListe
|
|||||||
mSwitchWidgetController.startListening();
|
mSwitchWidgetController.startListening();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTethering() {
|
private void setSharedPreferencesInternal(@TetheringState int tetherState) {
|
||||||
String[] tethered = mConnectivityManager.getTetheredIfaces();
|
if (tetherState == TETHERING_OFF) {
|
||||||
return isTethering(tethered);
|
// We don't override user's preferences when tethering off.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mSharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
|
||||||
|
final SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||||
|
editor.putBoolean(KEY_ENABLE_WIFI_TETHERING, (tetherState & TETHERING_WIFI_ON) != 0);
|
||||||
|
editor.putBoolean(USB_TETHER_KEY, (tetherState & TETHERING_USB_ON) != 0);
|
||||||
|
editor.putBoolean(BLUETOOTH_TETHER_KEY, (tetherState & TETHERING_BLUETOOTH_ON) != 0);
|
||||||
|
editor.commit();
|
||||||
|
mSharedPreferences.registerOnSharedPreferenceChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTethering(String[] tethered) {
|
private @TetheringState int getTetheringState(@Nullable String[] tethered) {
|
||||||
if (tethered != null && tethered.length != 0) {
|
int tetherState = TETHERING_OFF;
|
||||||
return true;
|
if (tethered == null) {
|
||||||
|
tethered = mConnectivityManager.getTetheredIfaces();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED) {
|
if (mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED) {
|
||||||
return true;
|
tetherState |= TETHERING_WIFI_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
final BluetoothPan pan = mBluetoothPan.get();
|
final BluetoothPan pan = mBluetoothPan.get();
|
||||||
|
if (pan != null && pan.isTetheringOn()) {
|
||||||
|
tetherState |= TETHERING_BLUETOOTH_ON;
|
||||||
|
}
|
||||||
|
|
||||||
return pan != null && pan.isTetheringOn();
|
String[] usbRegexs = mConnectivityManager.getTetherableUsbRegexs();
|
||||||
|
for (String s : tethered) {
|
||||||
|
for (String regex : usbRegexs) {
|
||||||
|
if (s.matches(regex)) {
|
||||||
|
return tetherState | TETHERING_USB_ON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tetherState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onSwitchToggled(boolean isChecked) {
|
public boolean onSwitchToggled(boolean isChecked) {
|
||||||
if (isChecked && !isTethering()) {
|
if (isChecked && getTetheringState(null /* tethered */) == TETHERING_OFF) {
|
||||||
startTether();
|
startTether();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isChecked && isTethering()) {
|
if (!isChecked && getTetheringState(null /* tethered */) != TETHERING_OFF) {
|
||||||
stopTether();
|
stopTether();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@@ -69,6 +69,7 @@ public class TetherEnablerTest {
|
|||||||
private SwitchBar mSwitchBar;
|
private SwitchBar mSwitchBar;
|
||||||
private TetherEnabler mEnabler;
|
private TetherEnabler mEnabler;
|
||||||
private SwitchWidgetController mSwitchWidgetController;
|
private SwitchWidgetController mSwitchWidgetController;
|
||||||
|
private static final String[] USB_TETHERED = {"usb"};
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -84,9 +85,13 @@ public class TetherEnablerTest {
|
|||||||
when(context.getSystemService(Context.NETWORK_POLICY_SERVICE)).thenReturn(
|
when(context.getSystemService(Context.NETWORK_POLICY_SERVICE)).thenReturn(
|
||||||
mNetworkPolicyManager);
|
mNetworkPolicyManager);
|
||||||
when(mConnectivityManager.getTetherableIfaces()).thenReturn(new String[0]);
|
when(mConnectivityManager.getTetherableIfaces()).thenReturn(new String[0]);
|
||||||
|
when(mConnectivityManager.getTetheredIfaces()).thenReturn(new String[0]);
|
||||||
|
when(mConnectivityManager.getTetherableUsbRegexs()).thenReturn(new String[0]);
|
||||||
panReference.set(mBluetoothPan);
|
panReference.set(mBluetoothPan);
|
||||||
when(context.getSharedPreferences(TetherEnabler.SHARED_PREF, Context.MODE_PRIVATE))
|
when(context.getSharedPreferences(TetherEnabler.SHARED_PREF, Context.MODE_PRIVATE))
|
||||||
.thenReturn(mSharedPreferences);
|
.thenReturn(mSharedPreferences);
|
||||||
|
SharedPreferences.Editor editor = mock(SharedPreferences.Editor.class);
|
||||||
|
when(mSharedPreferences.edit()).thenReturn(editor);
|
||||||
mEnabler = spy(new TetherEnabler(context, mSwitchWidgetController, panReference));
|
mEnabler = spy(new TetherEnabler(context, mSwitchWidgetController, panReference));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +108,8 @@ public class TetherEnablerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void lifecycle_onStart_setCheckedCorrectly() {
|
public void lifecycle_onStart_setCheckedCorrectly() {
|
||||||
when(mConnectivityManager.getTetheredIfaces()).thenReturn(new String[]{""});
|
when(mConnectivityManager.getTetheredIfaces()).thenReturn(USB_TETHERED);
|
||||||
|
when(mConnectivityManager.getTetherableUsbRegexs()).thenReturn(USB_TETHERED);
|
||||||
|
|
||||||
mEnabler.onStart();
|
mEnabler.onStart();
|
||||||
assertThat(mSwitchBar.isChecked()).isTrue();
|
assertThat(mSwitchBar.isChecked()).isTrue();
|
||||||
@@ -211,4 +217,28 @@ public class TetherEnablerTest {
|
|||||||
mEnabler.updateState(new String[]{""});
|
mEnabler.updateState(new String[]{""});
|
||||||
verify(mSwitchBar).setEnabled(true);
|
verify(mSwitchBar).setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateState_onSharedPreferencesChangeNeverCalled() {
|
||||||
|
mSharedPreferences.registerOnSharedPreferenceChangeListener(mEnabler);
|
||||||
|
mSwitchWidgetController.setListener(mEnabler);
|
||||||
|
mSwitchWidgetController.startListening();
|
||||||
|
|
||||||
|
mEnabler.updateState(null /* tethered */);
|
||||||
|
verify(mEnabler, never()).onSharedPreferenceChanged(eq(mSharedPreferences), any());
|
||||||
|
verify(mEnabler, never()).onSharedPreferenceChanged(eq(mSharedPreferences), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateState_setSharedPreferencesOnlyWhenNeeded() {
|
||||||
|
mSwitchWidgetController.setListener(mEnabler);
|
||||||
|
mSwitchWidgetController.startListening();
|
||||||
|
|
||||||
|
mEnabler.updateState(null /* tethered */);
|
||||||
|
verify(mSharedPreferences, never()).edit();
|
||||||
|
|
||||||
|
when(mConnectivityManager.getTetherableUsbRegexs()).thenReturn(USB_TETHERED);
|
||||||
|
mSharedPreferences.registerOnSharedPreferenceChangeListener(mEnabler);
|
||||||
|
mEnabler.updateState(USB_TETHERED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user