Fix unexpected Wi-Fi hotspot shutdown

- Filter out unnecessary onSwitchChanged callbacks when the switch is
  disabled, which should not be triggered by user input.

- Refine the state handling function to avoid unnecessary
  onSwitchChanged callback.

- Refine the error handling of isHotspotPasswordValid function.

Bug: 227719584
Test: manual test
make RunSettingsRoboTests \
  ROBOTEST_FILTER=WifiTetherSwitchBarControllerTest

Change-Id: If62aaadc8ddb214769b1367d7801b6125bb5377c
This commit is contained in:
Weng Su
2022-04-08 05:35:14 +08:00
parent e0f6939c4c
commit 6c42636cb8
3 changed files with 109 additions and 48 deletions

View File

@@ -17,6 +17,11 @@
package com.android.settings.wifi.tether;
import static android.net.ConnectivityManager.TETHERING_WIFI;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -51,7 +56,7 @@ public class WifiTetherSwitchBarController implements
private final WifiManager mWifiManager;
@VisibleForTesting
final DataSaverBackend mDataSaverBackend;
DataSaverBackend mDataSaverBackend;
@VisibleForTesting
final ConnectivityManager.OnStartTetheringCallback mOnStartTetheringCallback =
new ConnectivityManager.OnStartTetheringCallback() {
@@ -75,7 +80,7 @@ public class WifiTetherSwitchBarController implements
mConnectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
mSwitchBar.setChecked(mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED);
mSwitchBar.setChecked(mWifiManager.getWifiApState() == WIFI_AP_STATE_ENABLED);
updateWifiSwitch();
}
@@ -95,6 +100,9 @@ public class WifiTetherSwitchBarController implements
@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
// Filter out unnecessary callbacks when switch is disabled.
if (!switchView.isEnabled()) return;
if (isChecked) {
startTether();
} else {
@@ -118,39 +126,21 @@ public class WifiTetherSwitchBarController implements
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(action)) {
final int state = intent.getIntExtra(
WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED);
final int state = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_FAILED);
handleWifiApStateChanged(state);
}
}
};
private void handleWifiApStateChanged(int state) {
switch (state) {
case WifiManager.WIFI_AP_STATE_ENABLING:
mSwitchBar.setEnabled(false);
break;
case WifiManager.WIFI_AP_STATE_ENABLED:
if (!mSwitch.isChecked()) {
mSwitch.setChecked(true);
}
updateWifiSwitch();
break;
case WifiManager.WIFI_AP_STATE_DISABLING:
if (mSwitch.isChecked()) {
mSwitch.setChecked(false);
}
mSwitchBar.setEnabled(false);
break;
case WifiManager.WIFI_AP_STATE_DISABLED:
mSwitch.setChecked(false);
updateWifiSwitch();
break;
default:
mSwitch.setChecked(false);
updateWifiSwitch();
break;
@VisibleForTesting
void handleWifiApStateChanged(int state) {
if (state == WIFI_AP_STATE_ENABLING || state == WIFI_AP_STATE_DISABLING) return;
final boolean shouldBeChecked = (state == WIFI_AP_STATE_ENABLED);
if (mSwitch.isChecked() != shouldBeChecked) {
mSwitch.setChecked(shouldBeChecked);
}
updateWifiSwitch();
}
private void updateWifiSwitch() {