summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/ActiveModeManager.java24
-rw-r--r--service/java/com/android/server/wifi/ClientModeManager.java92
-rw-r--r--service/java/com/android/server/wifi/ScanOnlyModeManager.java57
-rw-r--r--service/java/com/android/server/wifi/SoftApManager.java47
-rw-r--r--service/java/com/android/server/wifi/WifiController.java158
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java4
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java844
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachinePrime.java283
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java60
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ScanOnlyModeManagerTest.java100
-rw-r--r--tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java68
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java30
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiStateMachinePrimeTest.java200
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java258
14 files changed, 819 insertions, 1406 deletions
diff --git a/service/java/com/android/server/wifi/ActiveModeManager.java b/service/java/com/android/server/wifi/ActiveModeManager.java
index 00ae7b3c2..6669e32f7 100644
--- a/service/java/com/android/server/wifi/ActiveModeManager.java
+++ b/service/java/com/android/server/wifi/ActiveModeManager.java
@@ -16,6 +16,12 @@
package com.android.server.wifi;
+import android.content.Context;
+import android.content.Intent;
+import android.net.wifi.WifiManager;
+import android.os.UserHandle;
+import android.util.Log;
+
/**
* Base class for available WiFi operating modes.
*
@@ -33,4 +39,22 @@ public interface ActiveModeManager {
* Method used to stop the Manager for a give Wifi operational mode.
*/
void stop();
+
+ /**
+ * Method that allows Mode Managers to update WifiScanner about the current state.
+ *
+ * @param context Context to use for the notification
+ * @param available boolean indicating if scanning is available
+ */
+ default void sendScanAvailableBroadcast(Context context, boolean available) {
+ Log.d(TAG, "sending scan available broadcast: " + available);
+ final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ if (available) {
+ intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_ENABLED);
+ } else {
+ intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_DISABLED);
+ }
+ context.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+ }
}
diff --git a/service/java/com/android/server/wifi/ClientModeManager.java b/service/java/com/android/server/wifi/ClientModeManager.java
index 14d55de1e..bd82876df 100644
--- a/service/java/com/android/server/wifi/ClientModeManager.java
+++ b/service/java/com/android/server/wifi/ClientModeManager.java
@@ -26,6 +26,7 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.util.IState;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.server.wifi.WifiNative.InterfaceCallback;
@@ -44,17 +45,20 @@ public class ClientModeManager implements ActiveModeManager {
private final WifiMetrics mWifiMetrics;
private final Listener mListener;
private final ScanRequestProxy mScanRequestProxy;
+ private final WifiStateMachine mWifiStateMachine;
private String mClientInterfaceName;
-
+ private boolean mIfaceIsUp;
ClientModeManager(Context context, @NonNull Looper looper, WifiNative wifiNative,
- Listener listener, WifiMetrics wifiMetrics, ScanRequestProxy scanRequestProxy) {
+ Listener listener, WifiMetrics wifiMetrics, ScanRequestProxy scanRequestProxy,
+ WifiStateMachine wifiStateMachine) {
mContext = context;
mWifiNative = wifiNative;
mListener = listener;
mWifiMetrics = wifiMetrics;
mScanRequestProxy = scanRequestProxy;
+ mWifiStateMachine = wifiStateMachine;
mStateMachine = new ClientModeStateMachine(looper);
}
@@ -69,7 +73,20 @@ public class ClientModeManager implements ActiveModeManager {
* Disconnect from any currently connected networks and stop client mode.
*/
public void stop() {
- mStateMachine.sendMessage(ClientModeStateMachine.CMD_STOP);
+ IState currentState = mStateMachine.getCurrentState();
+ Log.d(TAG, " currentstate: " + currentState);
+ if (mClientInterfaceName != null) {
+ if (mIfaceIsUp) {
+ updateWifiState(WifiManager.WIFI_STATE_DISABLING,
+ WifiManager.WIFI_STATE_ENABLED);
+ } else {
+ updateWifiState(WifiManager.WIFI_STATE_DISABLING,
+ WifiManager.WIFI_STATE_ENABLING);
+ }
+ }
+ if (currentState != null) {
+ currentState.exit();
+ }
}
/**
@@ -106,37 +123,35 @@ public class ClientModeManager implements ActiveModeManager {
private class ClientModeStateMachine extends StateMachine {
// Commands for the state machine.
public static final int CMD_START = 0;
- public static final int CMD_STOP = 1;
- public static final int CMD_WIFINATIVE_FAILURE = 2;
public static final int CMD_INTERFACE_STATUS_CHANGED = 3;
public static final int CMD_INTERFACE_DESTROYED = 4;
+ public static final int CMD_INTERFACE_DOWN = 5;
private final State mIdleState = new IdleState();
private final State mStartedState = new StartedState();
- private WifiNative.StatusListener mWifiNativeStatusListener = (boolean isReady) -> {
- if (!isReady) {
- sendMessage(CMD_WIFINATIVE_FAILURE);
- }
- };
private final InterfaceCallback mWifiNativeInterfaceCallback = new InterfaceCallback() {
@Override
public void onDestroyed(String ifaceName) {
- sendMessage(CMD_INTERFACE_DESTROYED);
+ if (mClientInterfaceName != null && mClientInterfaceName.equals(ifaceName)) {
+ sendMessage(CMD_INTERFACE_DESTROYED);
+ }
}
@Override
public void onUp(String ifaceName) {
- sendMessage(CMD_INTERFACE_STATUS_CHANGED, 1);
+ if (mClientInterfaceName != null && mClientInterfaceName.equals(ifaceName)) {
+ sendMessage(CMD_INTERFACE_STATUS_CHANGED, 1);
+ }
}
@Override
public void onDown(String ifaceName) {
- sendMessage(CMD_INTERFACE_STATUS_CHANGED, 0);
+ if (mClientInterfaceName != null && mClientInterfaceName.equals(ifaceName)) {
+ sendMessage(CMD_INTERFACE_STATUS_CHANGED, 0);
+ }
}
};
- private boolean mIfaceIsUp = false;
-
ClientModeStateMachine(Looper looper) {
super(TAG, looper);
@@ -152,8 +167,8 @@ public class ClientModeManager implements ActiveModeManager {
@Override
public void enter() {
Log.d(TAG, "entering IdleState");
- mWifiNative.registerStatusListener(mWifiNativeStatusListener);
mClientInterfaceName = null;
+ mIfaceIsUp = false;
}
@Override
@@ -167,17 +182,15 @@ public class ClientModeManager implements ActiveModeManager {
false /* not low priority */, mWifiNativeInterfaceCallback);
if (TextUtils.isEmpty(mClientInterfaceName)) {
Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
- sendScanAvailableBroadcast(false);
updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
WifiManager.WIFI_STATE_ENABLING);
+ updateWifiState(WifiManager.WIFI_STATE_DISABLED,
+ WifiManager.WIFI_STATE_UNKNOWN);
break;
}
+ sendScanAvailableBroadcast(false);
transitionTo(mStartedState);
break;
- case CMD_STOP:
- // This should be safe to ignore.
- Log.d(TAG, "received CMD_STOP when idle, ignoring");
- break;
default:
Log.d(TAG, "received an invalid message: " + message);
return NOT_HANDLED;
@@ -196,14 +209,21 @@ public class ClientModeManager implements ActiveModeManager {
if (isUp) {
Log.d(TAG, "Wifi is ready to use for client mode");
sendScanAvailableBroadcast(true);
+ mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE,
+ mClientInterfaceName);
updateWifiState(WifiManager.WIFI_STATE_ENABLED,
WifiManager.WIFI_STATE_ENABLING);
} else {
+ if (mWifiStateMachine.isConnectedMacRandomizationEnabled()) {
+ // Handle the error case where our underlying interface went down if we
+ // do not have mac randomization enabled (b/72459123).
+ return;
+ }
// if the interface goes down we should exit and go back to idle state.
- Log.d(TAG, "interface down! may need to restart ClientMode");
+ Log.d(TAG, "interface down!");
updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
- WifiManager.WIFI_STATE_UNKNOWN);
- mStateMachine.sendMessage(CMD_STOP);
+ WifiManager.WIFI_STATE_ENABLED);
+ mStateMachine.sendMessage(CMD_INTERFACE_DOWN);
}
}
@@ -221,25 +241,18 @@ public class ClientModeManager implements ActiveModeManager {
case CMD_START:
// Already started, ignore this command.
break;
- case CMD_STOP:
- Log.d(TAG, "Stopping client mode.");
+ case CMD_INTERFACE_DOWN:
+ Log.e(TAG, "Detected an interface down, reporting failure to SelfRecovery");
+ mWifiStateMachine.failureDetected(SelfRecovery.REASON_STA_IFACE_DOWN);
+
updateWifiState(WifiManager.WIFI_STATE_DISABLING,
- WifiManager.WIFI_STATE_ENABLED);
- mWifiNative.teardownInterface(mClientInterfaceName);
+ WifiManager.WIFI_STATE_UNKNOWN);
transitionTo(mIdleState);
break;
case CMD_INTERFACE_STATUS_CHANGED:
boolean isUp = message.arg1 == 1;
onUpChanged(isUp);
break;
- case CMD_WIFINATIVE_FAILURE:
- Log.d(TAG, "WifiNative failure - may need to restart ClientMode!");
- updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
- WifiManager.WIFI_STATE_UNKNOWN);
- updateWifiState(WifiManager.WIFI_STATE_DISABLING,
- WifiManager.WIFI_STATE_ENABLED);
- transitionTo(mIdleState);
- break;
case CMD_INTERFACE_DESTROYED:
Log.d(TAG, "interface destroyed - client mode stopping");
@@ -259,12 +272,19 @@ public class ClientModeManager implements ActiveModeManager {
*/
@Override
public void exit() {
+ if (mClientInterfaceName == null) {
+ return;
+ }
+ mWifiStateMachine.setOperationalMode(WifiStateMachine.DISABLED_MODE, null);
+ mWifiNative.teardownInterface(mClientInterfaceName);
// let WifiScanner know that wifi is down.
sendScanAvailableBroadcast(false);
updateWifiState(WifiManager.WIFI_STATE_DISABLED,
WifiManager.WIFI_STATE_DISABLING);
mScanRequestProxy.enableScanningForHiddenNetworks(false);
mScanRequestProxy.clearScanResults();
+ mClientInterfaceName = null;
+ mIfaceIsUp = false;
}
}
diff --git a/service/java/com/android/server/wifi/ScanOnlyModeManager.java b/service/java/com/android/server/wifi/ScanOnlyModeManager.java
index f1351b24f..4973de53d 100644
--- a/service/java/com/android/server/wifi/ScanOnlyModeManager.java
+++ b/service/java/com/android/server/wifi/ScanOnlyModeManager.java
@@ -18,14 +18,13 @@ package com.android.server.wifi;
import android.annotation.NonNull;
import android.content.Context;
-import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.Looper;
import android.os.Message;
-import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.util.IState;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.server.wifi.WifiNative.InterfaceCallback;
@@ -49,7 +48,6 @@ public class ScanOnlyModeManager implements ActiveModeManager {
private String mClientInterfaceName;
-
ScanOnlyModeManager(@NonNull Context context, @NonNull Looper looper,
@NonNull WifiNative wifiNative, @NonNull Listener listener,
@NonNull WifiMetrics wifiMetrics,
@@ -75,7 +73,11 @@ public class ScanOnlyModeManager implements ActiveModeManager {
* Cancel any pending scans and stop scan mode.
*/
public void stop() {
- mStateMachine.sendMessage(ScanOnlyModeStateMachine.CMD_STOP);
+ IState currentState = mStateMachine.getCurrentState();
+ Log.d(TAG, " currentstate: " + currentState);
+ if (currentState != null) {
+ currentState.exit();
+ }
}
/**
@@ -100,8 +102,6 @@ public class ScanOnlyModeManager implements ActiveModeManager {
private class ScanOnlyModeStateMachine extends StateMachine {
// Commands for the state machine.
public static final int CMD_START = 0;
- public static final int CMD_STOP = 1;
- public static final int CMD_WIFINATIVE_FAILURE = 2;
public static final int CMD_INTERFACE_STATUS_CHANGED = 3;
public static final int CMD_INTERFACE_DESTROYED = 4;
public static final int CMD_INTERFACE_DOWN = 5;
@@ -109,12 +109,6 @@ public class ScanOnlyModeManager implements ActiveModeManager {
private final State mIdleState = new IdleState();
private final State mStartedState = new StartedState();
- private final WifiNative.StatusListener mWifiNativeStatusListener = (boolean isReady) -> {
- if (!isReady) {
- sendMessage(CMD_WIFINATIVE_FAILURE);
- }
- };
-
private final InterfaceCallback mWifiNativeInterfaceCallback = new InterfaceCallback() {
@Override
public void onDestroyed(String ifaceName) {
@@ -154,7 +148,6 @@ public class ScanOnlyModeManager implements ActiveModeManager {
@Override
public void enter() {
Log.d(TAG, "entering IdleState");
- mWifiNative.registerStatusListener(mWifiNativeStatusListener);
mClientInterfaceName = null;
}
@@ -166,16 +159,14 @@ public class ScanOnlyModeManager implements ActiveModeManager {
mWifiNativeInterfaceCallback);
if (TextUtils.isEmpty(mClientInterfaceName)) {
Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
- sendScanAvailableBroadcast(false);
updateWifiState(WifiManager.WIFI_STATE_UNKNOWN);
break;
}
+ // we have a new scanning interface, make sure scanner knows we aren't
+ // ready yet
+ sendScanAvailableBroadcast(false);
transitionTo(mStartedState);
break;
- case CMD_STOP:
- // This should be safe to ignore.
- Log.d(TAG, "received CMD_STOP when idle, ignoring");
- break;
default:
Log.d(TAG, "received an invalid message: " + message);
return NOT_HANDLED;
@@ -218,12 +209,9 @@ public class ScanOnlyModeManager implements ActiveModeManager {
case CMD_START:
// Already started, ignore this command.
break;
- case CMD_STOP:
- Log.d(TAG, "Stopping scan mode.");
- transitionTo(mIdleState);
- break;
case CMD_INTERFACE_DESTROYED:
Log.d(TAG, "Interface cleanly destroyed, report scan mode stop.");
+ mClientInterfaceName = null;
transitionTo(mIdleState);
break;
case CMD_INTERFACE_STATUS_CHANGED:
@@ -231,8 +219,7 @@ public class ScanOnlyModeManager implements ActiveModeManager {
onUpChanged(isUp);
break;
case CMD_INTERFACE_DOWN:
- case CMD_WIFINATIVE_FAILURE:
- Log.d(TAG, "native/interface failure! restart services?");
+ Log.d(TAG, "interface down! stop mode");
updateWifiState(WifiManager.WIFI_STATE_UNKNOWN);
transitionTo(mIdleState);
break;
@@ -249,24 +236,18 @@ public class ScanOnlyModeManager implements ActiveModeManager {
@Override
public void exit() {
mWakeupController.stop();
- //mWifiNative.teardownInterface(mClientInterfaceName);
- // let WifiScanner know that wifi is down.
- sendScanAvailableBroadcast(false);
+ if (mClientInterfaceName == null) {
+ return;
+ }
+ mWifiNative.teardownInterface(mClientInterfaceName);
+ mClientInterfaceName = null;
updateWifiState(WifiManager.WIFI_STATE_DISABLED);
mScanRequestProxy.clearScanResults();
}
}
+ }
- private void sendScanAvailableBroadcast(boolean available) {
- Log.d(TAG, "sending scan available broadcast: " + available);
- final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- if (available) {
- intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_ENABLED);
- } else {
- intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WifiManager.WIFI_STATE_DISABLED);
- }
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
+ private void sendScanAvailableBroadcast(boolean available) {
+ sendScanAvailableBroadcast(mContext, available);
}
}
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index d2d0c4a37..77c217ab2 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -37,12 +37,12 @@ import android.util.Log;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IState;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.internal.util.WakeupMessage;
import com.android.server.wifi.WifiNative.InterfaceCallback;
import com.android.server.wifi.WifiNative.SoftApListener;
-import com.android.server.wifi.WifiNative.StatusListener;
import com.android.server.wifi.util.ApConfigUtil;
import java.util.Locale;
@@ -72,6 +72,7 @@ public class SoftApManager implements ActiveModeManager {
private final WifiManager.SoftApCallback mCallback;
private String mApInterfaceName;
+ private boolean mIfaceIsUp;
private final WifiApConfigStore mWifiApConfigStore;
@@ -134,7 +135,20 @@ public class SoftApManager implements ActiveModeManager {
* Stop soft AP.
*/
public void stop() {
- mStateMachine.sendMessage(SoftApStateMachine.CMD_STOP);
+ IState currentState = mStateMachine.getCurrentState();
+ Log.d(TAG, " currentstate: " + currentState);
+ if (mApInterfaceName != null) {
+ if (mIfaceIsUp) {
+ updateApState(WifiManager.WIFI_AP_STATE_DISABLING,
+ WifiManager.WIFI_AP_STATE_ENABLED, 0);
+ } else {
+ updateApState(WifiManager.WIFI_AP_STATE_DISABLING,
+ WifiManager.WIFI_AP_STATE_ENABLING, 0);
+ }
+ }
+ if (currentState != null) {
+ currentState.exit();
+ }
}
/**
@@ -219,8 +233,6 @@ public class SoftApManager implements ActiveModeManager {
private class SoftApStateMachine extends StateMachine {
// Commands for the state machine.
public static final int CMD_START = 0;
- public static final int CMD_STOP = 1;
- public static final int CMD_WIFINATIVE_FAILURE = 2;
public static final int CMD_INTERFACE_STATUS_CHANGED = 3;
public static final int CMD_NUM_ASSOCIATED_STATIONS_CHANGED = 4;
public static final int CMD_NO_ASSOCIATED_STATIONS_TIMEOUT = 5;
@@ -232,12 +244,6 @@ public class SoftApManager implements ActiveModeManager {
private final State mIdleState = new IdleState();
private final State mStartedState = new StartedState();
- private final StatusListener mWifiNativeStatusListener = (boolean isReady) -> {
- if (!isReady) {
- sendMessage(CMD_WIFINATIVE_FAILURE);
- }
- };
-
private final InterfaceCallback mWifiNativeInterfaceCallback = new InterfaceCallback() {
@Override
public void onDestroyed(String ifaceName) {
@@ -274,8 +280,8 @@ public class SoftApManager implements ActiveModeManager {
private class IdleState extends State {
@Override
public void enter() {
- mWifiNative.registerStatusListener(mWifiNativeStatusListener);
mApInterfaceName = null;
+ mIfaceIsUp = false;
}
@Override
@@ -320,8 +326,6 @@ public class SoftApManager implements ActiveModeManager {
}
private class StartedState extends State {
- private boolean mIfaceIsUp;
-
private int mNumAssociatedStations;
private boolean mTimeoutEnabled;
@@ -454,8 +458,10 @@ public class SoftApManager implements ActiveModeManager {
@Override
public void exit() {
- // will trigger interface teardown when interface management is dynamic
- // stopSoftAp();
+ if (mApInterfaceName == null) {
+ return;
+ }
+ stopSoftAp();
if (mSettingObserver != null) {
mSettingObserver.unregister();
}
@@ -467,6 +473,8 @@ public class SoftApManager implements ActiveModeManager {
mWifiMetrics.addSoftApUpChangedEvent(false, mMode);
updateApState(WifiManager.WIFI_AP_STATE_DISABLED,
WifiManager.WIFI_AP_STATE_DISABLING, 0);
+ mApInterfaceName = null;
+ mIfaceIsUp = false;
}
@Override
@@ -517,12 +525,6 @@ public class SoftApManager implements ActiveModeManager {
break;
}
Log.i(TAG, "Timeout message received. Stopping soft AP.");
- stopSoftAp();
- updateApState(WifiManager.WIFI_AP_STATE_DISABLING,
- WifiManager.WIFI_AP_STATE_ENABLED, 0);
- transitionTo(mIdleState);
- break;
- case CMD_STOP:
updateApState(WifiManager.WIFI_AP_STATE_DISABLING,
WifiManager.WIFI_AP_STATE_ENABLED, 0);
transitionTo(mIdleState);
@@ -533,9 +535,8 @@ public class SoftApManager implements ActiveModeManager {
WifiManager.WIFI_AP_STATE_ENABLED, 0);
transitionTo(mIdleState);
break;
- case CMD_WIFINATIVE_FAILURE:
case CMD_INTERFACE_DOWN:
- Log.w(TAG, "native/interface error, stop and report failure");
+ Log.w(TAG, "interface error, stop and report failure");
updateApState(WifiManager.WIFI_AP_STATE_FAILED,
WifiManager.WIFI_AP_STATE_ENABLED,
WifiManager.SAP_START_FAILURE_GENERAL);
diff --git a/service/java/com/android/server/wifi/WifiController.java b/service/java/com/android/server/wifi/WifiController.java
index 76b44c82f..7fb223535 100644
--- a/service/java/com/android/server/wifi/WifiController.java
+++ b/service/java/com/android/server/wifi/WifiController.java
@@ -30,6 +30,7 @@ import android.os.Message;
import android.os.SystemClock;
import android.os.WorkSource;
import android.provider.Settings;
+import android.util.Log;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
@@ -93,6 +94,8 @@ public class WifiController extends StateMachine {
private static final int CMD_RECOVERY_RESTART_WIFI_CONTINUE = BASE + 18;
// Command to disable wifi when SelfRecovery is throttled or otherwise not doing full recovery
static final int CMD_RECOVERY_DISABLE_WIFI = BASE + 19;
+ static final int CMD_STA_STOPPED = BASE + 20;
+ static final int CMD_SCANNING_STOPPED = BASE + 21;
private DefaultState mDefaultState = new DefaultState();
private StaEnabledState mStaEnabledState = new StaEnabledState();
@@ -102,6 +105,9 @@ public class WifiController extends StateMachine {
private DeviceActiveState mDeviceActiveState = new DeviceActiveState();
private EcmState mEcmState = new EcmState();
+ private ScanOnlyModeManager.Listener mScanOnlyModeCallback = new ScanOnlyCallback();
+ private ClientModeManager.Listener mClientModeCallback = new ClientModeCallback();
+
WifiController(Context context, WifiStateMachine wsm, Looper wifiStateMachineLooper,
WifiSettingsStore wss, Looper wifiServiceLooper, FrameworkFacade f,
WifiStateMachinePrime wsmp) {
@@ -113,6 +119,7 @@ public class WifiController extends StateMachine {
mWifiStateMachinePrime = wsmp;
mSettingsStore = wss;
+ // CHECKSTYLE:OFF IndentationCheck
addState(mDefaultState);
addState(mApStaDisabledState, mDefaultState);
addState(mStaEnabledState, mDefaultState);
@@ -120,6 +127,7 @@ public class WifiController extends StateMachine {
addState(mStaDisabledWithScanState, mDefaultState);
addState(mApEnabledState, mDefaultState);
addState(mEcmState, mDefaultState);
+ // CHECKSTYLE:ON IndentationCheck
boolean isAirplaneModeOn = mSettingsStore.isAirplaneModeOn();
boolean isWifiEnabled = mSettingsStore.isWifiToggleEnabled();
@@ -142,6 +150,10 @@ public class WifiController extends StateMachine {
setLogRecSize(100);
setLogOnlyTransitions(false);
+ // register for state updates via callbacks (vs the intents registered below)
+ mWifiStateMachinePrime.registerScanOnlyCallback(mScanOnlyModeCallback);
+ mWifiStateMachinePrime.registerClientModeCallback(mClientModeCallback);
+
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
@@ -160,19 +172,11 @@ public class WifiController extends StateMachine {
WifiManager.EXTRA_WIFI_AP_STATE,
WifiManager.WIFI_AP_STATE_FAILED);
if (state == WifiManager.WIFI_AP_STATE_FAILED) {
- loge(TAG + "SoftAP start failed");
+ Log.e(TAG, "SoftAP start failed");
sendMessage(CMD_AP_START_FAILURE);
} else if (state == WifiManager.WIFI_AP_STATE_DISABLED) {
sendMessage(CMD_AP_STOPPED);
}
- } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
- int state = intent.getIntExtra(
- WifiManager.EXTRA_WIFI_STATE,
- WifiManager.WIFI_STATE_UNKNOWN);
- if (state == WifiManager.WIFI_STATE_UNKNOWN) {
- loge(TAG + "Wifi turn on failed");
- sendMessage(CMD_STA_START_FAILURE);
- }
} else if (action.equals(LocationManager.MODE_CHANGED_ACTION)) {
// Location mode has been toggled... trigger with the scan change
// update to make sure we are in the correct mode
@@ -194,6 +198,48 @@ public class WifiController extends StateMachine {
return mSettingsStore.isScanAlwaysAvailable();
}
+ /**
+ * Listener used to receive scan mode updates - really needed for disabled updates to trigger
+ * mode changes.
+ */
+ private class ScanOnlyCallback implements ScanOnlyModeManager.Listener {
+ @Override
+ public void onStateChanged(int state) {
+ if (state == WifiManager.WIFI_STATE_UNKNOWN) {
+ Log.d(TAG, "ScanOnlyMode unexpected failure: state unknown");
+ } else if (state == WifiManager.WIFI_STATE_DISABLED) {
+ Log.d(TAG, "ScanOnlyMode stopped");
+ sendMessage(CMD_SCANNING_STOPPED);
+ } else if (state == WifiManager.WIFI_STATE_ENABLED) {
+ // scan mode is ready to go
+ Log.d(TAG, "scan mode active");
+ } else {
+ Log.d(TAG, "unexpected state update: " + state);
+ }
+ }
+ }
+
+ /**
+ * Listener used to receive client mode updates
+ */
+ private class ClientModeCallback implements ClientModeManager.Listener {
+ @Override
+ public void onStateChanged(int state) {
+ if (state == WifiManager.WIFI_STATE_UNKNOWN) {
+ logd("ClientMode unexpected failure: state unknown");
+ sendMessage(CMD_STA_START_FAILURE);
+ } else if (state == WifiManager.WIFI_STATE_DISABLED) {
+ logd("ClientMode stopped");
+ sendMessage(CMD_STA_STOPPED);
+ } else if (state == WifiManager.WIFI_STATE_ENABLED) {
+ // scan mode is ready to go
+ logd("client mode active");
+ } else {
+ logd("unexpected state update: " + state);
+ }
+ }
+ }
+
private void readWifiReEnableDelay() {
mReEnableDelayMillis = mFacade.getLongSetting(mContext,
Settings.Global.WIFI_REENABLE_DELAY_MS, DEFAULT_REENABLE_DELAY_MS);
@@ -216,11 +262,18 @@ public class WifiController extends StateMachine {
case CMD_EMERGENCY_CALL_STATE_CHANGED:
case CMD_AP_START_FAILURE:
case CMD_AP_STOPPED:
+ case CMD_SCANNING_STOPPED:
+ case CMD_STA_STOPPED:
case CMD_STA_START_FAILURE:
- case CMD_RECOVERY_RESTART_WIFI:
case CMD_RECOVERY_RESTART_WIFI_CONTINUE:
case CMD_RECOVERY_DISABLE_WIFI:
break;
+ case CMD_RECOVERY_RESTART_WIFI:
+ // TODO:b/72850700 : when softap is split out, we need to fully disable wifi
+ // here (like airplane mode toggle).
+ deferMessage(obtainMessage(CMD_RECOVERY_RESTART_WIFI_CONTINUE));
+ transitionTo(mApStaDisabledState);
+ break;
case CMD_USER_PRESENT:
mFirstUserSignOnSeen = true;
break;
@@ -242,7 +295,6 @@ public class WifiController extends StateMachine {
@Override
public void enter() {
- mWifiStateMachine.setOperationalMode(WifiStateMachine.DISABLED_MODE);
mWifiStateMachinePrime.disableWifi();
// Supplicant can't restart right away, so note the time we switched off
mDisabledTimestamp = SystemClock.elapsedRealtime();
@@ -264,11 +316,6 @@ public class WifiController extends StateMachine {
mHaveDeferredEnable = !mHaveDeferredEnable;
break;
}
- // wifi is toggled, we need to explicitly tell WifiStateMachine that we
- // are headed to connect mode before going to the DeviceActiveState
- // since that will start supplicant and WifiStateMachine may not know
- // what state to head to (it might go to scan mode).
- mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);
transitionTo(mDeviceActiveState);
} else if (checkScanOnlyModeAvailable()) {
transitionTo(mStaDisabledWithScanState);
@@ -279,15 +326,17 @@ public class WifiController extends StateMachine {
transitionTo(mStaDisabledWithScanState);
break;
}
- mWifiStateMachine.setOperationalMode(WifiStateMachine.DISABLED_MODE);
break;
case CMD_SET_AP:
+ // first make sure we aren't in airplane mode
+ if (mSettingsStore.isAirplaneModeOn()) {
+ log("drop softap requests when in airplane mode");
+ break;
+ }
if (msg.arg1 == 1) {
if (msg.arg2 == 0) { // previous wifi state has not been saved yet
mSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_DISABLED);
}
- mWifiStateMachine.setHostApRunning((SoftApModeConfiguration) msg.obj,
- true);
mWifiStateMachinePrime.enterSoftAPMode((SoftApModeConfiguration) msg.obj);
transitionTo(mApEnabledState);
}
@@ -301,7 +350,15 @@ public class WifiController extends StateMachine {
sendMessage((Message)(msg.obj));
break;
case CMD_RECOVERY_RESTART_WIFI_CONTINUE:
- transitionTo(mDeviceActiveState);
+ if (mSettingsStore.isWifiToggleEnabled()) {
+ // wifi is currently disabled but the toggle is on, must have had an
+ // interface down before the recovery triggered
+ transitionTo(mDeviceActiveState);
+ break;
+ } else if (checkScanOnlyModeAvailable()) {
+ transitionTo(mStaDisabledWithScanState);
+ break;
+ }
break;
default:
return NOT_HANDLED;
@@ -372,15 +429,14 @@ public class WifiController extends StateMachine {
break;
case CMD_SET_AP:
if (msg.arg1 == 1) {
- // remeber that we were enabled
+ // remember that we were enabled
mSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_ENABLED);
- mWifiStateMachine.setHostApRunning((SoftApModeConfiguration) msg.obj, true);
+ // since softap is not split out in WifiController, need to explicitly
+ // disable client and scan modes
+ mWifiStateMachinePrime.disableWifi();
+
mWifiStateMachinePrime.enterSoftAPMode((SoftApModeConfiguration) msg.obj);
transitionTo(mApEnabledState);
- // we should just go directly to ApEnabled since we will kill interfaces
- // from WSMP
- //deferMessage(obtainMessage(msg.what, msg.arg1, 1, msg.obj));
- //transitionTo(mApStaDisabledState);
}
break;
default:
@@ -398,9 +454,6 @@ public class WifiController extends StateMachine {
@Override
public void enter() {
- // first send the message to WSM to trigger the transition and act as a shadow
- mWifiStateMachine.setOperationalMode(WifiStateMachine.SCAN_ONLY_WITH_WIFI_OFF_MODE);
-
// now trigger the actual mode switch in WifiStateMachinePrime
mWifiStateMachinePrime.enterScanOnlyMode();
@@ -424,8 +477,6 @@ public class WifiController extends StateMachine {
mHaveDeferredEnable = !mHaveDeferredEnable;
break;
}
- // transition from scan mode to initial state in WifiStateMachine
- mWifiStateMachine.setOperationalMode(WifiStateMachine.DISABLED_MODE);
transitionTo(mDeviceActiveState);
}
break;
@@ -445,14 +496,12 @@ public class WifiController extends StateMachine {
// Before starting tethering, turn off supplicant for scan mode
if (msg.arg1 == 1) {
mSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_DISABLED);
+ // since softap is not split out in WifiController, need to explicitly
+ // disable client and scan modes
+ mWifiStateMachinePrime.disableWifi();
- mWifiStateMachine.setHostApRunning((SoftApModeConfiguration) msg.obj, true);
mWifiStateMachinePrime.enterSoftAPMode((SoftApModeConfiguration) msg.obj);
transitionTo(mApEnabledState);
- // we should just go directly to ApEnabled since we will kill interfaces
- // from WSMP
- //deferMessage(obtainMessage(msg.what, msg.arg1, 1, msg.obj));
- //transitionTo(mApStaDisabledState);
}
break;
case CMD_DEFERRED_TOGGLE:
@@ -517,31 +566,29 @@ public class WifiController extends StateMachine {
}
@Override
+ public void exit() {
+ mWifiStateMachinePrime.stopSoftAPMode();
+ }
+
+ @Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case CMD_AIRPLANE_TOGGLED:
if (mSettingsStore.isAirplaneModeOn()) {
- mWifiStateMachine.setHostApRunning(null, false);
- mWifiStateMachinePrime.disableWifi();
- mPendingState = mApStaDisabledState;
+ transitionTo(mApStaDisabledState);
}
break;
case CMD_WIFI_TOGGLED:
if (mSettingsStore.isWifiToggleEnabled()) {
- mWifiStateMachine.setHostApRunning(null, false);
- mWifiStateMachinePrime.disableWifi();
- mPendingState = mDeviceActiveState;
+ transitionTo(mDeviceActiveState);
}
break;
case CMD_SET_AP:
if (msg.arg1 == 0) {
- mWifiStateMachine.setHostApRunning(null, false);
- mWifiStateMachinePrime.disableWifi();
- mPendingState = getNextWifiState();
+ transitionTo(getNextWifiState());
}
break;
case CMD_AP_STOPPED:
- mWifiStateMachine.setHostApRunning(null, false);
if (mPendingState == null) {
/**
* Stop triggered internally, either tether notification
@@ -554,13 +601,18 @@ public class WifiController extends StateMachine {
case CMD_EMERGENCY_CALL_STATE_CHANGED:
case CMD_EMERGENCY_MODE_CHANGED:
if (msg.arg1 == 1) {
- mWifiStateMachine.setHostApRunning(null, false);
- mWifiStateMachinePrime.disableWifi();
- mPendingState = mEcmState;
+ transitionTo(mEcmState);
}
break;
case CMD_AP_START_FAILURE:
- mWifiStateMachine.setHostApRunning(null, false);
+ transitionTo(getNextWifiState());
+ break;
+ case CMD_RECOVERY_RESTART_WIFI:
+ case CMD_RECOVERY_DISABLE_WIFI:
+ // note: this will need to fully shutdown wifi when softap mode is removed from
+ // the state machine
+ loge("Recovery triggered while in softap active, disable");
+ mWifiStateMachinePrime.disableWifi();
transitionTo(getNextWifiState());
break;
default:
@@ -578,7 +630,6 @@ public class WifiController extends StateMachine {
private int mEcmEntryCount;
@Override
public void enter() {
- mWifiStateMachine.setOperationalMode(WifiStateMachine.DISABLED_MODE);
mWifiStateMachinePrime.disableWifi();
mWifiStateMachine.clearANQPCache();
mEcmEntryCount = 1;
@@ -605,6 +656,10 @@ public class WifiController extends StateMachine {
decrementCountAndReturnToAppropriateState();
}
return HANDLED;
+ } else if (msg.what == CMD_RECOVERY_RESTART_WIFI
+ || msg.what == CMD_RECOVERY_DISABLE_WIFI) {
+ // do not want to restart wifi if we are in emergency mode
+ return HANDLED;
} else {
return NOT_HANDLED;
}
@@ -636,7 +691,6 @@ public class WifiController extends StateMachine {
class DeviceActiveState extends State {
@Override
public void enter() {
- mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);
mWifiStateMachinePrime.enterClientMode();
mWifiStateMachine.setHighPerfModeEnabled(false);
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 82f7d6cb2..cdde22268 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -257,7 +257,7 @@ public class WifiInjector {
this, mBackupManagerProxy, mCountryCode, mWifiNative,
new WrongPasswordNotifier(mContext, mFrameworkFacade));
IBinder b = mFrameworkFacade.getService(Context.NETWORKMANAGEMENT_SERVICE);
- mWifiStateMachinePrime = new WifiStateMachinePrime(this, wifiStateMachineLooper,
+ mWifiStateMachinePrime = new WifiStateMachinePrime(this, mContext, wifiStateMachineLooper,
mWifiNative, new DefaultModeManager(mContext, wifiStateMachineLooper),
mBatteryStats);
mOpenNetworkNotifier = new OpenNetworkNotifier(mContext,
@@ -474,7 +474,7 @@ public class WifiInjector {
*/
public ClientModeManager makeClientModeManager(ClientModeManager.Listener listener) {
return new ClientModeManager(mContext, mWifiStateMachineHandlerThread.getLooper(),
- mWifiNative, listener, mWifiMetrics, mScanRequestProxy);
+ mWifiNative, listener, mWifiMetrics, mScanRequestProxy, mWifiStateMachine);
}
/**
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index dbb83609b..32427c92c 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -96,8 +96,6 @@ import com.android.internal.util.MessageUtils;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
-import com.android.server.wifi.WifiNative.InterfaceCallback;
-import com.android.server.wifi.WifiNative.StatusListener;
import com.android.server.wifi.hotspot2.AnqpEvent;
import com.android.server.wifi.hotspot2.IconEvent;
import com.android.server.wifi.hotspot2.NetworkDetail;
@@ -130,17 +128,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
- * TODO:
- * Deprecate WIFI_STATE_UNKNOWN
- */
-
-/**
* Track the state of Wifi connectivity. All event handling is done here,
* and all changes in connectivity state are initiated here.
*
* Wi-Fi now supports three modes of operation: Client, SoftAp and p2p
* In the current implementation, we support concurrent wifi p2p and wifi operation.
- * The WifiStateMachine handles SoftAp and Client operations while WifiP2pService
+ * The WifiStateMachine handles Client operations while WifiP2pService
* handles p2p operation.
*
* @hide
@@ -196,7 +189,6 @@ public class WifiStateMachine extends StateMachine {
private ConnectivityManager mCm;
private BaseWifiDiagnostics mWifiDiagnostics;
private ScanRequestProxy mScanRequestProxy;
- private WifiApConfigStore mWifiApConfigStore;
private final boolean mP2pSupported;
private final AtomicBoolean mP2pConnected = new AtomicBoolean(false);
private boolean mTemporarilyDisconnectWifi = false;
@@ -221,45 +213,8 @@ public class WifiStateMachine extends StateMachine {
private String mLastBssid;
private int mLastNetworkId; // The network Id we successfully joined
- private final StatusListener mWifiNativeStatusListener = (boolean isReady) -> {
- if (!isReady) {
- sendMessage(CMD_WIFINATIVE_FAILURE);
- }
- };
-
- private final InterfaceCallback mWifiNativeInterfaceCallback = new InterfaceCallback() {
- @Override
- public void onDestroyed(String ifaceName) {
- if (mInterfaceName != null && mInterfaceName.equals(ifaceName)) {
- sendMessage(CMD_INTERFACE_DESTROYED);
- }
- }
-
- @Override
- public void onUp(String ifaceName) {
- if (mInterfaceName != null && mInterfaceName.equals(ifaceName)) {
- sendMessage(CMD_INTERFACE_STATUS_CHANGED, 1);
- }
- }
-
- @Override
- public void onDown(String ifaceName) {
- if (mInterfaceName != null && mInterfaceName.equals(ifaceName)) {
- sendMessage(CMD_INTERFACE_STATUS_CHANGED, 0);
- }
- }
- };
private boolean mIpReachabilityDisconnectEnabled = true;
- private WifiManager.SoftApCallback mSoftApCallback;
-
- /**
- * Called from WifiServiceImpl to register a callback for notifications from SoftApManager
- */
- public void registerSoftApCallback(WifiManager.SoftApCallback callback) {
- mSoftApCallback = callback;
- }
-
private void processRssiThreshold(byte curRssi, int reason,
WifiNative.WifiRssiEventHandler rssiHandler) {
if (curRssi == Byte.MAX_VALUE || curRssi == Byte.MIN_VALUE) {
@@ -303,6 +258,8 @@ public class WifiStateMachine extends StateMachine {
// variable indicating we are expecting a mode switch - do not attempt recovery for failures
private boolean mModeChange = false;
+ private ClientModeManager.Listener mClientModeCallback = null;
+
private boolean mBluetoothConnectionActive = false;
private PowerManager.WakeLock mSuspendWakeLock;
@@ -460,29 +417,10 @@ public class WifiStateMachine extends StateMachine {
/* The base for wifi message types */
static final int BASE = Protocol.BASE_WIFI;
- /* Start the STA interface */
- static final int CMD_START_SUPPLICANT = BASE + 11;
- /* Stop the STA interface */
- static final int CMD_STOP_SUPPLICANT = BASE + 12;
- /* STA interface destroyed */
- static final int CMD_INTERFACE_DESTROYED = BASE + 13;
- /* STA interface down */
- static final int CMD_INTERFACE_DOWN = BASE + 14;
/* Indicates Static IP succeeded */
static final int CMD_STATIC_IP_SUCCESS = BASE + 15;
/* Indicates Static IP failed */
static final int CMD_STATIC_IP_FAILURE = BASE + 16;
- /* Interface status change */
- static final int CMD_INTERFACE_STATUS_CHANGED = BASE + 20;
-
- /* Start the soft access point */
- static final int CMD_START_AP = BASE + 21;
- /* Indicates soft ap start failed */
- static final int CMD_START_AP_FAILURE = BASE + 22;
- /* Stop the soft access point */
- static final int CMD_STOP_AP = BASE + 23;
- /* Soft access point teardown is completed. */
- static final int CMD_AP_STOPPED = BASE + 24;
static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE = BASE + 31;
@@ -698,9 +636,6 @@ public class WifiStateMachine extends StateMachine {
/* used to indicate that the foreground user was switched */
static final int CMD_USER_STOP = BASE + 207;
- /* Signals that one of the native daemons is dead. */
- private static final int CMD_WIFINATIVE_FAILURE = BASE + 250;
-
/* Indicates that diagnostics should time out a connection start event. */
private static final int CMD_DIAGS_CONNECT_TIMEOUT = BASE + 252;
@@ -776,12 +711,6 @@ public class WifiStateMachine extends StateMachine {
/* Default parent state */
private State mDefaultState = new DefaultState();
- /* Temporary initial state */
- private State mInitialState = new InitialState();
- /* Driver loaded and supplicant ready */
- private State mSupplicantStartedState = new SupplicantStartedState();
- /* Scan for networks, no connection will be established */
- private State mScanModeState = new ScanModeState();
/* Connecting to an access point */
private State mConnectModeState = new ConnectModeState();
/* Connected at 802.11 (L2) level */
@@ -796,8 +725,6 @@ public class WifiStateMachine extends StateMachine {
private State mDisconnectingState = new DisconnectingState();
/* Network is not connected, supplicant assoc+auth is not complete */
private State mDisconnectedState = new DisconnectedState();
- /* Soft ap state */
- private State mSoftApState = new SoftApState();
/**
* One of {@link WifiManager#WIFI_STATE_DISABLED},
@@ -998,17 +925,13 @@ public class WifiStateMachine extends StateMachine {
// CHECKSTYLE:OFF IndentationCheck
addState(mDefaultState);
- addState(mInitialState, mDefaultState);
- addState(mSupplicantStartedState, mInitialState);
- addState(mConnectModeState, mSupplicantStartedState);
- addState(mL2ConnectedState, mConnectModeState);
- addState(mObtainingIpState, mL2ConnectedState);
- addState(mConnectedState, mL2ConnectedState);
- addState(mRoamingState, mL2ConnectedState);
- addState(mDisconnectingState, mConnectModeState);
- addState(mDisconnectedState, mConnectModeState);
- addState(mScanModeState, mDefaultState);
- addState(mSoftApState, mDefaultState);
+ addState(mConnectModeState, mDefaultState);
+ addState(mL2ConnectedState, mConnectModeState);
+ addState(mObtainingIpState, mL2ConnectedState);
+ addState(mConnectedState, mL2ConnectedState);
+ addState(mRoamingState, mL2ConnectedState);
+ addState(mDisconnectingState, mConnectModeState);
+ addState(mDisconnectedState, mConnectModeState);
// CHECKSTYLE:ON IndentationCheck
setInitialState(mDefaultState);
@@ -1022,13 +945,6 @@ public class WifiStateMachine extends StateMachine {
// Learn the initial state of whether the screen is on.
// We update this field when we receive broadcasts from the system.
handleScreenStateChanged(powerManager.isInteractive());
-
- final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WIFI_STATE_DISABLED);
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-
- sendWifiScanAvailable(false);
}
private void registerForWifiMonitorEvents() {
@@ -1457,28 +1373,6 @@ public class WifiStateMachine extends StateMachine {
/**
* TODO: doc
*/
- public void setSupplicantRunning(boolean enable) {
- if (enable) {
- sendMessage(CMD_START_SUPPLICANT);
- } else {
- sendMessage(CMD_STOP_SUPPLICANT);
- }
- }
-
- /**
- * TODO: doc
- */
- public void setHostApRunning(SoftApModeConfiguration wifiConfig, boolean enable) {
- if (enable) {
- sendMessage(CMD_START_AP, wifiConfig);
- } else {
- sendMessage(CMD_STOP_AP);
- }
- }
-
- /**
- * TODO: doc
- */
public int syncGetWifiState() {
return mWifiState.get();
}
@@ -1554,9 +1448,12 @@ public class WifiStateMachine extends StateMachine {
/**
* TODO: doc
*/
- public void setOperationalMode(int mode) {
- if (mVerboseLoggingEnabled) log("setting operational mode to " + String.valueOf(mode));
+ public void setOperationalMode(int mode, String ifaceName) {
+ if (mVerboseLoggingEnabled) {
+ log("setting operational mode to " + String.valueOf(mode) + " for iface: " + ifaceName);
+ }
mModeChange = true;
+ mInterfaceName = ifaceName;
sendMessage(CMD_SET_OPERATIONAL_MODE, mode, 0);
}
@@ -2532,17 +2429,6 @@ public class WifiStateMachine extends StateMachine {
if (mVerboseLoggingEnabled) log("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled);
}
- private void sendWifiScanAvailable(boolean available) {
- int state = WIFI_STATE_DISABLED;
- if (available) {
- state = WIFI_STATE_ENABLED;
- }
- final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, state);
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
-
private void setWifiState(int wifiState) {
final int previousWifiState = mWifiState.get();
@@ -2550,6 +2436,17 @@ public class WifiStateMachine extends StateMachine {
if (mVerboseLoggingEnabled) log("setWifiState: " + syncGetWifiStateByName());
+ // first let WifiController know what is going on
+ if (mClientModeCallback != null) {
+ mClientModeCallback.onStateChanged(wifiState);
+ // once this instance of client mode is complete, remove the callback so we don't
+ // confuse ourselves
+ if (wifiState == WifiManager.WIFI_STATE_UNKNOWN
+ || wifiState == WifiManager.WIFI_STATE_DISABLED) {
+ mClientModeCallback = null;
+ }
+ }
+
final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState);
@@ -3373,20 +3270,22 @@ public class WifiStateMachine extends StateMachine {
}
/**
- * Handle the error case where our underlying interface went down (if we do not have mac
- * randomization enabled (b/72459123).
+ * Helper method to check if Connected MAC Randomization is enabled - onDown events are skipped
+ * if this feature is enabled (b/72459123).
*
- * This method triggers SelfRecovery with the error of REASON_STA_IFACE_DOWN. SelfRecovery then
- * decides if wifi should be restarted or disabled.
+ * @return boolean true if Connected MAC randomization is enabled, false otherwise
*/
- private void handleInterfaceDown() {
- if (mEnableConnectedMacRandomization.get()) {
- // interface will go down when mac randomization is active, skip
- Log.d(TAG, "MacRandomization enabled, ignoring iface down");
- return;
- }
+ public boolean isConnectedMacRandomizationEnabled() {
+ return mEnableConnectedMacRandomization.get();
+ }
- Log.e(TAG, "Detected an interface down, report failure to SelfRecovery");
+ /**
+ * Helper method allowing ClientModeManager to report an error (interface went down) and trigger
+ * recovery.
+ *
+ * @param reason int indicating the SelfRecovery failure type.
+ */
+ public void failureDetected(int reason) {
// report a failure
mWifiInjector.getSelfRecovery().trigger(SelfRecovery.REASON_STA_IFACE_DOWN);
}
@@ -3497,11 +3396,6 @@ public class WifiStateMachine extends StateMachine {
case CMD_SCREEN_STATE_CHANGED:
handleScreenStateChanged(message.arg1 != 0);
break;
- case CMD_START_SUPPLICANT:
- case CMD_STOP_SUPPLICANT:
- case CMD_START_AP_FAILURE:
- case CMD_STOP_AP:
- case CMD_AP_STOPPED:
case CMD_DISCONNECT:
case CMD_RECONNECT:
case CMD_REASSOCIATE:
@@ -3530,15 +3424,8 @@ public class WifiStateMachine extends StateMachine {
case CMD_DISABLE_P2P_WATCHDOG_TIMER:
case CMD_DISABLE_EPHEMERAL_NETWORK:
case CMD_SELECT_TX_POWER_SCENARIO:
- case CMD_WIFINATIVE_FAILURE:
- case CMD_INTERFACE_DESTROYED:
- case CMD_INTERFACE_DOWN:
- case CMD_INTERFACE_STATUS_CHANGED:
messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
break;
- case CMD_START_AP:
- transitionTo(mSoftApState);
- break;
case CMD_SET_OPERATIONAL_MODE:
mOperationalMode = message.arg1;
// now processing the mode change - we will start setting up new state and want
@@ -3549,10 +3436,7 @@ public class WifiStateMachine extends StateMachine {
transitionTo(mDefaultState);
break;
} else if (mOperationalMode == CONNECT_MODE) {
- transitionTo(mInitialState);
- } else if (mOperationalMode == SCAN_ONLY_MODE
- || mOperationalMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
- transitionTo(mScanModeState);
+ transitionTo(mDisconnectedState);
} else {
Log.e(TAG, "set operational mode with invalid mode: " + mOperationalMode);
mOperationalMode = DISABLED_MODE;
@@ -3721,337 +3605,6 @@ public class WifiStateMachine extends StateMachine {
}
}
- class InitialState extends State {
- private boolean mIfaceIsUp;
-
- private void onUpChanged(boolean isUp) {
- if (isUp == mIfaceIsUp) {
- return; // no change
- }
- mIfaceIsUp = isUp;
- if (isUp) {
- Log.d(TAG, "Client mode interface is up");
- // for now, do nothing - client mode has never waited for iface up
- } else {
- // A driver/firmware hang can now put the interface in a down state.
- // We detect the interface going down and recover from it
- handleInterfaceDown();
- }
- }
-
- private void cleanup() {
- // tell scanning service that scans are not available - about to kill the interface and
- // supplicant
- sendWifiScanAvailable(false);
-
- mWifiNative.registerStatusListener(mWifiNativeStatusListener);
- // TODO: This teardown should ideally be handled in STOP_SUPPLICANT to be consistent
- // with other mode managers. But, client mode is not yet controlled by
- // WifiStateMachinePrime.
- // TODO: Remove this big hammer. We cannot support concurrent interfaces with this!
- mWifiNative.teardownAllInterfaces();
- mInterfaceName = null;
- mIfaceIsUp = false;
- }
-
- @Override
- public void enter() {
- mIfaceIsUp = false;
- mWifiStateTracker.updateState(WifiStateTracker.INVALID);
- cleanup();
- sendMessage(CMD_START_SUPPLICANT);
- setWifiState(WIFI_STATE_ENABLING);
- }
-
- @Override
- public boolean processMessage(Message message) {
- logStateAndMessage(message, this);
- switch (message.what) {
- case CMD_START_SUPPLICANT:
- mInterfaceName = mWifiNative.setupInterfaceForClientMode(false,
- mWifiNativeInterfaceCallback);
- if (TextUtils.isEmpty(mInterfaceName)) {
- Log.e(TAG, "setup failure when creating client interface.");
- setWifiState(WifiManager.WIFI_STATE_UNKNOWN);
- transitionTo(mDefaultState);
- break;
- }
- // now that we have the interface, initialize our up/down status
- onUpChanged(mWifiNative.isInterfaceUp(mInterfaceName));
-
- mIpClient = mFacade.makeIpClient(
- mContext, mInterfaceName, new IpClientCallback());
- mIpClient.setMulticastFilter(true);
- if (mVerboseLoggingEnabled) log("Supplicant start successful");
- registerForWifiMonitorEvents();
- mWifiInjector.getWifiLastResortWatchdog().clearAllFailureCounts();
- setSupplicantLogLevel();
- transitionTo(mSupplicantStartedState);
- break;
- case CMD_SET_OPERATIONAL_MODE:
- if (message.arg1 == CONNECT_MODE) {
- break;
- } else {
- return NOT_HANDLED;
- }
- case CMD_WIFINATIVE_FAILURE:
- Log.e(TAG, "One of the native daemons died unexpectedly. Triggering recovery");
- mWifiDiagnostics.captureBugReportData(
- WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE);
- mWifiInjector.getSelfRecovery().trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE);
- break;
- case CMD_INTERFACE_STATUS_CHANGED:
- boolean isUp = message.arg1 == 1;
- // For now, this message can be triggered due to link state and/or interface
- // status changes (b/77218676). First check if we really see an iface down by
- // consulting our view of supplicant state.
- if (!isUp && SupplicantState.isDriverActive(mWifiInfo.getSupplicantState())) {
- // the driver is active, so this could just be part of normal operation, do
- // not disable wifi in these cases (ex, a network was removed) or worry
- // about the link status
- break;
- }
-
- onUpChanged(isUp);
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
- }
-
- class SupplicantStartedState extends State {
- @Override
- public void enter() {
- if (mVerboseLoggingEnabled) {
- logd("SupplicantStartedState enter");
- }
-
- // reset state related to supplicant starting
- mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
- // Initialize data structures
- mLastBssid = null;
- mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
- mLastSignalLevel = -1;
- mWifiInfo.setMacAddress(mWifiNative.getMacAddress(mInterfaceName));
- // Attempt to migrate data out of legacy store.
- if (!mWifiConfigManager.migrateFromLegacyStore()) {
- Log.e(TAG, "Failed to migrate from legacy config store");
- }
- sendSupplicantConnectionChangedBroadcast(true);
-
- mWifiNative.setExternalSim(mInterfaceName, true);
-
- setRandomMacOui();
- mCountryCode.setReadyForChange(true);
-
- if (mWifiConnectivityManager == null) {
- synchronized (mWifiReqCountLock) {
- mWifiConnectivityManager =
- mWifiInjector.makeWifiConnectivityManager(mWifiInfo,
- hasConnectionRequests());
- mWifiConnectivityManager.setUntrustedConnectionAllowed(mUntrustedReqCount > 0);
- mWifiConnectivityManager.handleScreenStateChanged(mScreenOn);
- }
- }
-
- mWifiDiagnostics.startLogging(mVerboseLoggingEnabled);
- mIsRunning = true;
- updateBatteryWorkSource(null);
- /**
- * Enable bluetooth coexistence scan mode when bluetooth connection is active.
- * When this mode is on, some of the low-level scan parameters used by the
- * driver are changed to reduce interference with bluetooth
- */
- mWifiNative.setBluetoothCoexistenceScanMode(mInterfaceName, mBluetoothConnectionActive);
- // Check if there is a voice call on-going and set/reset the tx power limit
- // appropriately.
- if (mEnableVoiceCallSarTxPowerLimit) {
- if (getTelephonyManager().isOffhook()) {
- sendMessage(CMD_SELECT_TX_POWER_SCENARIO,
- WifiNative.TX_POWER_SCENARIO_VOICE_CALL);
- } else {
- sendMessage(CMD_SELECT_TX_POWER_SCENARIO,
- WifiNative.TX_POWER_SCENARIO_NORMAL);
- }
- }
-
- // initialize network state
- setNetworkDetailedState(DetailedState.DISCONNECTED);
-
- // Disable legacy multicast filtering, which on some chipsets defaults to enabled.
- // Legacy IPv6 multicast filtering blocks ICMPv6 router advertisements which breaks IPv6
- // provisioning. Legacy IPv4 multicast filtering may be re-enabled later via
- // IpClient.Callback.setFallbackMulticastFilter()
- mWifiNative.stopFilteringMulticastV4Packets(mInterfaceName);
- mWifiNative.stopFilteringMulticastV6Packets(mInterfaceName);
-
- // Transitioning to Disconnected state will trigger a scan and subsequently AutoJoin
- transitionTo(mDisconnectedState);
-
- // Set the right suspend mode settings
- mWifiNative.setSuspendOptimizations(mInterfaceName, mSuspendOptNeedsDisabled == 0
- && mUserWantsSuspendOpt.get());
-
- mWifiNative.setPowerSave(mInterfaceName, true);
-
- if (mP2pSupported) {
- p2pSendMessage(WifiStateMachine.CMD_ENABLE_P2P);
- }
-
- // Disable wpa_supplicant from auto reconnecting.
- mWifiNative.enableStaAutoReconnect(mInterfaceName, false);
- // STA has higher priority over P2P
- mWifiNative.setConcurrencyPriority(true);
- }
-
- @Override
- public boolean processMessage(Message message) {
- logStateAndMessage(message, this);
-
- switch(message.what) {
- case CMD_TARGET_BSSID:
- // Trying to associate to this BSSID
- if (message.obj != null) {
- mTargetRoamBSSID = (String) message.obj;
- }
- break;
- case CMD_GET_LINK_LAYER_STATS:
- WifiLinkLayerStats stats = getWifiLinkLayerStats();
- replyToMessage(message, message.what, stats);
- break;
- case CMD_RESET_SIM_NETWORKS:
- log("resetting EAP-SIM/AKA/AKA' networks since SIM was changed");
- mWifiConfigManager.resetSimNetworks(message.arg1 == 1);
- break;
- case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
- mBluetoothConnectionActive = (message.arg1 !=
- BluetoothAdapter.STATE_DISCONNECTED);
- mWifiNative.setBluetoothCoexistenceScanMode(
- mInterfaceName, mBluetoothConnectionActive);
- break;
- case CMD_SET_SUSPEND_OPT_ENABLED:
- if (message.arg1 == 1) {
- setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, true);
- if (message.arg2 == 1) {
- mSuspendWakeLock.release();
- }
- } else {
- setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, false);
- }
- break;
- case CMD_SET_HIGH_PERF_MODE:
- if (message.arg1 == 1) {
- setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, false);
- } else {
- setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, true);
- }
- break;
- case CMD_ENABLE_TDLS:
- if (message.obj != null) {
- String remoteAddress = (String) message.obj;
- boolean enable = (message.arg1 == 1);
- mWifiNative.startTdls(mInterfaceName, remoteAddress, enable);
- }
- break;
- case WifiMonitor.ANQP_DONE_EVENT:
- // TODO(zqiu): remove this when switch over to wificond for ANQP requests.
- mPasspointManager.notifyANQPDone((AnqpEvent) message.obj);
- break;
- case CMD_STOP_IP_PACKET_OFFLOAD: {
- int slot = message.arg1;
- int ret = stopWifiIPPacketOffload(slot);
- if (mNetworkAgent != null) {
- mNetworkAgent.onPacketKeepaliveEvent(slot, ret);
- }
- break;
- }
- case WifiMonitor.RX_HS20_ANQP_ICON_EVENT:
- // TODO(zqiu): remove this when switch over to wificond for icon requests.
- mPasspointManager.notifyIconDone((IconEvent) message.obj);
- break;
- case WifiMonitor.HS20_REMEDIATION_EVENT:
- // TODO(zqiu): remove this when switch over to wificond for WNM frames
- // monitoring.
- mPasspointManager.receivedWnmFrame((WnmData) message.obj);
- break;
- case CMD_CONFIG_ND_OFFLOAD:
- final boolean enabled = (message.arg1 > 0);
- mWifiNative.configureNeighborDiscoveryOffload(mInterfaceName, enabled);
- break;
- case CMD_ENABLE_WIFI_CONNECTIVITY_MANAGER:
- mWifiConnectivityManager.enable(message.arg1 == 1 ? true : false);
- break;
- case CMD_SELECT_TX_POWER_SCENARIO:
- int txPowerScenario = message.arg1;
- logd("Setting Tx power scenario to " + txPowerScenario);
- if (!mWifiNative.selectTxPowerScenario(txPowerScenario)) {
- loge("Failed to set TX power scenario");
- }
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
-
- @Override
- public void exit() {
- setWifiState(WIFI_STATE_DISABLING);
- // when client mode is moved to WSMP, cleanup will be done on exit. For now, cleanup is
- // done when entering a mode.
-
- // exiting supplicant started state is now only applicable to client mode
- mWifiDiagnostics.stopLogging();
-
- if (mP2pSupported) {
- // we are not going to wait for a response - will still temporarily send the
- // disable command until p2p can detect the interface up/down on its own.
- p2pSendMessage(WifiStateMachine.CMD_DISABLE_P2P_REQ);
- }
-
- handleNetworkDisconnect();
-
- mIsRunning = false;
- updateBatteryWorkSource(null);
-
- mNetworkInfo.setIsAvailable(false);
- if (mNetworkAgent != null) mNetworkAgent.sendNetworkInfo(mNetworkInfo);
- mCountryCode.setReadyForChange(false);
- setWifiState(WIFI_STATE_DISABLED);
- }
- }
-
- class ScanModeState extends State {
- private int mLastOperationMode;
- @Override
- public void enter() {
- logd("entering ScanModeState");
- mWifiStateTracker.updateState(WifiStateTracker.SCAN_MODE);
- }
-
- @Override
- public void exit() {}
-
- @Override
- public boolean processMessage(Message message) {
- logStateAndMessage(message, this);
-
- if (message.what == CMD_SET_OPERATIONAL_MODE) {
- int operationMode = message.arg1;
- if (operationMode == SCAN_ONLY_MODE
- || operationMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
- // nothing to do, stay here...
- return HANDLED;
- }
- return NOT_HANDLED;
- }
- return NOT_HANDLED;
- }
- }
-
-
String smToString(Message message) {
return smToString(message.what);
}
@@ -4141,6 +3694,113 @@ public class WifiStateMachine extends StateMachine {
return s;
}
+ /**
+ * Helper method to start other services and get state ready for client mode
+ */
+ private void setupClientMode() {
+ mWifiStateTracker.updateState(WifiStateTracker.INVALID);
+
+ if (mWifiConnectivityManager == null) {
+ synchronized (mWifiReqCountLock) {
+ mWifiConnectivityManager =
+ mWifiInjector.makeWifiConnectivityManager(mWifiInfo,
+ hasConnectionRequests());
+ mWifiConnectivityManager.setUntrustedConnectionAllowed(mUntrustedReqCount > 0);
+ mWifiConnectivityManager.handleScreenStateChanged(mScreenOn);
+ }
+ }
+
+ mIpClient = mFacade.makeIpClient(mContext, mInterfaceName, new IpClientCallback());
+ mIpClient.setMulticastFilter(true);
+ registerForWifiMonitorEvents();
+ mWifiInjector.getWifiLastResortWatchdog().clearAllFailureCounts();
+ setSupplicantLogLevel();
+
+ // reset state related to supplicant starting
+ mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
+ // Initialize data structures
+ mLastBssid = null;
+ mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
+ mLastSignalLevel = -1;
+ mWifiInfo.setMacAddress(mWifiNative.getMacAddress(mInterfaceName));
+ // Attempt to migrate data out of legacy store.
+ if (!mWifiConfigManager.migrateFromLegacyStore()) {
+ Log.e(TAG, "Failed to migrate from legacy config store");
+ }
+ sendSupplicantConnectionChangedBroadcast(true);
+
+ mWifiNative.setExternalSim(mInterfaceName, true);
+
+ setRandomMacOui();
+ mCountryCode.setReadyForChange(true);
+
+ mWifiDiagnostics.startLogging(mVerboseLoggingEnabled);
+ mIsRunning = true;
+ updateBatteryWorkSource(null);
+
+ /**
+ * Enable bluetooth coexistence scan mode when bluetooth connection is active.
+ * When this mode is on, some of the low-level scan parameters used by the
+ * driver are changed to reduce interference with bluetooth
+ */
+ mWifiNative.setBluetoothCoexistenceScanMode(mInterfaceName, mBluetoothConnectionActive);
+ // Check if there is a voice call on-going and set/reset the tx power limit appropriately.
+ if (mEnableVoiceCallSarTxPowerLimit) {
+ if (getTelephonyManager().isOffhook()) {
+ sendMessage(CMD_SELECT_TX_POWER_SCENARIO, WifiNative.TX_POWER_SCENARIO_VOICE_CALL);
+ } else {
+ sendMessage(CMD_SELECT_TX_POWER_SCENARIO, WifiNative.TX_POWER_SCENARIO_NORMAL);
+ }
+ }
+
+ // initialize network state
+ setNetworkDetailedState(DetailedState.DISCONNECTED);
+
+ // Disable legacy multicast filtering, which on some chipsets defaults to enabled.
+ // Legacy IPv6 multicast filtering blocks ICMPv6 router advertisements which breaks IPv6
+ // provisioning. Legacy IPv4 multicast filtering may be re-enabled later via
+ // IpClient.Callback.setFallbackMulticastFilter()
+ mWifiNative.stopFilteringMulticastV4Packets(mInterfaceName);
+ mWifiNative.stopFilteringMulticastV6Packets(mInterfaceName);
+
+ // Set the right suspend mode settings
+ mWifiNative.setSuspendOptimizations(mInterfaceName, mSuspendOptNeedsDisabled == 0
+ && mUserWantsSuspendOpt.get());
+
+ mWifiNative.setPowerSave(mInterfaceName, true);
+
+ if (mP2pSupported) {
+ p2pSendMessage(WifiStateMachine.CMD_ENABLE_P2P);
+ }
+
+ // Disable wpa_supplicant from auto reconnecting.
+ mWifiNative.enableStaAutoReconnect(mInterfaceName, false);
+ // STA has higher priority over P2P
+ mWifiNative.setConcurrencyPriority(true);
+ }
+
+ /**
+ * Helper method to stop external services and clean up state from client mode.
+ */
+ private void stopClientMode() {
+ // exiting supplicant started state is now only applicable to client mode
+ mWifiDiagnostics.stopLogging();
+
+ if (mP2pSupported) {
+ // we are not going to wait for a response - will still temporarily send the
+ // disable command until p2p can detect the interface up/down on its own.
+ p2pSendMessage(WifiStateMachine.CMD_DISABLE_P2P_REQ);
+ }
+
+ mIsRunning = false;
+ updateBatteryWorkSource(null);
+
+ mNetworkInfo.setIsAvailable(false);
+ if (mNetworkAgent != null) mNetworkAgent.sendNetworkInfo(mNetworkInfo);
+ mCountryCode.setReadyForChange(false);
+ setWifiState(WIFI_STATE_DISABLED);
+ }
+
void registerConnected() {
if (mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) {
mWifiConfigManager.updateNetworkAfterConnect(mLastNetworkId);
@@ -4201,13 +3861,13 @@ public class WifiStateMachine extends StateMachine {
@Override
public void enter() {
+ setupClientMode();
if (!mWifiNative.removeAllNetworks(mInterfaceName)) {
loge("Failed to remove networks on entering connect mode");
}
mScanRequestProxy.enableScanningForHiddenNetworks(true);
mWifiInfo.reset();
mWifiInfo.setSupplicantState(SupplicantState.DISCONNECTED);
- sendWifiScanAvailable(true);
// Let the system know that wifi is available in client mode.
setWifiState(WIFI_STATE_ENABLED);
@@ -4247,6 +3907,7 @@ public class WifiStateMachine extends StateMachine {
mWifiInfo.reset();
mWifiInfo.setSupplicantState(SupplicantState.DISCONNECTED);
setWifiState(WIFI_STATE_DISABLED);
+ stopClientMode();
}
@Override
@@ -4264,6 +3925,12 @@ public class WifiStateMachine extends StateMachine {
logStateAndMessage(message, this);
switch (message.what) {
+ case CMD_SET_OPERATIONAL_MODE:
+ if (message.arg1 == CONNECT_MODE) {
+ break;
+ } else {
+ return NOT_HANDLED;
+ }
case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
mWifiDiagnostics.captureBugReportData(
WifiDiagnostics.REPORT_REASON_ASSOC_FAILURE);
@@ -4355,18 +4022,6 @@ public class WifiStateMachine extends StateMachine {
mIpClient.confirmConfiguration();
mWifiScoreReport.noteIpCheck();
}
-
- if (!SupplicantState.isDriverActive(state)) {
- // still use supplicant to detect interface down while work to
- // mitigate b/77218676 is in progress
- // note: explicitly using this command to dedup iface down notification
- // paths (onUpChanged filters out duplicate updates)
- sendMessage(CMD_INTERFACE_STATUS_CHANGED, 0);
- if (mVerboseLoggingEnabled) {
- Log.d(TAG, "detected interface down via supplicant");
- }
- }
-
break;
case WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST:
if (message.arg1 == 1) {
@@ -4791,6 +4446,86 @@ public class WifiStateMachine extends StateMachine {
replyToMessage(message, message.what,
mPasspointManager.getAllMatchingWifiConfigs((ScanResult) message.obj));
break;
+ case CMD_TARGET_BSSID:
+ // Trying to associate to this BSSID
+ if (message.obj != null) {
+ mTargetRoamBSSID = (String) message.obj;
+ }
+ break;
+ case CMD_GET_LINK_LAYER_STATS:
+ WifiLinkLayerStats stats = getWifiLinkLayerStats();
+ replyToMessage(message, message.what, stats);
+ break;
+ case CMD_RESET_SIM_NETWORKS:
+ log("resetting EAP-SIM/AKA/AKA' networks since SIM was changed");
+ mWifiConfigManager.resetSimNetworks(message.arg1 == 1);
+ break;
+ case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
+ mBluetoothConnectionActive = (message.arg1
+ != BluetoothAdapter.STATE_DISCONNECTED);
+ mWifiNative.setBluetoothCoexistenceScanMode(
+ mInterfaceName, mBluetoothConnectionActive);
+ break;
+ case CMD_SET_SUSPEND_OPT_ENABLED:
+ if (message.arg1 == 1) {
+ setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, true);
+ if (message.arg2 == 1) {
+ mSuspendWakeLock.release();
+ }
+ } else {
+ setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, false);
+ }
+ break;
+ case CMD_SET_HIGH_PERF_MODE:
+ if (message.arg1 == 1) {
+ setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, false);
+ } else {
+ setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, true);
+ }
+ break;
+ case CMD_ENABLE_TDLS:
+ if (message.obj != null) {
+ String remoteAddress = (String) message.obj;
+ boolean enable = (message.arg1 == 1);
+ mWifiNative.startTdls(mInterfaceName, remoteAddress, enable);
+ }
+ break;
+ case WifiMonitor.ANQP_DONE_EVENT:
+ // TODO(zqiu): remove this when switch over to wificond for ANQP requests.
+ mPasspointManager.notifyANQPDone((AnqpEvent) message.obj);
+ break;
+ case CMD_STOP_IP_PACKET_OFFLOAD: {
+ int slot = message.arg1;
+ int ret = stopWifiIPPacketOffload(slot);
+ if (mNetworkAgent != null) {
+ mNetworkAgent.onPacketKeepaliveEvent(slot, ret);
+ }
+ break;
+ }
+ case WifiMonitor.RX_HS20_ANQP_ICON_EVENT:
+ // TODO(zqiu): remove this when switch over to wificond for icon requests.
+ mPasspointManager.notifyIconDone((IconEvent) message.obj);
+ break;
+ case WifiMonitor.HS20_REMEDIATION_EVENT:
+ // TODO(zqiu): remove this when switch over to wificond for WNM frames
+ // monitoring.
+ mPasspointManager.receivedWnmFrame((WnmData) message.obj);
+ break;
+ case CMD_CONFIG_ND_OFFLOAD:
+ final boolean enabled = (message.arg1 > 0);
+ mWifiNative.configureNeighborDiscoveryOffload(mInterfaceName, enabled);
+ break;
+ case CMD_ENABLE_WIFI_CONNECTIVITY_MANAGER:
+ mWifiConnectivityManager.enable(message.arg1 == 1 ? true : false);
+ break;
+ case CMD_SELECT_TX_POWER_SCENARIO:
+ int txPowerScenario = message.arg1;
+ logd("Setting Tx power scenario to " + txPowerScenario);
+ if (!mWifiNative.selectTxPowerScenario(txPowerScenario)) {
+ loge("Failed to set TX power scenario");
+ }
+ break;
+
default:
return NOT_HANDLED;
}
@@ -5900,115 +5635,6 @@ public class WifiStateMachine extends StateMachine {
}
}
- class SoftApState extends State {
- private SoftApManager mSoftApManager;
- private String mIfaceName;
- private int mMode;
-
- /*
- private class SoftApCallbackImpl implements WifiManager.SoftApCallback {
- @Override
- public void onStateChanged(int state, int reason) {
- if (state == WIFI_AP_STATE_DISABLED) {
- sendMessage(CMD_AP_STOPPED);
- } else if (state == WIFI_AP_STATE_FAILED) {
- sendMessage(CMD_START_AP_FAILURE);
- }
-
- setWifiApState(state, reason, mIfaceName, mMode);
-
- if (mSoftApCallback != null) {
- mSoftApCallback.onStateChanged(state, reason);
- }
- }
-
- @Override
- public void onNumClientsChanged(int numClients) {
- if (mSoftApCallback != null) {
- mSoftApCallback.onNumClientsChanged(numClients);
- }
- }
- }
- */
-
- @Override
- public void enter() {
- final Message message = getCurrentMessage();
- if (message.what != CMD_START_AP) {
- throw new RuntimeException("Illegal transition to SoftApState: " + message);
- }
- /*
- SoftApModeConfiguration config = (SoftApModeConfiguration) message.obj;
- mMode = config.getTargetMode();
-
- IApInterface apInterface = null;
- Pair<Integer, IApInterface> statusAndInterface =
- mWifiNative.setupForSoftApMode(mInterfaceName);
- if (statusAndInterface.first == WifiNative.SETUP_SUCCESS) {
- apInterface = statusAndInterface.second;
- } else {
- incrementMetricsForSetupFailure(statusAndInterface.first);
- }
- if (apInterface == null) {
- setWifiApState(WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL, null, mMode);
- // Transition to InitialState to reset the driver/HAL back to the initial state.
- transitionTo(mInitialState);
- return;
- }
-
- try {
- mIfaceName = apInterface.getInterfaceName();
- } catch (RemoteException e) {
- // Failed to get the interface name. This is not a good sign and we should report
- // a failure and switch back to the initial state to reset the driver and HAL.
- setWifiApState(WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL, null, mMode);
- transitionTo(mInitialState);
- return;
- }
-
- checkAndSetConnectivityInstance();
- mSoftApManager = mWifiInjector.makeSoftApManager(mNwService,
- new SoftApCallbackImpl(),
- config);
- mSoftApManager.start();
- mWifiStateTracker.updateState(WifiStateTracker.SOFT_AP);
- */
- }
-
- @Override
- public void exit() {
- mSoftApManager = null;
- mIfaceName = null;
- mMode = WifiManager.IFACE_IP_MODE_UNSPECIFIED;
- }
-
- @Override
- public boolean processMessage(Message message) {
- logStateAndMessage(message, this);
-
- switch(message.what) {
- case CMD_START_AP:
- /* Ignore start command when it is starting/started. */
- break;
- case CMD_STOP_AP:
- //mSoftApManager.stop();
- transitionTo(mDefaultState);
- break;
- case CMD_START_AP_FAILURE:
- transitionTo(mDefaultState);
- break;
- case CMD_AP_STOPPED:
- transitionTo(mDefaultState);
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
- }
-
/**
* State machine initiated requests can have replyTo set to null indicating
* there are no recepients, we ignore those reply actions.
diff --git a/service/java/com/android/server/wifi/WifiStateMachinePrime.java b/service/java/com/android/server/wifi/WifiStateMachinePrime.java
index 8eb521cbb..fea191614 100644
--- a/service/java/com/android/server/wifi/WifiStateMachinePrime.java
+++ b/service/java/com/android/server/wifi/WifiStateMachinePrime.java
@@ -17,8 +17,11 @@
package com.android.server.wifi;
import android.annotation.NonNull;
+import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
+import android.os.BatteryStats;
+import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
@@ -29,9 +32,7 @@ import com.android.internal.app.IBatteryStats;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
-
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
+import com.android.server.wifi.WifiNative.StatusListener;
/**
* This class provides the implementation for different WiFi operating modes.
@@ -50,11 +51,13 @@ public class WifiStateMachinePrime {
private DefaultModeManager mDefaultModeManager;
private final WifiInjector mWifiInjector;
+ private final Context mContext;
private final Looper mLooper;
+ private final Handler mHandler;
private final WifiNative mWifiNative;
private final IBatteryStats mBatteryStats;
-
- private Queue<SoftApModeConfiguration> mApConfigQueue = new ConcurrentLinkedQueue<>();
+ private final SelfRecovery mSelfRecovery;
+ private BaseWifiDiagnostics mWifiDiagnostics;
// The base for wifi message types
static final int BASE = Protocol.BASE_WIFI;
@@ -91,27 +94,52 @@ public class WifiStateMachinePrime {
// Client mode failed
static final int CMD_CLIENT_MODE_FAILED = BASE + 304;
+ private StatusListener mWifiNativeStatusListener;
+
private WifiManager.SoftApCallback mSoftApCallback;
+ private ScanOnlyModeManager.Listener mScanOnlyCallback;
+ private ClientModeManager.Listener mClientModeCallback;
/**
* Called from WifiServiceImpl to register a callback for notifications from SoftApManager
*/
- public void registerSoftApCallback(WifiManager.SoftApCallback callback) {
+ public void registerSoftApCallback(@NonNull WifiManager.SoftApCallback callback) {
mSoftApCallback = callback;
}
+ /**
+ * Called from WifiController to register a callback for notifications from ScanOnlyModeManager
+ */
+ public void registerScanOnlyCallback(@NonNull ScanOnlyModeManager.Listener callback) {
+ mScanOnlyCallback = callback;
+ }
+
+ /**
+ * Called from WifiController to register a callback for notifications from ClientModeManager
+ */
+ public void registerClientModeCallback(@NonNull ClientModeManager.Listener callback) {
+ mClientModeCallback = callback;
+ }
+
WifiStateMachinePrime(WifiInjector wifiInjector,
+ Context context,
Looper looper,
WifiNative wifiNative,
DefaultModeManager defaultModeManager,
IBatteryStats batteryStats) {
mWifiInjector = wifiInjector;
+ mContext = context;
mLooper = looper;
+ mHandler = new Handler(looper);
mWifiNative = wifiNative;
mActiveModeManagers = new ArraySet();
mDefaultModeManager = defaultModeManager;
mBatteryStats = batteryStats;
+ mSelfRecovery = mWifiInjector.getSelfRecovery();
+ mWifiDiagnostics = mWifiInjector.makeWifiDiagnostics(mWifiNative);
mModeStateMachine = new ModeStateMachine();
+ mWifiNativeStatusListener = new WifiNativeStatusListener();
+ mWifiNative.registerStatusListener(mWifiNativeStatusListener);
}
/**
@@ -143,19 +171,50 @@ public class WifiStateMachinePrime {
* @param wifiConfig SoftApModeConfiguration for the hostapd softap
*/
public void enterSoftAPMode(@NonNull SoftApModeConfiguration wifiConfig) {
- mApConfigQueue.offer(wifiConfig);
- changeMode(ModeStateMachine.CMD_START_SOFT_AP_MODE);
+ mHandler.post(() -> {
+ startSoftAp(wifiConfig);
+ });
}
/**
- * Method to fully disable wifi.
+ * Method to stop soft ap for wifi hotspot.
*
- * This mode will completely shut down wifi and will not perform any network scans.
+ * This method will stop any active softAp mode managers, if there is one.
+ */
+ public void stopSoftAPMode() {
+ mHandler.post(() -> {
+ for (ActiveModeManager manager : mActiveModeManagers) {
+ if (manager instanceof SoftApManager) {
+ Log.d(TAG, "Stopping SoftApModeManager");
+ manager.stop();
+ mActiveModeManagers.remove(manager);
+ }
+ }
+ updateBatteryStatsWifiState(false);
+ });
+ }
+
+ /**
+ * Method to disable wifi in sta/client mode scenarios.
+ *
+ * This mode will stop any client/scan modes and will not perform any network scans.
*/
public void disableWifi() {
changeMode(ModeStateMachine.CMD_DISABLE_WIFI);
}
+ /**
+ * Method to stop all active modes, for example, when toggling airplane mode.
+ */
+ public void shutdownWifi() {
+ mHandler.post(() -> {
+ for (ActiveModeManager manager : mActiveModeManagers) {
+ manager.stop();
+ }
+ updateBatteryStatsWifiState(false);
+ });
+ }
+
protected String getCurrentMode() {
return mModeStateMachine.getCurrentMode();
}
@@ -164,27 +223,38 @@ public class WifiStateMachinePrime {
mModeStateMachine.sendMessage(newMode);
}
+ /**
+ * Helper class to wrap the ActiveModeManager callback objects.
+ */
+ private class ModeCallback {
+ ActiveModeManager mActiveManager;
+
+ void setActiveModeManager(ActiveModeManager manager) {
+ mActiveManager = manager;
+ }
+
+ ActiveModeManager getActiveModeManager() {
+ return mActiveManager;
+ }
+ }
+
private class ModeStateMachine extends StateMachine {
- // Commands for the state machine.
+ // Commands for the state machine - these will be removed,
+ // along with the StateMachine itself
public static final int CMD_START_CLIENT_MODE = 0;
public static final int CMD_START_SCAN_ONLY_MODE = 1;
- public static final int CMD_START_SOFT_AP_MODE = 2;
public static final int CMD_DISABLE_WIFI = 3;
private final State mWifiDisabledState = new WifiDisabledState();
private final State mClientModeActiveState = new ClientModeActiveState();
private final State mScanOnlyModeActiveState = new ScanOnlyModeActiveState();
- private final State mSoftAPModeActiveState = new SoftAPModeActiveState();
ModeStateMachine() {
super(TAG, mLooper);
- // CHECKSTYLE:OFF IndentationCheck
addState(mClientModeActiveState);
addState(mScanOnlyModeActiveState);
- addState(mSoftAPModeActiveState);
addState(mWifiDisabledState);
- // CHECKSTYLE:ON IndentationCheck
Log.d(TAG, "Starting Wifi in WifiDisabledState");
setInitialState(mWifiDisabledState);
@@ -205,10 +275,6 @@ public class WifiStateMachinePrime {
Log.d(TAG, "Switching from " + getCurrentMode() + " to ScanOnlyMode");
mModeStateMachine.transitionTo(mScanOnlyModeActiveState);
break;
- case ModeStateMachine.CMD_START_SOFT_AP_MODE:
- Log.d(TAG, "Switching from " + getCurrentMode() + " to SoftApMode");
- mModeStateMachine.transitionTo(mSoftAPModeActiveState);
- break;
case ModeStateMachine.CMD_DISABLE_WIFI:
Log.d(TAG, "Switching from " + getCurrentMode() + " to WifiDisabled");
mModeStateMachine.transitionTo(mWifiDisabledState);
@@ -219,11 +285,6 @@ public class WifiStateMachinePrime {
return HANDLED;
}
- private void cleanup() {
- // TODO: Remove this big hammer. We cannot support concurrent interfaces with this!
- mWifiNative.teardownAllInterfaces();
- }
-
class ModeActiveState extends State {
ActiveModeManager mManager;
@Override
@@ -249,8 +310,7 @@ public class WifiStateMachinePrime {
@Override
public void enter() {
Log.d(TAG, "Entering WifiDisabledState");
- // make sure everything is torn down - remove when client mode is moved here
- cleanup();
+ mDefaultModeManager.sendScanAvailableBroadcast(mContext, false);
}
@Override
@@ -294,23 +354,13 @@ public class WifiStateMachinePrime {
Log.d(TAG, "Entering ClientModeActiveState");
mManager = mWifiInjector.makeClientModeManager(new ClientListener());
- // DO NOT CALL START YET
- // mActiveModemanager.start();
+ mManager.start();
mActiveModeManagers.add(mManager);
updateBatteryStatsWifiState(true);
}
@Override
- public void exit() {
- Log.d(TAG, "Exiting ClientModeActiveState");
-
- // OVERRIDE exit() SO WE DO NOT CALL STOP (but we do need to report wifi off)
-
- updateBatteryStatsWifiState(false);
- }
-
- @Override
public boolean processMessage(Message message) {
if (checkForAndHandleModeChange(message)) {
return HANDLED;
@@ -323,11 +373,12 @@ public class WifiStateMachinePrime {
private class ScanOnlyListener implements ScanOnlyModeManager.Listener {
@Override
public void onStateChanged(int state) {
- Log.d(TAG, "State changed from scan only mode.");
if (state == WifiManager.WIFI_STATE_UNKNOWN) {
+ Log.d(TAG, "ScanOnlyMode mode failed");
// error while setting up scan mode or an unexpected failure.
mModeStateMachine.sendMessage(CMD_SCAN_ONLY_MODE_FAILED);
} else if (state == WifiManager.WIFI_STATE_DISABLED) {
+ Log.d(TAG, "ScanOnlyMode stopped");
//scan only mode stopped
mModeStateMachine.sendMessage(CMD_SCAN_ONLY_MODE_STOPPED);
} else if (state == WifiManager.WIFI_STATE_ENABLED) {
@@ -343,13 +394,12 @@ public class WifiStateMachinePrime {
public void enter() {
Log.d(TAG, "Entering ScanOnlyModeActiveState");
- // make sure everything is torn down - remove when client mode is moved here
- cleanup();
-
mManager = mWifiInjector.makeScanOnlyModeManager(new ScanOnlyListener());
mManager.start();
mActiveModeManagers.add(mManager);
+
updateBatteryStatsWifiState(true);
+ updateBatteryStatsScanModeActive();
}
@Override
@@ -364,10 +414,14 @@ public class WifiStateMachinePrime {
break;
case CMD_SCAN_ONLY_MODE_FAILED:
Log.d(TAG, "ScanOnlyMode failed, return to WifiDisabledState.");
+ // notify WifiController that ScanOnlyMode failed
+ mScanOnlyCallback.onStateChanged(WifiManager.WIFI_STATE_UNKNOWN);
mModeStateMachine.transitionTo(mWifiDisabledState);
break;
case CMD_SCAN_ONLY_MODE_STOPPED:
Log.d(TAG, "ScanOnlyMode stopped, return to WifiDisabledState.");
+ // notify WifiController that ScanOnlyMode stopped
+ mScanOnlyCallback.onStateChanged(WifiManager.WIFI_STATE_DISABLED);
mModeStateMachine.transitionTo(mWifiDisabledState);
break;
default:
@@ -376,101 +430,100 @@ public class WifiStateMachinePrime {
return HANDLED;
}
}
+ } // class ModeStateMachine
- class SoftAPModeActiveState extends ModeActiveState {
- private class SoftApCallbackImpl implements WifiManager.SoftApCallback {
- @Override
- public void onStateChanged(int state, int reason) {
- if (state == WifiManager.WIFI_AP_STATE_DISABLED) {
- mModeStateMachine.sendMessage(CMD_AP_STOPPED);
- } else if (state == WifiManager.WIFI_AP_STATE_FAILED) {
- mModeStateMachine.sendMessage(CMD_START_AP_FAILURE);
- }
-
- if (mSoftApCallback != null) {
- mSoftApCallback.onStateChanged(state, reason);
- } else {
- Log.wtf(TAG, "SoftApCallback is null. Dropping StateChanged event.");
- }
- }
+ private class SoftApCallbackImpl extends ModeCallback implements WifiManager.SoftApCallback {
+ @Override
+ public void onStateChanged(int state, int reason) {
+ if (state == WifiManager.WIFI_AP_STATE_DISABLED) {
+ mActiveModeManagers.remove(getActiveModeManager());
+ updateBatteryStatsWifiState(false);
+ } else if (state == WifiManager.WIFI_AP_STATE_FAILED) {
+ mActiveModeManagers.remove(getActiveModeManager());
+ updateBatteryStatsWifiState(false);
+ }
- @Override
- public void onNumClientsChanged(int numClients) {
- if (mSoftApCallback != null) {
- mSoftApCallback.onNumClientsChanged(numClients);
- } else {
- Log.d(TAG, "SoftApCallback is null. Dropping NumClientsChanged event.");
- }
- }
+ if (mSoftApCallback != null) {
+ mSoftApCallback.onStateChanged(state, reason);
}
+ }
- @Override
- public void enter() {
- Log.d(TAG, "Entering SoftApModeActiveState");
-
- // make sure everything is torn down - remove when client mode is moved here
- cleanup();
-
- SoftApModeConfiguration softApModeConfig = mApConfigQueue.poll();
- WifiConfiguration config = softApModeConfig.getWifiConfiguration();
- // TODO (b/67601382): add checks for valid softap configs
- if (config != null && config.SSID != null) {
- Log.d(TAG, "Passing config to SoftApManager! " + config);
- } else {
- config = null;
- }
- mManager = mWifiInjector.makeSoftApManager(
- new SoftApCallbackImpl(), softApModeConfig);
- mManager.start();
- mActiveModeManagers.add(mManager);
- updateBatteryStatsWifiState(true);
+ @Override
+ public void onNumClientsChanged(int numClients) {
+ if (mSoftApCallback != null) {
+ mSoftApCallback.onNumClientsChanged(numClients);
+ } else {
+ Log.d(TAG, "SoftApCallback is null. Dropping NumClientsChanged event.");
}
+ }
+ }
- @Override
- public boolean processMessage(Message message) {
- if (checkForAndHandleModeChange(message)) {
- return HANDLED;
- }
+ private void startSoftAp(SoftApModeConfiguration softapConfig) {
+ Log.d(TAG, "Starting SoftApModeManager");
- switch(message.what) {
- case CMD_START_AP:
- Log.d(TAG, "Received CMD_START_AP when active - invalid message - drop");
- break;
- case CMD_STOP_AP:
- mManager.stop();
- break;
- case CMD_START_AP_FAILURE:
- Log.d(TAG, "Failed to start SoftApMode. Return to WifiDisabledState.");
- mModeStateMachine.transitionTo(mWifiDisabledState);
- break;
- case CMD_AP_STOPPED:
- Log.d(TAG, "SoftApModeActiveState stopped. Return to WifiDisabledState.");
- mModeStateMachine.transitionTo(mWifiDisabledState);
- break;
- default:
- return NOT_HANDLED;
- }
- return HANDLED;
- }
+ WifiConfiguration config = softapConfig.getWifiConfiguration();
+ // TODO (b/67601382): add checks for valid softap configs
+ if (config != null && config.SSID != null) {
+ Log.d(TAG, "Passing config to SoftApManager! " + config);
+ } else {
+ config = null;
}
- } // class ModeStateMachine
+ SoftApCallbackImpl callback = new SoftApCallbackImpl();
+ ActiveModeManager manager = mWifiInjector.makeSoftApManager(callback, softapConfig);
+ callback.setActiveModeManager(manager);
+ manager.start();
+ mActiveModeManagers.add(manager);
+ updateBatteryStatsWifiState(true);
+ }
/**
* Helper method to report wifi state as on/off (doesn't matter which mode).
*
- * @param enabled boolean indicating if wifi is on or off
+ * @param enabled boolean indicating that some mode has been turned on or off
*/
private void updateBatteryStatsWifiState(boolean enabled) {
try {
if (enabled) {
- mBatteryStats.noteWifiOn();
+ if (mActiveModeManagers.size() == 1) {
+ // only report wifi on if we haven't already
+ mBatteryStats.noteWifiOn();
+ }
} else {
- mBatteryStats.noteWifiOff();
+ if (mActiveModeManagers.size() == 0) {
+ // only report if we don't have any active modes
+ mBatteryStats.noteWifiOff();
+ }
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to note battery stats in wifi");
}
}
+ private void updateBatteryStatsScanModeActive() {
+ try {
+ mBatteryStats.noteWifiState(BatteryStats.WIFI_STATE_OFF_SCANNING, null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to note battery stats in wifi");
+ }
+ }
+
+ // callback used to receive callbacks about underlying native failures
+ private final class WifiNativeStatusListener implements StatusListener {
+
+ @Override
+ public void onStatusChanged(boolean isReady) {
+ if (!isReady) {
+ mHandler.post(() -> {
+ Log.e(TAG, "One of the native daemons died. Triggering recovery");
+ mWifiDiagnostics.captureBugReportData(
+ WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE);
+
+ // immediately trigger SelfRecovery if we receive a notice about an
+ // underlying daemon failure
+ mWifiInjector.getSelfRecovery().trigger(SelfRecovery.REASON_WIFINATIVE_FAILURE);
+ });
+ }
+ }
+ };
}
diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java
index 942ff1c8b..25987d305 100644
--- a/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ClientModeManagerTest.java
@@ -64,9 +64,8 @@ public class ClientModeManagerTest {
@Mock ClientModeManager.Listener mListener;
@Mock WifiMonitor mWifiMonitor;
@Mock ScanRequestProxy mScanRequestProxy;
+ @Mock WifiStateMachine mWifiStateMachine;
- final ArgumentCaptor<WifiNative.StatusListener> mStatusListenerCaptor =
- ArgumentCaptor.forClass(WifiNative.StatusListener.class);
final ArgumentCaptor<WifiNative.InterfaceCallback> mInterfaceCallbackCaptor =
ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class);
@@ -81,7 +80,7 @@ public class ClientModeManagerTest {
private ClientModeManager createClientModeManager() {
return new ClientModeManager(mContext, mLooper.getLooper(), mWifiNative, mListener,
- mWifiMetrics, mScanRequestProxy);
+ mWifiMetrics, mScanRequestProxy, mWifiStateMachine);
}
private void startClientModeAndVerifyEnabled() throws Exception {
@@ -92,7 +91,6 @@ public class ClientModeManagerTest {
mClientModeManager.start();
mLooper.dispatchAll();
- verify(mWifiNative).registerStatusListener(mStatusListenerCaptor.capture());
verify(mWifiNative).setupInterfaceForClientMode(
eq(false), mInterfaceCallbackCaptor.capture());
@@ -104,11 +102,12 @@ public class ClientModeManagerTest {
eq(UserHandle.ALL));
List<Intent> intents = intentCaptor.getAllValues();
- assertEquals(3, intents.size());
+ assertEquals(4, intents.size());
Log.d(TAG, "captured intents: " + intents);
checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING, WIFI_STATE_DISABLED);
- checkWifiScanStateChangedBroadcast(intents.get(1), WIFI_STATE_ENABLED);
- checkWifiStateChangedBroadcast(intents.get(2), WIFI_STATE_ENABLED, WIFI_STATE_ENABLING);
+ checkWifiScanStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED);
+ checkWifiScanStateChangedBroadcast(intents.get(2), WIFI_STATE_ENABLED);
+ checkWifiStateChangedBroadcast(intents.get(3), WIFI_STATE_ENABLED, WIFI_STATE_ENABLING);
checkWifiStateChangeListenerUpdate(WIFI_STATE_ENABLED);
verify(mScanRequestProxy, atLeastOnce()).enableScanningForHiddenNetworks(true);
@@ -157,7 +156,7 @@ public class ClientModeManagerTest {
List<Intent> intents = intentCaptor.getAllValues();
assertEquals(3, intents.size());
- checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_DISABLING, WIFI_STATE_ENABLED);
+ checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_DISABLING, WIFI_STATE_UNKNOWN);
checkWifiScanStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED);
checkWifiStateChangedBroadcast(intents.get(2), WIFI_STATE_DISABLED, WIFI_STATE_DISABLING);
checkWifiStateChangeListenerUpdate(WIFI_STATE_DISABLED);
@@ -185,7 +184,10 @@ public class ClientModeManagerTest {
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
eq(UserHandle.ALL));
- checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED);
+ List<Intent> intents = intentCaptor.getAllValues();
+ assertEquals(2, intents.size());
+ checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING, WIFI_STATE_DISABLED);
+ checkWifiStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED, WIFI_STATE_UNKNOWN);
checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
}
@@ -206,7 +208,7 @@ public class ClientModeManagerTest {
List<Intent> intents = intentCaptor.getAllValues();
assertEquals(2, intents.size());
checkWifiStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING, WIFI_STATE_DISABLED);
- checkWifiScanStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED);
+ checkWifiStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED, WIFI_STATE_UNKNOWN);
checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
}
@@ -261,45 +263,29 @@ public class ClientModeManagerTest {
public void clientModeStartedStopsWhenInterfaceDown() throws Exception {
startClientModeAndVerifyEnabled();
reset(mContext, mScanRequestProxy);
+ when(mWifiStateMachine.isConnectedMacRandomizationEnabled()).thenReturn(false);
mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME);
mLooper.dispatchAll();
+ verify(mWifiStateMachine).failureDetected(eq(SelfRecovery.REASON_STA_IFACE_DOWN));
verifyNotificationsForFailure();
}
/**
- * Testing the handling of a wifinative failure status change notification.
- */
- @Test
- public void clientModeStartedStopsOnNativeFailure() throws Exception {
- startClientModeAndVerifyEnabled();
- reset(mContext, mScanRequestProxy, mListener);
- mStatusListenerCaptor.getValue().onStatusChanged(false);
- mLooper.dispatchNext();
-
- checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
-
- mLooper.dispatchAll();
-
- verifyNotificationsForFailure();
- }
-
- /**
- * Testing that handling of a wifinative callback that is not a failuer does not stop client
- * mode.
+ * Triggering interface down when ClientMode is active and Connected MacRandomization is enabled
+ * does not exit the active state.
*/
@Test
- public void clientModeStartedAndStaysUpOnNativeNonFailureCallback() throws Exception {
+ public void clientModeStartedWithConnectedMacRandDoesNotStopWhenInterfaceDown()
+ throws Exception {
startClientModeAndVerifyEnabled();
- reset(mContext, mScanRequestProxy, mListener);
- mStatusListenerCaptor.getValue().onStatusChanged(true);
+ reset(mContext, mScanRequestProxy);
+ when(mWifiStateMachine.isConnectedMacRandomizationEnabled()).thenReturn(true);
+ mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME);
mLooper.dispatchAll();
-
- verify(mListener, never()).onStateChanged(eq(WIFI_STATE_UNKNOWN));
- verify(mListener, never()).onStateChanged(eq(WIFI_STATE_DISABLING));
- verify(mListener, never()).onStateChanged(eq(WIFI_STATE_DISABLED));
+ verify(mWifiStateMachine, never()).failureDetected(eq(SelfRecovery.REASON_STA_IFACE_DOWN));
+ verify(mContext, never()).sendStickyBroadcastAsUser(any(), any());
}
-
/**
* Testing the handling of an interface destroyed notification.
*/
diff --git a/tests/wifitests/src/com/android/server/wifi/ScanOnlyModeManagerTest.java b/tests/wifitests/src/com/android/server/wifi/ScanOnlyModeManagerTest.java
index 2556dfcf4..3d70fa902 100644
--- a/tests/wifitests/src/com/android/server/wifi/ScanOnlyModeManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ScanOnlyModeManagerTest.java
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@@ -48,6 +49,8 @@ import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.List;
+
/**
* Unit tests for {@link ScanOnlyModeManager}.
*/
@@ -69,8 +72,6 @@ public class ScanOnlyModeManagerTest {
@Mock ScanRequestProxy mScanRequestProxy;
@Mock WakeupController mWakeupController;
- final ArgumentCaptor<WifiNative.StatusListener> mStatusListenerCaptor =
- ArgumentCaptor.forClass(WifiNative.StatusListener.class);
final ArgumentCaptor<WifiNative.InterfaceCallback> mInterfaceCallbackCaptor =
ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class);
@@ -94,7 +95,6 @@ public class ScanOnlyModeManagerTest {
mScanOnlyModeManager.start();
mLooper.dispatchAll();
- verify(mWifiNative).registerStatusListener(mStatusListenerCaptor.capture());
verify(mWifiNative).setupInterfaceForClientMode(eq(true),
mInterfaceCallbackCaptor.capture());
@@ -103,10 +103,12 @@ public class ScanOnlyModeManagerTest {
mLooper.dispatchAll();
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext).sendStickyBroadcastAsUser(intentCaptor.capture(),
+ verify(mContext, times(2)).sendStickyBroadcastAsUser(intentCaptor.capture(),
eq(UserHandle.ALL));
+ List<Intent> intents = intentCaptor.getAllValues();
- checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_ENABLED);
+ checkWifiScanStateChangedBroadcast(intents.get(0), WIFI_STATE_DISABLED);
+ checkWifiScanStateChangedBroadcast(intents.get(1), WIFI_STATE_ENABLED);
checkWifiStateChangeListenerUpdate(WIFI_STATE_ENABLED);
verify(mScanRequestProxy, atLeastOnce()).enableScanningForHiddenNetworks(false);
}
@@ -131,37 +133,6 @@ public class ScanOnlyModeManagerTest {
}
/**
- * ScanMode idle state does not crash when a native status update comes before entering the
- * active state.
- */
- @Test
- public void scanModeNativeUpdateBeforeStartDoesNotCrash() throws Exception {
- verify(mWifiNative).registerStatusListener(mStatusListenerCaptor.capture());
-
- mStatusListenerCaptor.getValue().onStatusChanged(false);
- mLooper.dispatchAll();
- verifyNoMoreInteractions(mContext, mListener);
-
- verify(mScanRequestProxy, never()).clearScanResults();
- }
-
- /**
- * ScanMode increments failure metrics when failing to setup client mode.
- */
- @Test
- public void detectAndReportErrorWhenSetupForClientWifiNativeFailure() throws Exception {
- when(mWifiNative.setupInterfaceForClientMode(anyBoolean(), any())).thenReturn(null);
- mScanOnlyModeManager.start();
- mLooper.dispatchAll();
-
- ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
- eq(UserHandle.ALL));
- checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED);
- checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
- }
-
- /**
* ScanMode start does not indicate scanning is available when the interface name is empty.
*/
@Test
@@ -171,10 +142,7 @@ public class ScanOnlyModeManagerTest {
mScanOnlyModeManager.start();
mLooper.dispatchAll();
- ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
- eq(UserHandle.ALL));
- checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED);
+ verify(mContext, never()).sendStickyBroadcastAsUser(any(), eq(UserHandle.ALL));
checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
}
@@ -201,10 +169,7 @@ public class ScanOnlyModeManagerTest {
mLooper.dispatchAll();
// check when interface management it dynamic
//verify(mWifiNative).teardownInterface(TEST_INTERFACE_NAME);
- ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
- eq(UserHandle.ALL));
- checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED);
+ verify(mContext, never()).sendStickyBroadcastAsUser(any(), eq(UserHandle.ALL));
checkWifiStateChangeListenerUpdate(WIFI_STATE_DISABLED);
verify(mScanRequestProxy).clearScanResults();
}
@@ -218,12 +183,7 @@ public class ScanOnlyModeManagerTest {
reset(mContext);
mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME);
mLooper.dispatchAll();
- ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext).sendStickyBroadcastAsUser(intentCaptor.capture(),
- eq(UserHandle.ALL));
- checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED);
- checkWifiStateChangeListenerUpdate(WIFI_STATE_DISABLED);
- verify(mScanRequestProxy).clearScanResults();
+ verify(mContext, never()).sendStickyBroadcastAsUser(any(), eq(UserHandle.ALL));
}
/**
@@ -253,10 +213,7 @@ public class ScanOnlyModeManagerTest {
reset(mContext);
mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME);
mLooper.dispatchAll();
- ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext).sendStickyBroadcastAsUser(intentCaptor.capture(),
- eq(UserHandle.ALL));
- checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED);
+ verify(mContext, never()).sendStickyBroadcastAsUser(any(), eq(UserHandle.ALL));
checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
checkWifiStateChangeListenerUpdate(WIFI_STATE_DISABLED);
verify(mScanRequestProxy).clearScanResults();
@@ -278,41 +235,6 @@ public class ScanOnlyModeManagerTest {
verify(mScanRequestProxy, never()).clearScanResults();
}
-
- /**
- * Testing the handling of a WifiNative failure status change notification.
- */
- @Test
- public void scanModeStartedStopsOnNativeFailure() throws Exception {
- startScanOnlyModeAndVerifyEnabled();
- reset(mContext);
- mStatusListenerCaptor.getValue().onStatusChanged(false);
- mLooper.dispatchAll();
- ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext).sendStickyBroadcastAsUser(intentCaptor.capture(),
- eq(UserHandle.ALL));
-
- checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED);
- checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
- checkWifiStateChangeListenerUpdate(WIFI_STATE_DISABLED);
- verify(mScanRequestProxy).clearScanResults();
- }
-
- /**
- * WifiNative callback that does not indicate failure should not stop Scan mode.
- */
- @Test
- public void scanModeStartedDoesNotStopOnNativeSuccessUpdate() throws Exception {
- startScanOnlyModeAndVerifyEnabled();
- reset(mContext, mListener);
- mStatusListenerCaptor.getValue().onStatusChanged(true);
- mLooper.dispatchAll();
-
- verifyNoMoreInteractions(mContext, mListener);
-
- verify(mScanRequestProxy, never()).clearScanResults();
- }
-
/**
* Entering StartedState starts the WakeupController.
*/
diff --git a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
index e41af6867..bce5e8e94 100644
--- a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -93,8 +93,6 @@ public class SoftApManagerTest {
@Mock FrameworkFacade mFrameworkFacade;
@Mock WifiApConfigStore mWifiApConfigStore;
@Mock WifiMetrics mWifiMetrics;
- final ArgumentCaptor<WifiNative.StatusListener> mWifiNativeStatusListenerCaptor =
- ArgumentCaptor.forClass(WifiNative.StatusListener.class);
final ArgumentCaptor<WifiNative.InterfaceCallback> mWifiNativeInterfaceCallbackCaptor =
ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class);
final ArgumentCaptor<WifiNative.SoftApListener> mSoftApListenerCaptor =
@@ -140,7 +138,6 @@ public class SoftApManagerTest {
config,
mWifiMetrics);
mLooper.dispatchAll();
- verify(mWifiNative).registerStatusListener(mWifiNativeStatusListenerCaptor.capture());
return newSoftApManager;
}
@@ -473,71 +470,6 @@ public class SoftApManagerTest {
}
/**
- * Verify that SoftAp mode shuts down on wifinative failure.
- */
- @Test
- public void handlesWifiNativeFailure() throws Exception {
- SoftApModeConfiguration softApModeConfig =
- new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
- startSoftApAndVerifyEnabled(softApModeConfig);
-
- // reset to clear verified Intents for ap state change updates
- reset(mContext);
-
- mWifiNativeStatusListenerCaptor.getValue().onStatusChanged(false);
- mLooper.dispatchAll();
- InOrder order = inOrder(mCallback);
- order.verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
- ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mContext, times(3)).sendStickyBroadcastAsUser(intentCaptor.capture(),
- eq(UserHandle.ALL));
-
- List<Intent> capturedIntents = intentCaptor.getAllValues();
- checkApStateChangedBroadcast(capturedIntents.get(0), WIFI_AP_STATE_FAILED,
- WIFI_AP_STATE_ENABLED, WifiManager.SAP_START_FAILURE_GENERAL, TEST_INTERFACE_NAME,
- softApModeConfig.getTargetMode());
- checkApStateChangedBroadcast(capturedIntents.get(1), WIFI_AP_STATE_DISABLING,
- WIFI_AP_STATE_FAILED, HOTSPOT_NO_ERROR, TEST_INTERFACE_NAME,
- softApModeConfig.getTargetMode());
- checkApStateChangedBroadcast(capturedIntents.get(2), WIFI_AP_STATE_DISABLED,
- WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR, TEST_INTERFACE_NAME,
- softApModeConfig.getTargetMode());
- }
-
- /**
- * Verify that SoftAp does not crash on wifinative failure before it is started.
- */
- @Test
- public void handlesWifiNativeFailureBeforeStart() throws Exception {
- SoftApModeConfiguration softApModeConfig =
- new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
-
- mSoftApManager = createSoftApManager(softApModeConfig);
-
- mWifiNativeStatusListenerCaptor.getValue().onStatusChanged(false);
- mLooper.dispatchAll();
- }
-
- /**
- * Verify that SoftAp mode does not shut down on wifinative success update.
- */
- @Test
- public void handlesWifiNativeSuccess() throws Exception {
- SoftApModeConfiguration softApModeConfig =
- new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null);
- startSoftApAndVerifyEnabled(softApModeConfig);
-
- // reset to clear verified Intents for ap state change updates
- reset(mContext, mCallback);
-
- mWifiNativeStatusListenerCaptor.getValue().onStatusChanged(true);
- mLooper.dispatchAll();
-
- verifyNoMoreInteractions(mContext, mCallback);
- }
-
- /**
* Verify that onDestroyed properly reports softap stop.
*/
@Test
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java
index 279fb670b..0698eef48 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java
@@ -369,8 +369,8 @@ public class WifiControllerTest {
mWifiController.obtainMessage(CMD_AP_STOPPED).sendToTarget();
mLooper.dispatchAll();
- InOrder inOrder = inOrder(mWifiStateMachine);
- inOrder.verify(mWifiStateMachine).setOperationalMode(WifiStateMachine.CONNECT_MODE);
+ InOrder inOrder = inOrder(mWifiStateMachinePrime);
+ inOrder.verify(mWifiStateMachinePrime).enterClientMode();
assertEquals("DeviceActiveState", getCurrentState().getName());
}
@@ -395,8 +395,8 @@ public class WifiControllerTest {
mWifiController.obtainMessage(CMD_AP_STOPPED).sendToTarget();
mLooper.dispatchAll();
- InOrder inOrder = inOrder(mWifiStateMachine);
- inOrder.verify(mWifiStateMachine).setOperationalMode(WifiStateMachine.CONNECT_MODE);
+ InOrder inOrder = inOrder(mWifiStateMachinePrime);
+ inOrder.verify(mWifiStateMachinePrime).enterClientMode();
assertEquals("DeviceActiveState", getCurrentState().getName());
}
@@ -424,10 +424,10 @@ public class WifiControllerTest {
@Test
public void testRecoveryDisabledTurnsWifiOff() throws Exception {
enableWifi();
- reset(mWifiStateMachine);
+ reset(mWifiStateMachinePrime);
mWifiController.sendMessage(CMD_RECOVERY_DISABLE_WIFI);
mLooper.dispatchAll();
- verify(mWifiStateMachine).setOperationalMode(WifiStateMachine.DISABLED_MODE);
+ verify(mWifiStateMachinePrime).disableWifi();
}
/**
@@ -466,9 +466,11 @@ public class WifiControllerTest {
reset(mWifiStateMachine);
assertEquals("ApStaDisabledState", getCurrentState().getName());
+
+ reset(mWifiStateMachinePrime);
mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI);
mLooper.dispatchAll();
- verifyZeroInteractions(mWifiStateMachine);
+ verify(mWifiStateMachinePrime).disableWifi();
}
/**
@@ -484,9 +486,12 @@ public class WifiControllerTest {
public void testRestartWifiStackInStaDisabledWithScanState() throws Exception {
reset(mWifiStateMachine);
assertEquals("StaDisabledWithScanState", getCurrentState().getName());
+ reset(mWifiStateMachinePrime);
mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI);
mLooper.dispatchAll();
- verifyZeroInteractions(mWifiStateMachine);
+ InOrder inOrder = inOrder(mWifiStateMachinePrime);
+ verify(mWifiStateMachinePrime).disableWifi();
+ verify(mWifiStateMachinePrime).enterScanOnlyMode();
}
/**
@@ -507,8 +512,8 @@ public class WifiControllerTest {
assertEquals("DeviceActiveState", getCurrentState().getName());
mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI);
mLooper.dispatchAll();
- InOrder inOrder = inOrder(mWifiStateMachine);
- inOrder.verify(mWifiStateMachine).setOperationalMode(WifiStateMachine.CONNECT_MODE);
+ InOrder inOrder = inOrder(mWifiStateMachinePrime);
+ inOrder.verify(mWifiStateMachinePrime).enterClientMode();
assertEquals("DeviceActiveState", getCurrentState().getName());
}
@@ -550,10 +555,9 @@ public class WifiControllerTest {
verify(mWifiStateMachinePrime).enterSoftAPMode(any());
assertEquals("ApEnabledState", getCurrentState().getName());
- reset(mWifiStateMachine);
+ reset(mWifiStateMachinePrime);
mWifiController.sendMessage(CMD_RECOVERY_RESTART_WIFI);
mLooper.dispatchAll();
- verifyZeroInteractions(mWifiStateMachine);
- verify(mWifiStateMachinePrime, never()).disableWifi();
+ verify(mWifiStateMachinePrime).disableWifi();
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachinePrimeTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachinePrimeTest.java
index ae8d8cd95..e3775cd68 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachinePrimeTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachinePrimeTest.java
@@ -19,8 +19,10 @@ package com.android.server.wifi;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
+import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
+import android.os.BatteryStats;
import android.os.test.TestLooper;
import android.support.test.filters.SmallTest;
import android.util.Log;
@@ -30,6 +32,7 @@ import com.android.internal.app.IBatteryStats;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
@@ -44,23 +47,33 @@ public class WifiStateMachinePrimeTest {
private static final String CLIENT_MODE_STATE_STRING = "ClientModeActiveState";
private static final String SCAN_ONLY_MODE_STATE_STRING = "ScanOnlyModeActiveState";
- private static final String SOFT_AP_MODE_STATE_STRING = "SoftAPModeActiveState";
private static final String WIFI_DISABLED_STATE_STRING = "WifiDisabledState";
private static final String WIFI_IFACE_NAME = "mockWlan";
@Mock WifiInjector mWifiInjector;
+ @Mock Context mContext;
@Mock WifiNative mWifiNative;
@Mock WifiApConfigStore mWifiApConfigStore;
TestLooper mLooper;
+ @Mock ClientModeManager mClientModeManager;
@Mock ScanOnlyModeManager mScanOnlyModeManager;
@Mock SoftApManager mSoftApManager;
@Mock DefaultModeManager mDefaultModeManager;
@Mock IBatteryStats mBatteryStats;
+ @Mock SelfRecovery mSelfRecovery;
+ @Mock BaseWifiDiagnostics mWifiDiagnostics;
+ ClientModeManager.Listener mClientListener;
ScanOnlyModeManager.Listener mScanOnlyListener;
+ ScanOnlyModeCallback mScanOnlyCallback = new ScanOnlyModeCallback();
+ ClientModeCallback mClientModeCallback = new ClientModeCallback();
WifiManager.SoftApCallback mSoftApManagerCallback;
@Mock WifiManager.SoftApCallback mSoftApStateMachineCallback;
+ WifiNative.StatusListener mWifiNativeStatusListener;
WifiStateMachinePrime mWifiStateMachinePrime;
+ final ArgumentCaptor<WifiNative.StatusListener> mStatusListenerCaptor =
+ ArgumentCaptor.forClass(WifiNative.StatusListener.class);
+
/**
* Set up the test environment.
*/
@@ -71,14 +84,23 @@ public class WifiStateMachinePrimeTest {
MockitoAnnotations.initMocks(this);
mLooper = new TestLooper();
+ when(mWifiInjector.getSelfRecovery()).thenReturn(mSelfRecovery);
+ when(mWifiInjector.makeWifiDiagnostics(eq(mWifiNative))).thenReturn(mWifiDiagnostics);
+
mWifiStateMachinePrime = createWifiStateMachinePrime();
mLooper.dispatchAll();
+ verify(mWifiNative).registerStatusListener(mStatusListenerCaptor.capture());
+ mWifiNativeStatusListener = mStatusListenerCaptor.getValue();
+
mWifiStateMachinePrime.registerSoftApCallback(mSoftApStateMachineCallback);
+ mWifiStateMachinePrime.registerScanOnlyCallback(mScanOnlyCallback);
+ mWifiStateMachinePrime.registerClientModeCallback(mClientModeCallback);
}
private WifiStateMachinePrime createWifiStateMachinePrime() {
return new WifiStateMachinePrime(mWifiInjector,
+ mContext,
mLooper.getLooper(),
mWifiNative,
mDefaultModeManager,
@@ -93,12 +115,54 @@ public class WifiStateMachinePrimeTest {
mWifiStateMachinePrime = null;
}
+ private class ClientModeCallback implements ClientModeManager.Listener {
+ public int currentState = WifiManager.WIFI_STATE_UNKNOWN;
+
+ @Override
+ public void onStateChanged(int state) {
+ currentState = state;
+ }
+ }
+
+ private class ScanOnlyModeCallback implements ScanOnlyModeManager.Listener {
+ public int currentState = WifiManager.WIFI_STATE_UNKNOWN;
+
+ @Override
+ public void onStateChanged(int state) {
+ currentState = state;
+ }
+ }
+
private void enterSoftApActiveMode() throws Exception {
enterSoftApActiveMode(
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null));
}
/**
+ * Helper method to enter the ClientModeActiveState for WifiStateMachinePrime.
+ */
+ private void enterClientModeActiveState() throws Exception {
+ String fromState = mWifiStateMachinePrime.getCurrentMode();
+ doAnswer(
+ new Answer<Object>() {
+ public ClientModeManager answer(InvocationOnMock invocation) {
+ Object[] args = invocation.getArguments();
+ mClientListener = (ClientModeManager.Listener) args[0];
+ return mClientModeManager;
+ }
+ }).when(mWifiInjector).makeClientModeManager(
+ any(ClientModeManager.Listener.class));
+ mWifiStateMachinePrime.enterClientMode();
+ mLooper.dispatchAll();
+ mClientListener.onStateChanged(WifiManager.WIFI_STATE_ENABLED);
+ mLooper.dispatchAll();
+
+ assertEquals(CLIENT_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
+ verify(mClientModeManager).start();
+ verify(mBatteryStats).noteWifiOn();
+ }
+
+ /**
* Helper method to enter the ScanOnlyModeActiveState for WifiStateMachinePrime.
*/
private void enterScanOnlyModeActiveState() throws Exception {
@@ -114,9 +178,13 @@ public class WifiStateMachinePrimeTest {
any(ScanOnlyModeManager.Listener.class));
mWifiStateMachinePrime.enterScanOnlyMode();
mLooper.dispatchAll();
+ mScanOnlyListener.onStateChanged(WifiManager.WIFI_STATE_ENABLED);
+ mLooper.dispatchAll();
+
assertEquals(SCAN_ONLY_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
verify(mScanOnlyModeManager).start();
verify(mBatteryStats).noteWifiOn();
+ verify(mBatteryStats).noteWifiState(eq(BatteryStats.WIFI_STATE_OFF_SCANNING), eq(null));
}
/**
@@ -138,15 +206,10 @@ public class WifiStateMachinePrimeTest {
any());
mWifiStateMachinePrime.enterSoftAPMode(softApConfig);
mLooper.dispatchAll();
- assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
verify(mSoftApManager).start();
- verify(mBatteryStats).noteWifiOn();
- }
-
- private void verifyCleanupCalled() {
- // for now, this is a single call, but make a helper to avoid adding any additional cleanup
- // checks
- verify(mWifiNative).teardownAllInterfaces();
+ if (fromState.equals(WIFI_DISABLED_STATE_STRING)) {
+ verify(mBatteryStats).noteWifiOn();
+ }
}
/**
@@ -154,7 +217,6 @@ public class WifiStateMachinePrimeTest {
*/
@Test
public void testWifiDisabledAtStartup() throws Exception {
- verify(mWifiNative).teardownAllInterfaces();
assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
}
@@ -165,7 +227,6 @@ public class WifiStateMachinePrimeTest {
@Test
public void testEnterScanOnlyModeFromDisabled() throws Exception {
enterScanOnlyModeActiveState();
- verify(mWifiNative, times(2)).teardownAllInterfaces();
}
/**
@@ -175,22 +236,18 @@ public class WifiStateMachinePrimeTest {
@Test
public void testEnterSoftApModeFromDisabled() throws Exception {
enterSoftApActiveMode();
- verify(mWifiNative, times(2)).teardownAllInterfaces();
}
/**
* Test that WifiStateMachinePrime properly enters the SoftApModeActiveState from another state.
- * Expectations: When going from one state to another, cleanup will be called
*/
@Test
public void testEnterSoftApModeFromDifferentState() throws Exception {
- mWifiStateMachinePrime.enterClientMode();
+ enterClientModeActiveState();
mLooper.dispatchAll();
assertEquals(CLIENT_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
reset(mBatteryStats);
enterSoftApActiveMode();
- // still only two times since we do not control the interface yet in client mode
- verify(mWifiNative, times(2)).teardownAllInterfaces();
}
/**
@@ -205,41 +262,22 @@ public class WifiStateMachinePrimeTest {
verify(mScanOnlyModeManager).stop();
verify(mBatteryStats).noteWifiOff();
assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
- verify(mWifiNative, times(3)).teardownAllInterfaces();
}
/**
- * Test that we can disable wifi fully from the SoftApModeActiveState.
+ * Test that we can disable wifi from the SoftApModeActiveState and not impact softap.
*/
@Test
- public void testDisableWifiFromSoftApModeActiveState() throws Exception {
+ public void testDisableWifiFromSoftApModeActiveStateDoesNotStopSoftAp() throws Exception {
enterSoftApActiveMode();
+ reset(mDefaultModeManager);
mWifiStateMachinePrime.disableWifi();
mLooper.dispatchAll();
- verify(mSoftApManager).stop();
- verify(mBatteryStats).noteWifiOff();
+ verify(mSoftApManager, never()).stop();
+ verify(mBatteryStats, never()).noteWifiOff();
+ verify(mDefaultModeManager).sendScanAvailableBroadcast(eq(mContext), eq(false));
assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
- verify(mWifiNative, times(3)).teardownAllInterfaces();
- }
-
- /**
- * Test that we can disable wifi fully from the SoftApModeState.
- */
- @Test
- public void testDisableWifiFromSoftApModeState() throws Exception {
- enterSoftApActiveMode();
- // now inject failure through the SoftApManager.Listener
- mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_FAILED, 0);
- mLooper.dispatchAll();
- assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
-
- mWifiStateMachinePrime.disableWifi();
- mLooper.dispatchAll();
- verify(mBatteryStats).noteWifiOff();
-
- assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
- verify(mWifiNative, times(4)).teardownAllInterfaces();
}
/**
@@ -250,27 +288,28 @@ public class WifiStateMachinePrimeTest {
public void testSwitchModeWhenScanOnlyModeActiveState() throws Exception {
enterScanOnlyModeActiveState();
- mWifiStateMachinePrime.enterClientMode();
+ reset(mBatteryStats);
+ enterClientModeActiveState();
mLooper.dispatchAll();
verify(mScanOnlyModeManager).stop();
assertEquals(CLIENT_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
- verify(mWifiNative, times(2)).teardownAllInterfaces();
}
/**
* Test that we can switch from SoftApActiveMode to another mode.
- * Expectation: When switching out of SoftApModeActiveState we stop the SoftApManager and tear
- * down existing interfaces.
+ * Expectation: When switching out of SoftApModeActiveState we do not impact softap operation
*/
@Test
public void testSwitchModeWhenSoftApActiveMode() throws Exception {
enterSoftApActiveMode();
- mWifiStateMachinePrime.enterClientMode();
+ reset(mWifiNative);
+
+ enterClientModeActiveState();
mLooper.dispatchAll();
- verify(mSoftApManager).stop();
+ verify(mSoftApManager, never()).stop();
assertEquals(CLIENT_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
- verify(mWifiNative, times(2)).teardownAllInterfaces();
+ verify(mWifiNative, never()).teardownAllInterfaces();
}
/**
@@ -290,7 +329,6 @@ public class WifiStateMachinePrimeTest {
reset(mSoftApManager, mBatteryStats);
enterSoftApActiveMode();
- verify(mWifiNative, times(4)).teardownAllInterfaces();
}
/**
@@ -306,8 +344,8 @@ public class WifiStateMachinePrimeTest {
mLooper.dispatchAll();
assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
verify(mScanOnlyModeManager).stop();
- verify(mWifiNative, times(3)).teardownAllInterfaces();
verify(mBatteryStats).noteWifiOff();
+ assertEquals(WifiManager.WIFI_STATE_UNKNOWN, mScanOnlyCallback.currentState);
}
/**
@@ -321,9 +359,6 @@ public class WifiStateMachinePrimeTest {
// now inject failure through the SoftApManager.Listener
mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_FAILED, 0);
mLooper.dispatchAll();
- assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
- verify(mSoftApManager).stop();
- verify(mWifiNative, times(3)).teardownAllInterfaces();
verify(mBatteryStats).noteWifiOff();
}
@@ -340,7 +375,6 @@ public class WifiStateMachinePrimeTest {
mLooper.dispatchAll();
assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
verify(mScanOnlyModeManager).stop();
- verify(mWifiNative, times(3)).teardownAllInterfaces();
verify(mBatteryStats).noteWifiOff();
}
@@ -352,13 +386,12 @@ public class WifiStateMachinePrimeTest {
@Test
public void testSoftApDisabledWhenActive() throws Exception {
enterSoftApActiveMode();
+ reset(mWifiNative);
// now inject failure through the SoftApManager.Listener
mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_FAILED, 0);
mLooper.dispatchAll();
- assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
- verify(mSoftApManager).stop();
- verify(mWifiNative, times(3)).teardownAllInterfaces();
verify(mBatteryStats).noteWifiOff();
+ verifyNoMoreInteractions(mWifiNative);
}
/**
@@ -435,7 +468,6 @@ public class WifiStateMachinePrimeTest {
mLooper.dispatchAll();
assertEquals(SCAN_ONLY_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
verify(mScanOnlyModeManager, never()).stop();
- verify(mWifiNative, times(2)).teardownAllInterfaces();
}
/**
@@ -450,7 +482,6 @@ public class WifiStateMachinePrimeTest {
mLooper.dispatchAll();
assertEquals(SCAN_ONLY_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
verify(mScanOnlyModeManager, never()).stop();
- verify(mWifiNative, times(2)).teardownAllInterfaces();
}
/**
@@ -501,42 +532,53 @@ public class WifiStateMachinePrimeTest {
when(mWifiInjector.makeSoftApManager(any(WifiManager.SoftApCallback.class),
eq(softApConfig1)))
.thenReturn(mSoftApManager);
+ // make a second softap manager
+ SoftApManager softapManager = mock(SoftApManager.class);
when(mWifiInjector.makeSoftApManager(any(WifiManager.SoftApCallback.class),
- eq(softApConfig2)))
- .thenReturn(mSoftApManager);
-
+ eq(softApConfig2)))
+ .thenReturn(softapManager);
mWifiStateMachinePrime.enterSoftAPMode(softApConfig1);
mWifiStateMachinePrime.enterSoftAPMode(softApConfig2);
mLooper.dispatchAll();
- assertEquals(SOFT_AP_MODE_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
- verify(mBatteryStats).noteWifiOff();
+ verify(mSoftApManager).start();
+ verify(softapManager).start();
+ verify(mBatteryStats).noteWifiOn();
}
/**
- * Test that when softap manager reports that softap has stopped, we return to the
- * WifiDisabledState.
+ * Test that we safely disable wifi if it is already disabled.
+ * Expectations: We should not interact with WifiNative since we should have already cleaned up
+ * everything.
*/
@Test
- public void testSoftApStopReturnsToWifiDisabled() throws Exception {
- enterSoftApActiveMode();
+ public void disableWifiWhenAlreadyOff() throws Exception {
+ mWifiStateMachinePrime.disableWifi();
+ // since we start up in disabled, this should not re-enter the disabled state
+ verify(mDefaultModeManager).sendScanAvailableBroadcast(eq(mContext), eq(false));
+ }
- mSoftApManagerCallback.onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
+ /**
+ * Trigger recovery and a bug report if we see a native failure.
+ */
+ @Test
+ public void handleWifiNativeFailure() throws Exception {
+ mWifiNativeStatusListener.onStatusChanged(false);
mLooper.dispatchAll();
- assertEquals(WIFI_DISABLED_STATE_STRING, mWifiStateMachinePrime.getCurrentMode());
- verify(mWifiNative, times(3)).teardownAllInterfaces();
- verify(mBatteryStats).noteWifiOff();
+ verify(mWifiDiagnostics).captureBugReportData(
+ WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE);
+ verify(mSelfRecovery).trigger(eq(SelfRecovery.REASON_WIFINATIVE_FAILURE));
}
/**
- * Test that we safely disable wifi if it is already disabled.
- * Expectations: We should not interact with WifiNative since we should have already cleaned up
- * everything.
+ * Verify an onStatusChanged callback with "true" does not trigger recovery.
*/
@Test
- public void disableWifiWhenAlreadyOff() throws Exception {
- mWifiStateMachinePrime.disableWifi();
- // since we start up in disabled, this should not re-enter the disabled state
- verify(mWifiNative).teardownAllInterfaces();
+ public void handleWifiNativeStatusReady() throws Exception {
+ mWifiNativeStatusListener.onStatusChanged(true);
+ mLooper.dispatchAll();
+ verify(mWifiDiagnostics, never()).captureBugReportData(
+ WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE);
+ verify(mSelfRecovery, never()).trigger(eq(SelfRecovery.REASON_WIFINATIVE_FAILURE));
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
index c90bde3bb..c70a77102 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
@@ -336,9 +336,6 @@ public class WifiStateMachineTest {
OsuProvider mOsuProvider;
ContentObserver mContentObserver;
- final ArgumentCaptor<WifiManager.SoftApCallback> mSoftApCallbackCaptor =
- ArgumentCaptor.forClass(WifiManager.SoftApCallback.class);
-
@Mock WifiScanner mWifiScanner;
@Mock SupplicantStateTracker mSupplicantStateTracker;
@Mock WifiMetrics mWifiMetrics;
@@ -353,7 +350,6 @@ public class WifiStateMachineTest {
@Mock WifiConfigManager mWifiConfigManager;
@Mock WifiNative mWifiNative;
@Mock WifiConnectivityManager mWifiConnectivityManager;
- @Mock SoftApManager mSoftApManager;
@Mock WifiStateTracker mWifiStateTracker;
@Mock PasspointManager mPasspointManager;
@Mock SelfRecovery mSelfRecovery;
@@ -371,8 +367,6 @@ public class WifiStateMachineTest {
@Mock WakeupController mWakeupController;
@Mock ScanRequestProxy mScanRequestProxy;
- final ArgumentCaptor<WifiNative.StatusListener> mStatusListenerCaptor =
- ArgumentCaptor.forClass(WifiNative.StatusListener.class);
final ArgumentCaptor<WifiNative.InterfaceCallback> mInterfaceCallbackCaptor =
ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class);
@@ -568,61 +562,16 @@ public class WifiStateMachineTest {
@Test
public void loadComponentsInStaMode() throws Exception {
startSupplicantAndDispatchMessages();
-
- verify(mContext).sendStickyBroadcastAsUser(
- (Intent) argThat(new WifiEnablingStateIntentMatcher()), eq(UserHandle.ALL));
-
assertEquals("DisconnectedState", getCurrentState().getName());
}
- private void loadComponentsInApMode(int mode) throws Exception {
- SoftApModeConfiguration config = new SoftApModeConfiguration(mode, new WifiConfiguration());
- mWsm.setHostApRunning(config, true);
- mLooper.dispatchAll();
-
- assertEquals("SoftApState", getCurrentState().getName());
-
- verify(mWifiNative, never()).setupInterfaceForSoftApMode(any());
- verify(mSoftApManager, never()).start();
- }
-
- @Test
- public void loadComponentsInApModeForTethering() throws Exception {
- loadComponentsInApMode(WifiManager.IFACE_IP_MODE_TETHERED);
- }
-
- @Test
- public void loadComponentsInApModeForLOHS() throws Exception {
- loadComponentsInApMode(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
- }
-
- @Test
- public void shouldRequireSupplicantStartupToLeaveInitialState() throws Exception {
- when(mWifiNative.setupInterfaceForClientMode(anyBoolean(), any())).thenReturn(null);
- mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE);
- mLooper.dispatchAll();
- assertEquals("DefaultState", getCurrentState().getName());
- // we should be sending a wifi enabling update
- verify(mContext).sendStickyBroadcastAsUser(
- (Intent) argThat(new WifiEnablingStateIntentMatcher()), any());
- }
-
- @Test
- public void loadComponentsFailure() throws Exception {
- when(mWifiNative.setupInterfaceForClientMode(anyBoolean(), any())).thenReturn(null);
-
- mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE);
- mLooper.dispatchAll();
- assertEquals("DefaultState", getCurrentState().getName());
- }
-
@Test
public void checkInitialStateStickyWhenDisabledMode() throws Exception {
mLooper.dispatchAll();
assertEquals("DefaultState", getCurrentState().getName());
assertEquals(WifiStateMachine.DISABLED_MODE, mWsm.getOperationalModeForTest());
- mWsm.setOperationalMode(WifiStateMachine.DISABLED_MODE);
+ mWsm.setOperationalMode(WifiStateMachine.DISABLED_MODE, null);
mLooper.dispatchAll();
assertEquals(WifiStateMachine.DISABLED_MODE, mWsm.getOperationalModeForTest());
assertEquals("DefaultState", getCurrentState().getName());
@@ -636,7 +585,7 @@ public class WifiStateMachineTest {
assertEquals(WifiStateMachine.DISABLED_MODE, mWsm.getOperationalModeForTest());
// But if someone tells us to enter connect mode, we start up supplicant
- mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE);
+ mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE, WIFI_IFACE_NAME);
mLooper.dispatchAll();
assertEquals("DisconnectedState", getCurrentState().getName());
}
@@ -651,43 +600,22 @@ public class WifiStateMachineTest {
assertEquals("DefaultState", getCurrentState().getName());
assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState());
- mWsm.setOperationalMode(WifiStateMachine.SCAN_ONLY_MODE);
- mLooper.dispatchAll();
- assertEquals(WifiStateMachine.SCAN_ONLY_MODE, mWsm.getOperationalModeForTest());
- assertEquals("ScanModeState", getCurrentState().getName());
- assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState());
- verify(mContext, never()).sendStickyBroadcastAsUser(
- (Intent) argThat(new WifiEnablingStateIntentMatcher()), any());
-
// switch to connect mode and verify wifi is reported as enabled
startSupplicantAndDispatchMessages();
assertEquals("DisconnectedState", getCurrentState().getName());
assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest());
assertEquals(WifiManager.WIFI_STATE_ENABLED, mWsm.syncGetWifiState());
- verify(mContext).sendStickyBroadcastAsUser(
- (Intent) argThat(new WifiEnablingStateIntentMatcher()), eq(UserHandle.ALL));
// reset the expectations on mContext since we did get an expected broadcast, but we should
// not on the next transition
reset(mContext);
- // now go back to scan mode with "wifi disabled" to verify the reported wifi state.
- mWsm.setOperationalMode(WifiStateMachine.SCAN_ONLY_WITH_WIFI_OFF_MODE);
+ // now disable wifi and verify the reported wifi state
+ mWsm.setOperationalMode(WifiStateMachine.DISABLED_MODE, null);
mLooper.dispatchAll();
- assertEquals(WifiStateMachine.SCAN_ONLY_WITH_WIFI_OFF_MODE,
- mWsm.getOperationalModeForTest());
- assertEquals("ScanModeState", getCurrentState().getName());
- assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState());
- verify(mContext, never()).sendStickyBroadcastAsUser(
- (Intent) argThat(new WifiEnablingStateIntentMatcher()), any());
-
- // now go to AP mode
- SoftApModeConfiguration config = new SoftApModeConfiguration(
- WifiManager.IFACE_IP_MODE_TETHERED, new WifiConfiguration());
- mWsm.setHostApRunning(config, true);
- mLooper.dispatchAll();
- assertEquals("SoftApState", getCurrentState().getName());
+ assertEquals(WifiStateMachine.DISABLED_MODE, mWsm.getOperationalModeForTest());
+ assertEquals("DefaultState", getCurrentState().getName());
assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState());
verify(mContext, never()).sendStickyBroadcastAsUser(
(Intent) argThat(new WifiEnablingStateIntentMatcher()), any());
@@ -856,14 +784,9 @@ public class WifiStateMachineTest {
* Helper method to move through startup states.
*/
private void startSupplicantAndDispatchMessages() throws Exception {
- mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE);
+ mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE, WIFI_IFACE_NAME);
mLooper.dispatchAll();
- // this will be removed when interface management is dynamic
- verify(mWifiNative, atLeastOnce()).teardownAllInterfaces();
-
- verify(mWifiNative, atLeastOnce())
- .setupInterfaceForClientMode(eq(false), mInterfaceCallbackCaptor.capture());
verify(mWifiLastResortWatchdog, atLeastOnce()).clearAllFailureCounts();
assertEquals("DisconnectedState", getCurrentState().getName());
@@ -1045,7 +968,7 @@ public class WifiStateMachineTest {
public void verifyWifiStateTrackerUpdatedWhenDisabled() throws Exception {
connect();
- mWsm.setOperationalMode(WifiStateMachine.DISABLED_MODE);
+ mWsm.setOperationalMode(WifiStateMachine.DISABLED_MODE, null);
mLooper.dispatchAll();
verify(mWifiStateTracker).updateState(eq(WifiStateTracker.DISCONNECTED));
}
@@ -1712,8 +1635,7 @@ public class WifiStateMachineTest {
* client mode.
*/
@Test
- public void syncStartSubscriptionProvisioningInAPMode() throws Exception {
- loadComponentsInApMode(WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
+ public void syncStartSubscriptionProvisioningNoOpWifiDisabled() throws Exception {
mLooper.startAutoDispatch();
assertEquals(false, mWsm.syncStartSubscriptionProvisioning(
OTHER_USER_UID, mOsuProvider, mProvisioningCallback, mWsmAsyncChannel));
@@ -1783,119 +1705,6 @@ public class WifiStateMachineTest {
}
/**
- * Trigger recovery and a bug report of we see a native failure when Client mode is active.
- */
- @Test
- public void handleWifiNativeFailureWhenClientModeActive() throws Exception {
- // Trigger initialize to capture the death handler registration.
- loadComponentsInStaMode();
-
- verify(mWifiNative).registerStatusListener(mStatusListenerCaptor.capture());
-
- // Now trigger the death notification.
- mStatusListenerCaptor.getValue().onStatusChanged(false);
- mLooper.dispatchAll();
- verify(mSelfRecovery).trigger(eq(SelfRecovery.REASON_WIFINATIVE_FAILURE));
- verify(mWifiDiagnostics).captureBugReportData(
- WifiDiagnostics.REPORT_REASON_WIFINATIVE_FAILURE);
- }
-
- /**
- * WifiNative failures when in a state other than client mode should just be dropped.
- */
- @Test
- public void handleWifiNativeFailureInDefaultDoesNotRestartClientMode() throws Exception {
- // Trigger initialize to capture the death handler registration.
- loadComponentsInStaMode();
- verify(mWifiNative).registerStatusListener(mStatusListenerCaptor.capture());
-
- mWsm.setOperationalMode(WifiStateMachine.SCAN_ONLY_MODE);
- mLooper.dispatchAll();
-
- // Now trigger the death notification.
- mStatusListenerCaptor.getValue().onStatusChanged(false);
- mLooper.dispatchAll();
- verify(mSelfRecovery, never()).trigger(anyInt());
- verify(mWifiDiagnostics, never()).captureBugReportData(anyInt());
- }
-
- /**
- * Test verifying that interface onDown callback triggers SelfRecovery when Supplicant has
- * already reported the driver is not active.
- */
- @Test
- public void testInterfaceOnDownInClientModeTriggersSelfRecovery() throws Exception {
- // Trigger initialize to capture the death handler registration.
- loadComponentsInStaMode();
-
- // make sure we mark the iface up
- mInterfaceCallbackCaptor.getValue().onUp(WIFI_IFACE_NAME);
-
- // make sure supplicant has been reported as inactive
- when(mWifiNative.isInterfaceUp(eq(WIFI_IFACE_NAME))).thenReturn(true);
- mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
- new StateChangeResult(0, WifiSsid.createFromAsciiEncoded(""), null,
- SupplicantState.INTERFACE_DISABLED));
- mLooper.dispatchAll();
-
- // trigger onDown for the client interface
- mInterfaceCallbackCaptor.getValue().onDown(WIFI_IFACE_NAME);
- mLooper.dispatchAll();
-
- // WSM should trigger self recovery, but not disconnect until externally triggered
- verify(mSelfRecovery).trigger(eq(SelfRecovery.REASON_STA_IFACE_DOWN));
- }
-
- /**
- * Test verifying that interface onDown callback does not trigger SelfRecovery when
- * Supplicant reports that the driver is active.
- */
- @Test
- public void testInterfaceOnDownInClientModeDoesNotTriggerSelfRecoveryIfDriverActive()
- throws Exception {
- // Trigger initialize to capture the death handler registration.
- loadComponentsInStaMode();
-
- // make sure we mark the iface up
- mInterfaceCallbackCaptor.getValue().onUp(WIFI_IFACE_NAME);
- mLooper.dispatchAll();
-
- // make sure supplicant has been reported as active
- mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
- new StateChangeResult(0, WifiSsid.createFromAsciiEncoded(""), null,
- SupplicantState.DISCONNECTED));
- mLooper.dispatchAll();
-
- // trigger onDown for the client interface
- mInterfaceCallbackCaptor.getValue().onDown(WIFI_IFACE_NAME);
- mLooper.dispatchAll();
-
- // WSM should trigger self recovery, but not disconnect until externally triggered
- verify(mSelfRecovery, never()).trigger(eq(SelfRecovery.REASON_STA_IFACE_DOWN));
- }
-
- /**
- * Test verifying that Supplicant update for inactive driver does not trigger SelfRecovery
- * when the interface is reported down.
- */
- @Test
- public void testSupplicantUpdateDriverInactiveInClientModeTriggersSelfRecovery()
- throws Exception {
- // Trigger initialize to capture the death handler registration.
- loadComponentsInStaMode();
-
- when(mWifiNative.isInterfaceUp(eq(WIFI_IFACE_NAME))).thenReturn(false);
-
- mWsm.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
- new StateChangeResult(0, WifiSsid.createFromAsciiEncoded(""), null,
- SupplicantState.INTERFACE_DISABLED));
- mLooper.dispatchAll();
-
- // WSM should trigger self recovery, but not disconnect until externally triggered
- verify(mSelfRecovery, never()).trigger(eq(SelfRecovery.REASON_STA_IFACE_DOWN));
- }
-
- /**
* Test verifying that interface Supplicant update for inactive driver does not trigger
* SelfRecovery when WifiNative reports the interface is up.
*/
@@ -1918,47 +1727,6 @@ public class WifiStateMachineTest {
}
/**
- * Test verifying that interface onDown callback does not trigger SelfRecovery when
- * MacRandomization is enabled.
- */
- @Test
- public void testInterfaceOnDownInClientModeDoesNotTriggerSelfRecoveryWithMacRand()
- throws Exception {
- when(mFrameworkFacade.getIntegerSetting(mContext,
- Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED, 0)).thenReturn(1);
- mContentObserver.onChange(false);
-
- // Trigger initialize to capture the death handler registration.
- loadComponentsInStaMode();
-
- // make sure we mark the iface up
- mInterfaceCallbackCaptor.getValue().onUp(WIFI_IFACE_NAME);
- mLooper.dispatchAll();
-
- // trigger onDown for the client interface
- mInterfaceCallbackCaptor.getValue().onDown(WIFI_IFACE_NAME);
- mLooper.dispatchAll();
-
- // WSM should trigger self recovery, but not disconnect until externally triggered
- verify(mSelfRecovery, never()).trigger(eq(SelfRecovery.REASON_STA_IFACE_DOWN));
- }
-
- /**
- * Test verifying that interface onDestroyed callbacks are not currently hooked up.
- */
- @Test
- public void testInterfaceOnDestroyedDoesNotTriggerClientModeShutdown() throws Exception {
- connect();
-
- // trigger onDestroyed for the client interface
- mInterfaceCallbackCaptor.getValue().onDown(WIFI_IFACE_NAME);
- mLooper.dispatchAll();
-
- // since this is not handled yet, should not trigger a disconnect
- assertEquals("ConnectedState", getCurrentState().getName());
- }
-
- /**
* Verifies that WifiInfo is updated upon SUPPLICANT_STATE_CHANGE_EVENT.
*/
@Test
@@ -2052,13 +1820,13 @@ public class WifiStateMachineTest {
assertEquals(sBSSID, wifiInfo.getBSSID());
assertEquals(SupplicantState.COMPLETED, wifiInfo.getSupplicantState());
- // Set WSM to SCAN_ONLY_MODE, verify state and wifi disabled in ConnectivityManager, and
+ // Set WSM to DISABLED_MODE, verify state and wifi disabled in ConnectivityManager, and
// WifiInfo is reset() and state set to DISCONNECTED
- mWsm.setOperationalMode(WifiStateMachine.SCAN_ONLY_MODE);
+ mWsm.setOperationalMode(WifiStateMachine.DISABLED_MODE, null);
mLooper.dispatchAll();
- assertEquals(WifiStateMachine.SCAN_ONLY_MODE, mWsm.getOperationalModeForTest());
- assertEquals("ScanModeState", getCurrentState().getName());
+ assertEquals(WifiStateMachine.DISABLED_MODE, mWsm.getOperationalModeForTest());
+ assertEquals("DefaultState", getCurrentState().getName());
assertEquals(WifiManager.WIFI_STATE_DISABLED, mWsm.syncGetWifiState());
inOrder.verify(mWifiConnectivityManager).setWifiEnabled(eq(false));
assertNull(wifiInfo.getBSSID());