summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorRebecca Silberstein <silberst@google.com>2018-03-21 22:46:41 -0700
committerRebecca Silberstein <silberst@google.com>2018-04-18 09:15:18 -0700
commit28646f4ea232bdaef9e1f8a737b37c84f6aac8d5 (patch)
treee5ff87c4a8183010ec58bf86160ed292030a64a4 /service
parentdd06605ed8c1249718eb881e3ebde3ee6da82eca (diff)
WifiStateMachinePrime: centralize native failure handling
Instead of having each mode listen and react to underlying native daemon failures, centralize the control in WifiStateMachinePrime. Now all modes have the benefit of detection and SelfRecovery (when applicable). Note: Multiple notifications for underlying failures is interfering with recovery, tested with wifi hal death that only sends one callback. Supplicant and wificond failures still trigger multiple callbacks and recovery needs to be verified once those are fixed. Bug: 75989180 Bug: 31346104 Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh Test: triggered wifi hal failures with 'kill' while in all modes, wifi re-entered scan and client modes as appropriate. Change-Id: I2b606b25e463b1f5e152cf6a6ff2a188e5c48d6d
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/ClientModeManager.java61
-rw-r--r--service/java/com/android/server/wifi/ScanOnlyModeManager.java34
-rw-r--r--service/java/com/android/server/wifi/SoftApManager.java47
-rw-r--r--service/java/com/android/server/wifi/WifiController.java29
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java21
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachinePrime.java31
6 files changed, 124 insertions, 99 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeManager.java b/service/java/com/android/server/wifi/ClientModeManager.java
index 14d55de1e..22db07a8f 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;
@@ -46,7 +47,7 @@ public class ClientModeManager implements ActiveModeManager {
private final ScanRequestProxy mScanRequestProxy;
private String mClientInterfaceName;
-
+ private boolean mIfaceIsUp;
ClientModeManager(Context context, @NonNull Looper looper, WifiNative wifiNative,
Listener listener, WifiMetrics wifiMetrics, ScanRequestProxy scanRequestProxy) {
@@ -69,7 +70,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,17 +120,11 @@ 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
@@ -135,8 +143,6 @@ public class ClientModeManager implements ActiveModeManager {
}
};
- private boolean mIfaceIsUp = false;
-
ClientModeStateMachine(Looper looper) {
super(TAG, looper);
@@ -152,8 +158,8 @@ public class ClientModeManager implements ActiveModeManager {
@Override
public void enter() {
Log.d(TAG, "entering IdleState");
- mWifiNative.registerStatusListener(mWifiNativeStatusListener);
mClientInterfaceName = null;
+ mIfaceIsUp = false;
}
@Override
@@ -174,10 +180,6 @@ public class ClientModeManager implements ActiveModeManager {
}
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;
@@ -200,10 +202,10 @@ public class ClientModeManager implements ActiveModeManager {
WifiManager.WIFI_STATE_ENABLING);
} else {
// 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 +223,16 @@ 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.d(TAG, "Interface down! stop mode");
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 +252,18 @@ public class ClientModeManager implements ActiveModeManager {
*/
@Override
public void exit() {
+ if (mClientInterfaceName == null) {
+ return;
+ }
+ 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..3e7f96b1b 100644
--- a/service/java/com/android/server/wifi/ScanOnlyModeManager.java
+++ b/service/java/com/android/server/wifi/ScanOnlyModeManager.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;
@@ -49,7 +50,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 +75,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 +104,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 +111,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 +150,6 @@ public class ScanOnlyModeManager implements ActiveModeManager {
@Override
public void enter() {
Log.d(TAG, "entering IdleState");
- mWifiNative.registerStatusListener(mWifiNativeStatusListener);
mClientInterfaceName = null;
}
@@ -172,10 +167,6 @@ public class ScanOnlyModeManager implements ActiveModeManager {
}
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,10 +209,6 @@ 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.");
transitionTo(mIdleState);
@@ -231,8 +218,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;
@@ -248,8 +234,12 @@ public class ScanOnlyModeManager implements ActiveModeManager {
*/
@Override
public void exit() {
+ if (mClientInterfaceName == null) {
+ return;
+ }
mWakeupController.stop();
- //mWifiNative.teardownInterface(mClientInterfaceName);
+ mWifiNative.teardownInterface(mClientInterfaceName);
+ mClientInterfaceName = null;
// let WifiScanner know that wifi is down.
sendScanAvailableBroadcast(false);
updateWifiState(WifiManager.WIFI_STATE_DISABLED);
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..607d86341 100644
--- a/service/java/com/android/server/wifi/WifiController.java
+++ b/service/java/com/android/server/wifi/WifiController.java
@@ -217,10 +217,15 @@ public class WifiController extends StateMachine {
case CMD_AP_START_FAILURE:
case CMD_AP_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;
@@ -301,7 +306,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;
@@ -563,6 +576,14 @@ public class WifiController extends StateMachine {
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:
return NOT_HANDLED;
}
@@ -605,6 +626,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;
}
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index dbb83609b..c44384f40 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -97,7 +97,6 @@ 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;
@@ -221,12 +220,6 @@ 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) {
@@ -698,9 +691,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;
@@ -3530,7 +3520,6 @@ 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:
@@ -3744,10 +3733,6 @@ public class WifiStateMachine extends StateMachine {
// 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;
@@ -3794,12 +3779,6 @@ public class WifiStateMachine extends StateMachine {
} 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
diff --git a/service/java/com/android/server/wifi/WifiStateMachinePrime.java b/service/java/com/android/server/wifi/WifiStateMachinePrime.java
index 8eb521cbb..8099066e5 100644
--- a/service/java/com/android/server/wifi/WifiStateMachinePrime.java
+++ b/service/java/com/android/server/wifi/WifiStateMachinePrime.java
@@ -19,6 +19,7 @@ package com.android.server.wifi;
import android.annotation.NonNull;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
+import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
@@ -29,6 +30,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 com.android.server.wifi.WifiNative.StatusListener;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -53,6 +55,8 @@ public class WifiStateMachinePrime {
private final Looper mLooper;
private final WifiNative mWifiNative;
private final IBatteryStats mBatteryStats;
+ private final SelfRecovery mSelfRecovery;
+ private BaseWifiDiagnostics mWifiDiagnostics;
private Queue<SoftApModeConfiguration> mApConfigQueue = new ConcurrentLinkedQueue<>();
@@ -91,6 +95,8 @@ public class WifiStateMachinePrime {
// Client mode failed
static final int CMD_CLIENT_MODE_FAILED = BASE + 304;
+ private StatusListener mWifiNativeStatusListener;
+
private WifiManager.SoftApCallback mSoftApCallback;
/**
@@ -111,7 +117,11 @@ public class WifiStateMachinePrime {
mActiveModeManagers = new ArraySet();
mDefaultModeManager = defaultModeManager;
mBatteryStats = batteryStats;
+ mSelfRecovery = mWifiInjector.getSelfRecovery();
+ mWifiDiagnostics = mWifiInjector.makeWifiDiagnostics(mWifiNative);
mModeStateMachine = new ModeStateMachine();
+ mWifiNativeStatusListener = new WifiNativeStatusListener();
+ mWifiNative.registerStatusListener(mWifiNativeStatusListener);
}
/**
@@ -325,9 +335,11 @@ public class WifiStateMachinePrime {
public void onStateChanged(int state) {
Log.d(TAG, "State changed from scan only mode.");
if (state == WifiManager.WIFI_STATE_UNKNOWN) {
+ Log.d(TAG, "ScanOnly 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, "ScanOnly mode stopped");
//scan only mode stopped
mModeStateMachine.sendMessage(CMD_SCAN_ONLY_MODE_STOPPED);
} else if (state == WifiManager.WIFI_STATE_ENABLED) {
@@ -473,4 +485,23 @@ public class WifiStateMachinePrime {
}
}
+ // callback used to receive callbacks about underlying native failures
+ private final class WifiNativeStatusListener implements StatusListener {
+ Handler mHandler = new Handler(mLooper);
+
+ @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);
+ });
+ }
+ }
+ };
}