summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java40
-rw-r--r--service/java/com/android/server/wifi/DeviceConfigFacade.java60
-rw-r--r--service/java/com/android/server/wifi/WifiDiagnostics.java4
-rw-r--r--service/java/com/android/server/wifi/WifiHealthMonitor.java10
-rw-r--r--service/java/com/android/server/wifi/WifiScoreCard.java123
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java25
-rw-r--r--tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java16
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java7
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java22
9 files changed, 238 insertions, 69 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 2c01eb8f8..85eeb22fa 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -1583,6 +1583,32 @@ public class ClientModeImpl extends StateMachine {
sendMessageAtFrontOfQueue(CMD_SET_OPERATIONAL_MODE);
}
+ private void checkAbnormalConnectionFailureAndTakeBugReport(String ssid) {
+ if (mWifiInjector.getDeviceConfigFacade()
+ .isAbnormalConnectionFailureBugreportEnabled()) {
+ int reasonCode = mWifiScoreCard.detectAbnormalConnectionFailure(ssid);
+ if (reasonCode != WifiHealthMonitor.REASON_NO_FAILURE) {
+ String bugTitle = "Wi-Fi BugReport";
+ String bugDetail = "Detect abnormal "
+ + WifiHealthMonitor.FAILURE_REASON_NAME[reasonCode];
+ takeBugReport(bugTitle, bugDetail);
+ }
+ }
+ }
+
+ private void checkAbnormalDisconnectionAndTakeBugReport() {
+ if (mWifiInjector.getDeviceConfigFacade()
+ .isAbnormalDisconnectionBugreportEnabled()) {
+ int reasonCode = mWifiScoreCard.detectAbnormalDisconnection();
+ if (reasonCode != WifiHealthMonitor.REASON_NO_FAILURE) {
+ String bugTitle = "Wi-Fi BugReport";
+ String bugDetail = "Detect abnormal "
+ + WifiHealthMonitor.FAILURE_REASON_NAME[reasonCode];
+ takeBugReport(bugTitle, bugDetail);
+ }
+ }
+ }
+
/**
* Initiates a system-level bugreport, in a non-blocking fashion.
*/
@@ -2731,6 +2757,7 @@ public class ClientModeImpl extends StateMachine {
mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
mLastSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
mLastSimBasedConnectionCarrierName = null;
+ checkAbnormalDisconnectionAndTakeBugReport();
mWifiScoreCard.resetConnectionState();
mWifiDataStall.reset();
updateL2KeyAndGroupHint();
@@ -2901,18 +2928,7 @@ public class ClientModeImpl extends StateMachine {
: configuration.networkId;
int scanRssi = mWifiConfigManager.findScanRssi(networkId, SCAN_RSSI_VALID_TIME_MS);
mWifiScoreCard.noteConnectionFailure(mWifiInfo, scanRssi, ssid, blocklistReason);
- boolean isNonWrongPwdAuthFailure =
- blocklistReason == BssidBlocklistMonitor.REASON_AUTHENTICATION_FAILURE
- || blocklistReason == BssidBlocklistMonitor.REASON_EAP_FAILURE;
- boolean isEnterpriseNetwork = configuration != null && configuration.isEnterprise();
- if (isNonWrongPwdAuthFailure && isEnterpriseNetwork && mWifiInjector
- .getDeviceConfigFacade().isAbnormalEapAuthFailureBugreportEnabled()
- && mWifiScoreCard.detectAbnormalAuthFailure(ssid)) {
- String bugTitle = "Wi-Fi BugReport";
- String bugDetail = "Abnormal authentication failure with enterprise network";
- mWifiDiagnostics.takeBugReport(bugTitle, bugDetail);
- }
-
+ checkAbnormalConnectionFailureAndTakeBugReport(ssid);
boolean isLowRssi = false;
int sufficientRssi = getSufficientRssi(networkId, bssid);
if (scanRssi != WifiInfo.INVALID_RSSI && sufficientRssi != WifiInfo.INVALID_RSSI) {
diff --git a/service/java/com/android/server/wifi/DeviceConfigFacade.java b/service/java/com/android/server/wifi/DeviceConfigFacade.java
index 7ea346c80..67cc01ce9 100644
--- a/service/java/com/android/server/wifi/DeviceConfigFacade.java
+++ b/service/java/com/android/server/wifi/DeviceConfigFacade.java
@@ -67,12 +67,12 @@ public class DeviceConfigFacade {
public static final int DEFAULT_RX_PACKET_PER_SECOND_THR = 1;
// Default high threshold values for various connection/disconnection cases
// All of them are in percent with respect to connection attempts
- static final int DEFAULT_CONNECTION_FAILURE_HIGH_THR_PERCENT = 30;
- static final int DEFAULT_ASSOC_REJECTION_HIGH_THR_PERCENT = 20;
- static final int DEFAULT_ASSOC_TIMEOUT_HIGH_THR_PERCENT = 20;
- static final int DEFAULT_AUTH_FAILURE_HIGH_THR_PERCENT = 20;
- static final int DEFAULT_SHORT_CONNECTION_NONLOCAL_HIGH_THR_PERCENT = 15;
- static final int DEFAULT_DISCONNECTION_NONLOCAL_HIGH_THR_PERCENT = 20;
+ static final int DEFAULT_CONNECTION_FAILURE_HIGH_THR_PERCENT = 40;
+ static final int DEFAULT_ASSOC_REJECTION_HIGH_THR_PERCENT = 30;
+ static final int DEFAULT_ASSOC_TIMEOUT_HIGH_THR_PERCENT = 30;
+ static final int DEFAULT_AUTH_FAILURE_HIGH_THR_PERCENT = 30;
+ static final int DEFAULT_SHORT_CONNECTION_NONLOCAL_HIGH_THR_PERCENT = 20;
+ static final int DEFAULT_DISCONNECTION_NONLOCAL_HIGH_THR_PERCENT = 25;
// Default health monitor abnormal count minimum for various cases
static final int DEFAULT_CONNECTION_FAILURE_COUNT_MIN = 6;
static final int DEFAULT_ASSOC_REJECTION_COUNT_MIN = 3;
@@ -90,6 +90,11 @@ public class DeviceConfigFacade {
static final int DEFAULT_HEALTH_MONITOR_MIN_RSSI_THR_DBM = -68;
// Default minimum number of connection attempts to qualify daily detection
static final int DEFAULT_HEALTH_MONITOR_MIN_NUM_CONNECTION_ATTEMPT = 10;
+ // Default minimum wait time between two bug report captures
+ static final int DEFAULT_BUG_REPORT_MIN_WINDOW_MS = 3_600_000;
+ // Default report-high threshold to take-bug-report threshold ratio.
+ // It should be larger than 1 since the bar to take bugreport should be higher.
+ static final int DEFAULT_BUG_REPORT_THRESHOLD_EXTRA_RATIO = 2;
// Cached values of fields updated via updateDeviceConfigFlags()
private boolean mIsAbnormalConnectionBugreportEnabled;
@@ -122,8 +127,11 @@ public class DeviceConfigFacade {
private Set<String> mRandomizationFlakySsidHotlist;
private Set<String> mAggressiveMacRandomizationSsidAllowlist;
private Set<String> mAggressiveMacRandomizationSsidBlocklist;
- private boolean mIsAbnormalEapAuthFailureBugreportEnabled;
+ private boolean mIsAbnormalConnectionFailureBugreportEnabled;
+ private boolean mIsAbnormalDisconnectionBugreportEnabled;
private int mHealthMonitorMinNumConnectionAttempt;
+ private int mBugReportMinWindowMs;
+ private int mBugReportThresholdExtraRatio;
public DeviceConfigFacade(Context context, Handler handler, WifiMetrics wifiMetrics) {
mContext = context;
@@ -224,11 +232,19 @@ public class DeviceConfigFacade {
mAggressiveMacRandomizationSsidBlocklist =
getUnmodifiableSetQuoted("aggressive_randomization_ssid_blocklist");
- mIsAbnormalEapAuthFailureBugreportEnabled = DeviceConfig.getBoolean(NAMESPACE,
- "abnormal_eap_auth_failure_bugreport_enabled", false);
+ mIsAbnormalConnectionFailureBugreportEnabled = DeviceConfig.getBoolean(NAMESPACE,
+ "abnormal_connection_failure_bugreport_enabled", false);
+ mIsAbnormalDisconnectionBugreportEnabled = DeviceConfig.getBoolean(NAMESPACE,
+ "abnormal_disconnection_bugreport_enabled", false);
mHealthMonitorMinNumConnectionAttempt = DeviceConfig.getInt(NAMESPACE,
"health_monitor_min_num_connection_attempt",
DEFAULT_HEALTH_MONITOR_MIN_NUM_CONNECTION_ATTEMPT);
+ mBugReportMinWindowMs = DeviceConfig.getInt(NAMESPACE,
+ "bug_report_min_window_ms",
+ DEFAULT_BUG_REPORT_MIN_WINDOW_MS);
+ mBugReportThresholdExtraRatio = DeviceConfig.getInt(NAMESPACE,
+ "report_bug_report_threshold_extra_ratio",
+ DEFAULT_BUG_REPORT_THRESHOLD_EXTRA_RATIO);
}
private Set<String> getUnmodifiableSetQuoted(String key) {
@@ -458,12 +474,18 @@ public class DeviceConfigFacade {
public Set<String> getAggressiveMacRandomizationSsidBlocklist() {
return mAggressiveMacRandomizationSsidBlocklist;
}
+ /**
+ * Gets the feature flag for reporting abnormal connection failure.
+ */
+ public boolean isAbnormalConnectionFailureBugreportEnabled() {
+ return mIsAbnormalConnectionFailureBugreportEnabled;
+ }
/**
- * Gets the feature flag for reporting abnormal EAP authentication failure.
+ * Gets the feature flag for reporting abnormal disconnection.
*/
- public boolean isAbnormalEapAuthFailureBugreportEnabled() {
- return mIsAbnormalEapAuthFailureBugreportEnabled;
+ public boolean isAbnormalDisconnectionBugreportEnabled() {
+ return mIsAbnormalDisconnectionBugreportEnabled;
}
/**
@@ -472,4 +494,18 @@ public class DeviceConfigFacade {
public int getHealthMonitorMinNumConnectionAttempt() {
return mHealthMonitorMinNumConnectionAttempt;
}
+
+ /**
+ * Gets minimum wait time between two bug report captures
+ */
+ public int getBugReportMinWindowMs() {
+ return mBugReportMinWindowMs;
+ }
+
+ /**
+ * Gets the extra ratio of threshold to trigger bug report.
+ */
+ public int getBugReportThresholdExtraRatio() {
+ return mBugReportThresholdExtraRatio;
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiDiagnostics.java b/service/java/com/android/server/wifi/WifiDiagnostics.java
index 05c4df634..4ac982063 100644
--- a/service/java/com/android/server/wifi/WifiDiagnostics.java
+++ b/service/java/com/android/server/wifi/WifiDiagnostics.java
@@ -108,7 +108,6 @@ class WifiDiagnostics extends BaseWifiDiagnostics {
public static final long MIN_DUMP_TIME_WINDOW_MILLIS = 10 * 60 * 1000; // 10 mins
private long mLastBugReportTime;
- static final long MIN_BUG_REPORT_TIME_WINDOW_MILLIS = 60 * 60 * 1000; // 60 mins
@VisibleForTesting public static final String FIRMWARE_DUMP_SECTION_HEADER =
"FW Memory dump";
@@ -302,7 +301,8 @@ class WifiDiagnostics extends BaseWifiDiagnostics {
return;
}
long currentTime = mClock.getWallClockMillis();
- if ((currentTime - mLastBugReportTime) < MIN_BUG_REPORT_TIME_WINDOW_MILLIS
+ if ((currentTime - mLastBugReportTime)
+ < mWifiInjector.getDeviceConfigFacade().getBugReportMinWindowMs()
&& mLastBugReportTime > 0) {
return;
}
diff --git a/service/java/com/android/server/wifi/WifiHealthMonitor.java b/service/java/com/android/server/wifi/WifiHealthMonitor.java
index b85fa5fbe..123c576bd 100644
--- a/service/java/com/android/server/wifi/WifiHealthMonitor.java
+++ b/service/java/com/android/server/wifi/WifiHealthMonitor.java
@@ -524,6 +524,7 @@ public class WifiHealthMonitor {
mWifiSystemInfoStats.clearAll();
}
+ public static final int REASON_NO_FAILURE = -1;
public static final int REASON_ASSOC_REJECTION = 0;
public static final int REASON_ASSOC_TIMEOUT = 1;
public static final int REASON_AUTH_FAILURE = 2;
@@ -531,7 +532,16 @@ public class WifiHealthMonitor {
public static final int REASON_DISCONNECTION_NONLOCAL = 4;
public static final int REASON_SHORT_CONNECTION_NONLOCAL = 5;
public static final int NUMBER_FAILURE_REASON_CODE = 6;
+ public static final String[] FAILURE_REASON_NAME = {
+ "association rejection failure",
+ "association timeout failure",
+ "authentication failure",
+ "connection failure",
+ "disconnection",
+ "short connection"
+ };
@IntDef(prefix = { "REASON_" }, value = {
+ REASON_NO_FAILURE,
REASON_ASSOC_REJECTION,
REASON_ASSOC_TIMEOUT,
REASON_AUTH_FAILURE,
diff --git a/service/java/com/android/server/wifi/WifiScoreCard.java b/service/java/com/android/server/wifi/WifiScoreCard.java
index 79c9ccb24..61a8435ed 100644
--- a/service/java/com/android/server/wifi/WifiScoreCard.java
+++ b/service/java/com/android/server/wifi/WifiScoreCard.java
@@ -27,6 +27,7 @@ import static com.android.server.wifi.WifiHealthMonitor.REASON_ASSOC_TIMEOUT;
import static com.android.server.wifi.WifiHealthMonitor.REASON_AUTH_FAILURE;
import static com.android.server.wifi.WifiHealthMonitor.REASON_CONNECTION_FAILURE;
import static com.android.server.wifi.WifiHealthMonitor.REASON_DISCONNECTION_NONLOCAL;
+import static com.android.server.wifi.WifiHealthMonitor.REASON_NO_FAILURE;
import static com.android.server.wifi.WifiHealthMonitor.REASON_SHORT_CONNECTION_NONLOCAL;
import android.annotation.IntDef;
@@ -104,10 +105,6 @@ public class WifiScoreCard {
// disconnection stats collection.
private static final int LAST_RSSI_POLL_MAX_INTERVAL_MS = 3_100;
- // Minimum number of connection attempts to qualify abnormal auth detection
- static final int MIN_NUM_CONNECTION_ATTEMPT_ABNORMAL_AUTH_FAILURE = 5;
- static final int FAILURE_PERCENT_THRESHOLD_ABNORMAL_AUTH_FAILURE = 80;
-
static final int INSUFFICIENT_RECENT_STATS = 0;
static final int SUFFICIENT_RECENT_STATS_ONLY = 1;
static final int SUFFICIENT_RECENT_PREV_STATS = 2;
@@ -258,7 +255,7 @@ public class WifiScoreCard {
* Handle network disconnection or shutdown event
*/
public void resetConnectionState() {
- String ssidDisconnected = (mAttemptingSwitch) ? mSsidPrev : mSsidCurr;
+ String ssidDisconnected = mAttemptingSwitch ? mSsidPrev : mSsidCurr;
updatePerNetwork(Event.DISCONNECTION, ssidDisconnected, INVALID_RSSI, LINK_SPEED_UNKNOWN,
UNKNOWN_REASON);
if (mVerboseLoggingEnabled && mTsConnectionAttemptStart > TS_NONE && !mAttemptingSwitch) {
@@ -565,20 +562,90 @@ public class WifiScoreCard {
}
/**
- * Detect abnormal authentication failure at high RSSI with enough connection attempts
- * and high failure rate
- * @return true if abnormal auth failure is detected, false otherwise
+ * Detect abnormal disconnection at high RSSI with a high rate
*/
- public boolean detectAbnormalAuthFailure(String ssid) {
+ public int detectAbnormalDisconnection() {
+ String ssid = mAttemptingSwitch ? mSsidPrev : mSsidCurr;
PerNetwork perNetwork = lookupNetwork(ssid);
NetworkConnectionStats recentStats = perNetwork.getRecentStats();
- logd("detectAbnormalAuthFailure: " + recentStats.toString());
- int numAuthFailure = recentStats.getCount(CNT_AUTHENTICATION_FAILURE);
- int numAttempt = recentStats.getCount(CNT_CONNECTION_ATTEMPT);
- boolean hasEnoughAttempt = numAttempt >= MIN_NUM_CONNECTION_ATTEMPT_ABNORMAL_AUTH_FAILURE;
- boolean isAuthFailureRateHigh = (numAuthFailure * 100)
- >= (numAttempt * FAILURE_PERCENT_THRESHOLD_ABNORMAL_AUTH_FAILURE);
- return hasEnoughAttempt && isAuthFailureRateHigh;
+ if (recentStats.getRecentCountCode() == CNT_SHORT_CONNECTION_NONLOCAL) {
+ return detectAbnormalFailureReason(recentStats, CNT_SHORT_CONNECTION_NONLOCAL,
+ REASON_SHORT_CONNECTION_NONLOCAL,
+ mDeviceConfigFacade.getShortConnectionNonlocalHighThrPercent(),
+ mDeviceConfigFacade.getShortConnectionNonlocalCountMin(),
+ CNT_DISCONNECTION);
+ } else if (recentStats.getRecentCountCode() == CNT_DISCONNECTION_NONLOCAL) {
+ return detectAbnormalFailureReason(recentStats, CNT_DISCONNECTION_NONLOCAL,
+ REASON_DISCONNECTION_NONLOCAL,
+ mDeviceConfigFacade.getDisconnectionNonlocalHighThrPercent(),
+ mDeviceConfigFacade.getDisconnectionNonlocalCountMin(),
+ CNT_DISCONNECTION);
+ } else {
+ return REASON_NO_FAILURE;
+ }
+ }
+
+ /**
+ * Detect abnormal connection failure at high RSSI with a high rate
+ */
+ public int detectAbnormalConnectionFailure(String ssid) {
+ PerNetwork perNetwork = lookupNetwork(ssid);
+ NetworkConnectionStats recentStats = perNetwork.getRecentStats();
+ int recentCountCode = recentStats.getRecentCountCode();
+ if (recentCountCode == CNT_AUTHENTICATION_FAILURE) {
+ return detectAbnormalFailureReason(recentStats, CNT_AUTHENTICATION_FAILURE,
+ REASON_AUTH_FAILURE,
+ mDeviceConfigFacade.getAuthFailureHighThrPercent(),
+ mDeviceConfigFacade.getAuthFailureCountMin(),
+ CNT_CONNECTION_ATTEMPT);
+ } else if (recentCountCode == CNT_ASSOCIATION_REJECTION) {
+ return detectAbnormalFailureReason(recentStats, CNT_ASSOCIATION_REJECTION,
+ REASON_ASSOC_REJECTION,
+ mDeviceConfigFacade.getAssocRejectionHighThrPercent(),
+ mDeviceConfigFacade.getAssocRejectionCountMin(),
+ CNT_CONNECTION_ATTEMPT);
+ } else if (recentCountCode == CNT_ASSOCIATION_TIMEOUT) {
+ return detectAbnormalFailureReason(recentStats, CNT_ASSOCIATION_TIMEOUT,
+ REASON_ASSOC_TIMEOUT,
+ mDeviceConfigFacade.getAssocTimeoutHighThrPercent(),
+ mDeviceConfigFacade.getAssocTimeoutCountMin(),
+ CNT_CONNECTION_ATTEMPT);
+ } else if (recentCountCode == CNT_CONNECTION_FAILURE) {
+ return detectAbnormalFailureReason(recentStats, CNT_CONNECTION_FAILURE,
+ REASON_CONNECTION_FAILURE,
+ mDeviceConfigFacade.getConnectionFailureHighThrPercent(),
+ mDeviceConfigFacade.getConnectionFailureCountMin(),
+ CNT_CONNECTION_ATTEMPT);
+ } else {
+ return REASON_NO_FAILURE;
+ }
+ }
+
+ private int detectAbnormalFailureReason(NetworkConnectionStats stats, int countCode,
+ int reasonCode, int highThresholdPercent, int minCount, int refCountCode) {
+ // To detect abnormal failure which may trigger bugReport,
+ // increase the detection threshold by thresholdRatio
+ int thresholdRatio =
+ mDeviceConfigFacade.getBugReportThresholdExtraRatio();
+ if (isHighPercentageAndEnoughCount(stats, countCode, reasonCode,
+ highThresholdPercent * thresholdRatio,
+ minCount * thresholdRatio,
+ refCountCode)) {
+ return reasonCode;
+ } else {
+ return REASON_NO_FAILURE;
+ }
+ }
+
+ private boolean isHighPercentageAndEnoughCount(NetworkConnectionStats stats, int countCode,
+ int reasonCode, int highThresholdPercent, int minCount, int refCountCode) {
+ highThresholdPercent = Math.min(highThresholdPercent, 100);
+ // Use Laplace's rule of succession, useful especially for a small
+ // connection attempt count
+ // R = (f+1)/(n+2) with a pseudo count of 2 (one for f and one for s)
+ return ((stats.getCount(countCode) >= minCount)
+ && ((stats.getCount(countCode) + 1) * 100)
+ >= (highThresholdPercent * (stats.getCount(refCountCode) + 2)));
}
final class PerBssid extends MemoryStoreAccessBase {
@@ -999,12 +1066,8 @@ public class WifiScoreCard {
private boolean recentStatsHighDetection(FailureStats statsHigh, int countCode,
int reasonCode, int highThresholdPercent, int minCount, int refCountCode) {
- // Use Laplace's rule of succession, useful especially for a small
- // connection attempt count
- // R = (f+1)/(n+2) with a pseudo count of 2 (one for f and one for s)
- if ((((mRecentStats.getCount(countCode) + 1) * 100)
- >= (highThresholdPercent * (mRecentStats.getCount(refCountCode) + 2)))
- && (mRecentStats.getCount(countCode) >= minCount)) {
+ if (isHighPercentageAndEnoughCount(mRecentStats, countCode, reasonCode,
+ highThresholdPercent, minCount, refCountCode)) {
statsHigh.incrementCount(reasonCode);
return true;
}
@@ -1152,6 +1215,7 @@ public class WifiScoreCard {
}
// Codes for various connection related counts
+ public static final int CNT_INVALID = -1;
public static final int CNT_CONNECTION_ATTEMPT = 0;
public static final int CNT_CONNECTION_FAILURE = 1;
public static final int CNT_CONNECTION_DURATION_SEC = 2;
@@ -1194,7 +1258,7 @@ public class WifiScoreCard {
*/
public static class NetworkConnectionStats {
private final int[] mCount = new int[NUMBER_CONNECTION_CNT_CODE];
-
+ private int mRecentCountCode = CNT_INVALID;
/**
* Copy all values
* @param src is the source of copy
@@ -1203,6 +1267,7 @@ public class WifiScoreCard {
for (int i = 0; i < NUMBER_CONNECTION_CNT_CODE; i++) {
mCount[i] = src.getCount(i);
}
+ mRecentCountCode = src.mRecentCountCode;
}
/**
@@ -1212,6 +1277,7 @@ public class WifiScoreCard {
for (int i = 0; i < NUMBER_CONNECTION_CNT_CODE; i++) {
mCount[i] = 0;
}
+ mRecentCountCode = CNT_INVALID;
}
/**
@@ -1224,12 +1290,13 @@ public class WifiScoreCard {
}
/**
- * Set counterer value
+ * Set counter value
* @param countCode is the selected counter
* @param cnt is the value set to the selected counter
*/
public void setCount(@ConnectionCountCode int countCode, int cnt) {
mCount[countCode] = cnt;
+ mRecentCountCode = countCode;
}
/**
@@ -1238,6 +1305,14 @@ public class WifiScoreCard {
*/
public void incrementCount(@ConnectionCountCode int countCode) {
mCount[countCode]++;
+ mRecentCountCode = countCode;
+ }
+
+ /**
+ * Got the recent count code
+ */
+ public int getRecentCountCode() {
+ return mRecentCountCode;
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index 0679b8c4f..1930cd15a 100644
--- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -551,7 +551,12 @@ public class ClientModeImplTest extends WifiBaseTest {
mConnectedNetwork = spy(WifiConfigurationTestUtil.createOpenNetwork());
when(mNullAsyncChannel.sendMessageSynchronously(any())).thenReturn(null);
when(mWifiScoreCard.getL2KeyAndGroupHint(any())).thenReturn(new Pair<>(null, null));
- when(mDeviceConfigFacade.isAbnormalEapAuthFailureBugreportEnabled()).thenReturn(true);
+ when(mDeviceConfigFacade.isAbnormalDisconnectionBugreportEnabled()).thenReturn(true);
+ when(mDeviceConfigFacade.isAbnormalConnectionFailureBugreportEnabled()).thenReturn(true);
+ when(mWifiScoreCard.detectAbnormalConnectionFailure(anyString()))
+ .thenReturn(WifiHealthMonitor.REASON_NO_FAILURE);
+ when(mWifiScoreCard.detectAbnormalDisconnection())
+ .thenReturn(WifiHealthMonitor.REASON_NO_FAILURE);
when(mThroughputPredictor.predictMaxTxThroughput(any())).thenReturn(90);
when(mThroughputPredictor.predictMaxRxThroughput(any())).thenReturn(80);
}
@@ -1724,8 +1729,6 @@ public class ClientModeImplTest extends WifiBaseTest {
verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(),
eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD));
- verify(mWifiScoreCard, never()).detectAbnormalAuthFailure(any());
-
assertEquals("DisconnectedState", getCurrentState().getName());
}
@@ -1757,6 +1760,8 @@ public class ClientModeImplTest extends WifiBaseTest {
.startMocking();
when(SubscriptionManager.getDefaultDataSubscriptionId()).thenReturn(DATA_SUBID);
when(SubscriptionManager.isValidSubscriptionId(anyInt())).thenReturn(true);
+ when(mWifiScoreCard.detectAbnormalConnectionFailure(anyString()))
+ .thenReturn(WifiHealthMonitor.REASON_AUTH_FAILURE);
mCmi.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT,
WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE,
@@ -1767,8 +1772,9 @@ public class ClientModeImplTest extends WifiBaseTest {
WifiNative.EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED, config);
verify(mDataTelephonyManager).resetCarrierKeysForImsiEncryption();
mockSession.finishMocking();
- verify(mWifiScoreCard).detectAbnormalAuthFailure(anyString());
- verify(mDeviceConfigFacade).isAbnormalEapAuthFailureBugreportEnabled();
+ verify(mDeviceConfigFacade).isAbnormalConnectionFailureBugreportEnabled();
+ verify(mWifiScoreCard).detectAbnormalConnectionFailure(anyString());
+ verify(mWifiDiagnostics).takeBugReport(anyString(), anyString());
}
/**
@@ -1799,8 +1805,6 @@ public class ClientModeImplTest extends WifiBaseTest {
mLooper.dispatchAll();
verify(mDataTelephonyManager, never()).resetCarrierKeysForImsiEncryption();
- verify(mWifiScoreCard).detectAbnormalAuthFailure(null);
- verify(mDeviceConfigFacade).isAbnormalEapAuthFailureBugreportEnabled();
}
/**
@@ -1828,8 +1832,6 @@ public class ClientModeImplTest extends WifiBaseTest {
verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(),
eq(WifiConfiguration.NetworkSelectionStatus
.DISABLED_AUTHENTICATION_NO_SUBSCRIPTION));
- verify(mWifiScoreCard, never()).detectAbnormalAuthFailure(null);
- verify(mDeviceConfigFacade, never()).isAbnormalEapAuthFailureBugreportEnabled();
}
@Test
@@ -1851,6 +1853,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mLooper.dispatchAll();
assertEquals("DisconnectedState", getCurrentState().getName());
+ verify(mWifiDiagnostics, never()).takeBugReport(anyString(), anyString());
}
@@ -1865,6 +1868,8 @@ public class ClientModeImplTest extends WifiBaseTest {
@Test
public void disconnect() throws Exception {
+ when(mWifiScoreCard.detectAbnormalDisconnection())
+ .thenReturn(WifiHealthMonitor.REASON_SHORT_CONNECTION_NONLOCAL);
InOrder inOrderWifiLockManager = inOrder(mWifiLockManager);
connect();
inOrderWifiLockManager.verify(mWifiLockManager).updateWifiClientConnected(true);
@@ -1879,6 +1884,8 @@ public class ClientModeImplTest extends WifiBaseTest {
verify(mWifiNetworkSuggestionsManager).handleDisconnect(any(), any());
assertEquals("DisconnectedState", getCurrentState().getName());
inOrderWifiLockManager.verify(mWifiLockManager).updateWifiClientConnected(false);
+ verify(mWifiScoreCard).detectAbnormalDisconnection();
+ verify(mWifiDiagnostics).takeBugReport(anyString(), anyString());
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java b/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
index d6a05c7a3..b7136d986 100644
--- a/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
@@ -170,9 +170,12 @@ public class DeviceConfigFacadeTest extends WifiBaseTest {
mDeviceConfigFacade.getAggressiveMacRandomizationSsidAllowlist());
assertEquals(Collections.emptySet(),
mDeviceConfigFacade.getAggressiveMacRandomizationSsidBlocklist());
- assertEquals(false, mDeviceConfigFacade.isAbnormalEapAuthFailureBugreportEnabled());
+ assertEquals(false, mDeviceConfigFacade.isAbnormalConnectionFailureBugreportEnabled());
+ assertEquals(false, mDeviceConfigFacade.isAbnormalDisconnectionBugreportEnabled());
assertEquals(DeviceConfigFacade.DEFAULT_HEALTH_MONITOR_MIN_NUM_CONNECTION_ATTEMPT,
mDeviceConfigFacade.getHealthMonitorMinNumConnectionAttempt());
+ assertEquals(DeviceConfigFacade.DEFAULT_BUG_REPORT_MIN_WINDOW_MS,
+ mDeviceConfigFacade.getBugReportMinWindowMs());
}
/**
@@ -242,10 +245,15 @@ public class DeviceConfigFacadeTest extends WifiBaseTest {
anyString())).thenReturn(testSsidList);
when(DeviceConfig.getString(anyString(), eq("aggressive_randomization_ssid_blocklist"),
anyString())).thenReturn(testSsidList);
- when(DeviceConfig.getBoolean(anyString(), eq("abnormal_eap_auth_failure_bugreport_enabled"),
+ when(DeviceConfig.getBoolean(anyString(),
+ eq("abnormal_connection_failure_bugreport_enabled"),
+ anyBoolean())).thenReturn(true);
+ when(DeviceConfig.getBoolean(anyString(), eq("abnormal_disconnection_bugreport_enabled"),
anyBoolean())).thenReturn(true);
when(DeviceConfig.getInt(anyString(), eq("health_monitor_min_num_connection_attempt"),
anyInt())).thenReturn(20);
+ when(DeviceConfig.getInt(anyString(), eq("bug_report_min_window_ms"),
+ anyInt())).thenReturn(1000);
mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
@@ -285,7 +293,9 @@ public class DeviceConfigFacadeTest extends WifiBaseTest {
mDeviceConfigFacade.getAggressiveMacRandomizationSsidAllowlist());
assertEquals(testSsidSet,
mDeviceConfigFacade.getAggressiveMacRandomizationSsidBlocklist());
- assertEquals(true, mDeviceConfigFacade.isAbnormalEapAuthFailureBugreportEnabled());
+ assertEquals(true, mDeviceConfigFacade.isAbnormalConnectionFailureBugreportEnabled());
+ assertEquals(true, mDeviceConfigFacade.isAbnormalDisconnectionBugreportEnabled());
assertEquals(20, mDeviceConfigFacade.getHealthMonitorMinNumConnectionAttempt());
+ assertEquals(1000, mDeviceConfigFacade.getBugReportMinWindowMs());
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java
index acfc78d7e..6b235b9f7 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java
@@ -64,6 +64,7 @@ public class WifiDiagnosticsTest extends WifiBaseTest {
@Mock BuildProperties mBuildProperties;
@Mock Context mContext;
@Mock WifiInjector mWifiInjector;
+ @Mock DeviceConfigFacade mDeviceConfigFacade;
@Spy FakeWifiLog mLog;
@Mock LastMileLogger mLastMileLogger;
@Mock Runtime mJavaRuntime;
@@ -86,6 +87,7 @@ public class WifiDiagnosticsTest extends WifiBaseTest {
private static final int[] FATAL_FW_ALERT_LIST = {256, 257, 258};
/** Mock a non fatal firmware alert */
private static final int NON_FATAL_FW_ALERT = 0;
+ private static final int BUG_REPORT_MIN_WINDOW_MS = 3600_000;
private WifiNative.RingBufferStatus mFakeRbs;
/**
@@ -131,7 +133,8 @@ public class WifiDiagnosticsTest extends WifiBaseTest {
when(mWifiInjector.makeLog(anyString())).thenReturn(mLog);
when(mWifiInjector.getJavaRuntime()).thenReturn(mJavaRuntime);
when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics);
-
+ when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade);
+ when(mDeviceConfigFacade.getBugReportMinWindowMs()).thenReturn(BUG_REPORT_MIN_WINDOW_MS);
mWifiDiagnostics = new WifiDiagnostics(
mContext, mWifiInjector, mWifiNative, mBuildProperties, mLastMileLogger, mClock);
mWifiNative.enableVerboseLogging(0);
@@ -888,7 +891,7 @@ public class WifiDiagnosticsTest extends WifiBaseTest {
mWifiDiagnostics.takeBugReport("", "");
verify(mBugreportManager, times(1)).requestBugreport(any(), any(), any());
// 2nd attempt should fail
- when(mClock.getWallClockMillis()).thenReturn(1000_000L);
+ when(mClock.getWallClockMillis()).thenReturn(BUG_REPORT_MIN_WINDOW_MS - 20L);
mWifiDiagnostics.takeBugReport("", "");
verify(mBugreportManager, times(1)).requestBugreport(any(), any(), any());
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java b/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java
index e98b03acf..d6dc020b9 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java
@@ -154,6 +154,7 @@ public class WifiScoreCardTest extends WifiBaseTest {
DeviceConfigFacade.DEFAULT_HEALTH_MONITOR_RATIO_THR_NUMERATOR);
when(mDeviceConfigFacade.getHealthMonitorMinNumConnectionAttempt()).thenReturn(
DeviceConfigFacade.DEFAULT_HEALTH_MONITOR_MIN_NUM_CONNECTION_ATTEMPT);
+ when(mDeviceConfigFacade.getBugReportThresholdExtraRatio()).thenReturn(1);
mWifiScoreCard.enableVerboseLogging(true);
}
@@ -1106,6 +1107,8 @@ public class WifiScoreCardTest extends WifiBaseTest {
perNetwork.updateAfterDailyDetection();
checkShortConnectionExample(perNetwork.getRecentStats(), 1);
checkShortConnectionExample(perNetwork.getStatsPrevBuild(), 0);
+ assertEquals(WifiHealthMonitor.REASON_NO_FAILURE,
+ mWifiScoreCard.detectAbnormalConnectionFailure(mWifiInfo.getSSID()));
}
/**
@@ -1131,11 +1134,13 @@ public class WifiScoreCardTest extends WifiBaseTest {
// Add >2x failures after the SW build change
int numBadConnectionDays = 4;
for (int i = 0; i < numBadConnectionDays; i++) {
- makeRecentStatsWithShortConnection();
makeRecentStatsWithAssocTimeOut();
makeRecentStatsWithAuthFailure();
+ makeRecentStatsWithShortConnection();
}
+ assertEquals(WifiHealthMonitor.REASON_SHORT_CONNECTION_NONLOCAL,
+ mWifiScoreCard.detectAbnormalDisconnection());
FailureStats statsDec = new FailureStats();
FailureStats statsInc = new FailureStats();
FailureStats statsHigh = new FailureStats();
@@ -1175,6 +1180,8 @@ public class WifiScoreCardTest extends WifiBaseTest {
checkStatsDeltaExample(statsDec, 0);
checkStatsDeltaExample(statsInc, 0);
checkStatsDeltaExample(statsHigh, 0);
+ assertEquals(WifiHealthMonitor.REASON_NO_FAILURE,
+ mWifiScoreCard.detectAbnormalConnectionFailure(mWifiInfo.getSSID()));
}
/**
@@ -1197,10 +1204,12 @@ public class WifiScoreCardTest extends WifiBaseTest {
for (int i = 0; i < numGoodConnectionDays; i++) {
makeRecentStatsWithGoodConnection();
}
- makeRecentStatsWithShortConnection();
makeRecentStatsWithAssocTimeOut();
makeRecentStatsWithAuthFailure();
+ makeRecentStatsWithShortConnection();
+ assertEquals(WifiHealthMonitor.REASON_NO_FAILURE,
+ mWifiScoreCard.detectAbnormalConnectionFailure(mWifiInfo.getSSID()));
FailureStats statsDec = new FailureStats();
FailureStats statsInc = new FailureStats();
FailureStats statsHigh = new FailureStats();
@@ -1215,9 +1224,11 @@ public class WifiScoreCardTest extends WifiBaseTest {
PerNetwork perNetwork = mWifiScoreCard.lookupNetwork(mWifiInfo.getSSID());
makeRecentStatsWithShortConnection(); // Day 1
- makeRecentStatsWithAssocTimeOut();
makeRecentStatsWithAuthFailure();
+ makeRecentStatsWithAssocTimeOut();
+ assertEquals(WifiHealthMonitor.REASON_ASSOC_TIMEOUT,
+ mWifiScoreCard.detectAbnormalConnectionFailure(mWifiInfo.getSSID()));
FailureStats statsDec = new FailureStats();
FailureStats statsInc = new FailureStats();
FailureStats statsHigh = new FailureStats();
@@ -1226,12 +1237,13 @@ public class WifiScoreCardTest extends WifiBaseTest {
checkStatsDeltaExample(statsDec, 0);
checkStatsDeltaExample(statsInc, 0);
checkStatsDeltaExample(statsHigh, 1);
- assertEquals(false, mWifiScoreCard.detectAbnormalAuthFailure(mWifiInfo.getSSID()));
}
@Test
public void testHighAuthFailureRate() throws Exception {
+ makeRecentStatsWithGoodConnection();
makeRecentStatsWithAuthFailure();
- assertEquals(true, mWifiScoreCard.detectAbnormalAuthFailure(mWifiInfo.getSSID()));
+ assertEquals(WifiHealthMonitor.REASON_AUTH_FAILURE,
+ mWifiScoreCard.detectAbnormalConnectionFailure(mWifiInfo.getSSID()));
}
}