summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorRebecca Silberstein <silberst@google.com>2018-04-18 18:50:16 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2018-04-18 18:50:16 +0000
commit2a78fd6b8dd165346650ed56335b2f0774baa553 (patch)
tree5d91cd72050abbba216d66a9c37bc51e5fe7d95f /service
parent3a48dfd8ab53cf4050a17009afd829e6483369bb (diff)
parent1c5f984de5c482992943b7e5a4869f24b5072d27 (diff)
Merge changes Ieed3609a,I0a9a5241,Ie6857478,I5c1e4378,Id01c9a28, ... into pi-dev
* changes: ClientModeManager: control WifiStateMachine WifiStateMachinePrime: separate softap mode ActiveModeManager: add default scan available bcast WifiStateMachine: remove unused states WifiStateMachine: remove supplicant specific states WifiController: use callbacks instead of bcasts WifiStateMachinePrime: centralize native failure handling
Diffstat (limited to 'service')
-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
8 files changed, 634 insertions, 875 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);
+ });
+ }
+ }
+ };
}