diff options
author | Kai Shi <kaishi@google.com> | 2020-06-16 21:09:17 -0700 |
---|---|---|
committer | Kai Shi <kaishi@google.com> | 2020-06-17 21:10:16 -0700 |
commit | 6d8147c663bfbe7507287054b0483feaf30d7c05 (patch) | |
tree | 3af26060cf467413588b158d131ee81bf4f17be6 | |
parent | c4d7ad413909b181fd59b595dc66d7d6d39aa684 (diff) |
Check deauth reason and FW alert for abnormal disconnection
1)To improve abnormal disconnection detection, add deauth reason and FW
alert check. The list of reason codes is configurable through a 64-bit
mask and FW alert valid time is also configurable.
2)Move other abnormal connection failure and disconnection detection timing related parameters to DeviceConfig.
3)Log last rssi poll valid time in wifi metrics.
4)Reduce default value of rssi poll valid time from 3.1s to 2.1s
5)Reduce default value of scan rssi valid time for stationary state from
20s to 8s because mobility state detection could be delayed.
Updated-PDD: TRUE
Bug: 159178185
Test: atest com.android.server.wifi
Change-Id: I6e131f149d242e5dbf0b8b0087303e85ed428f9f
Merged-In: Ifbd5519841d616651cacc846056eda6ff64393e0
10 files changed, 243 insertions, 40 deletions
diff --git a/service/java/com/android/server/wifi/DeviceConfigFacade.java b/service/java/com/android/server/wifi/DeviceConfigFacade.java index cfd2ad081..0e43a0891 100644 --- a/service/java/com/android/server/wifi/DeviceConfigFacade.java +++ b/service/java/com/android/server/wifi/DeviceConfigFacade.java @@ -107,7 +107,28 @@ public class DeviceConfigFacade { // At low traffic, Rx link speed values below the following threshold // are ignored because it could be due to low rate management frames static final int DEFAULT_RX_LINK_SPEED_LOW_THRESHOLD_MBPS = 9; - + // Default health monitor short connection duration threshold in ms + static final int DEFAULT_HEALTH_MONITOR_SHORT_CONNECTION_DURATION_THR_MS = 20_000; + + // Default mask for abnormal disconnection reason codes. + // Each bit of mask corresponds to a reason code defined in 802.11 standard section 9.4.1.7 + // For example, b0 for reason code 0, b1 for reason code 1, etc. + // Bits below are abnormal disconnection reasons and thus are set to 1 + // b0: reserved (e.g., STA heartbeat failure) + // b2: invalid auth + // b4: disassociated due to inactivity + // b6 and b7: invalid class 2 and 3 frames + // b34: disassociated due to missing ACKs + static final long DEFAULT_ABNORMAL_DISCONNECTION_REASON_CODE_MASK = 0x4_0000_00d5L; + // Default maximum interval between last RSSI poll and disconnection + static final int DEFAULT_HEALTH_MONITOR_RSSI_POLL_VALID_TIME_MS = 2_100; + // Default maximum interval between scan and connection attempt in non-stationary state + static final int DEFAULT_NONSTATIONARY_SCAN_RSSI_VALID_TIME_MS = 5_000; + // Default maximum interval between scan and connection attempt in stationary state + static final int DEFAULT_STATIONARY_SCAN_RSSI_VALID_TIME_MS = 8_000; + // Default health monitor firmware alert valid time. + // -1 disables firmware alert time check + static final int DEFAULT_HEALTH_MONITOR_FW_ALERT_VALID_TIME_MS = -1; // Cached values of fields updated via updateDeviceConfigFlags() private boolean mIsAbnormalConnectionBugreportEnabled; private int mAbnormalConnectionDurationMs; @@ -150,6 +171,12 @@ public class DeviceConfigFacade { private int mOverlappingConnectionDurationThresholdMs; private int mTxLinkSpeedLowThresholdMbps; private int mRxLinkSpeedLowThresholdMbps; + private int mHealthMonitorShortConnectionDurationThrMs; + private long mAbnormalDisconnectionReasonCodeMask; + private int mHealthMonitorRssiPollValidTimeMs; + private int mNonstationaryScanRssiValidTimeMs; + private int mStationaryScanRssiValidTimeMs; + private int mHealthMonitorFwAlertValidTimeMs; public DeviceConfigFacade(Context context, Handler handler, WifiMetrics wifiMetrics) { mContext = context; @@ -278,6 +305,26 @@ public class DeviceConfigFacade { mRxLinkSpeedLowThresholdMbps = DeviceConfig.getInt(NAMESPACE, "rx_link_speed_low_threshold_mbps", DEFAULT_RX_LINK_SPEED_LOW_THRESHOLD_MBPS); + mHealthMonitorShortConnectionDurationThrMs = DeviceConfig.getInt(NAMESPACE, + "health_monitor_short_connection_duration_thr_ms", + DEFAULT_HEALTH_MONITOR_SHORT_CONNECTION_DURATION_THR_MS); + mAbnormalDisconnectionReasonCodeMask = DeviceConfig.getLong(NAMESPACE, + "abnormal_disconnection_reason_code_mask", + DEFAULT_ABNORMAL_DISCONNECTION_REASON_CODE_MASK); + mHealthMonitorRssiPollValidTimeMs = DeviceConfig.getInt(NAMESPACE, + "health_monitor_rssi_poll_valid_time_ms", + DEFAULT_HEALTH_MONITOR_RSSI_POLL_VALID_TIME_MS); + mNonstationaryScanRssiValidTimeMs = DeviceConfig.getInt(NAMESPACE, + "nonstationary_scan_rssi_valid_time_ms", + DEFAULT_NONSTATIONARY_SCAN_RSSI_VALID_TIME_MS); + mStationaryScanRssiValidTimeMs = DeviceConfig.getInt(NAMESPACE, + "stationary_scan_rssi_valid_time_ms", + DEFAULT_STATIONARY_SCAN_RSSI_VALID_TIME_MS); + mHealthMonitorFwAlertValidTimeMs = DeviceConfig.getInt(NAMESPACE, + "health_monitor_fw_alert_valid_time_ms", + DEFAULT_HEALTH_MONITOR_FW_ALERT_VALID_TIME_MS); + mWifiMetrics.setHealthMonitorRssiPollValidTimeMs(mHealthMonitorRssiPollValidTimeMs); + } private Set<String> getUnmodifiableSetQuoted(String key) { @@ -583,4 +630,47 @@ public class DeviceConfigFacade { public int getRxLinkSpeedLowThresholdMbps() { return mRxLinkSpeedLowThresholdMbps; } + + /** + * Gets health monitor short connection duration threshold in ms + */ + public int getHealthMonitorShortConnectionDurationThrMs() { + return mHealthMonitorShortConnectionDurationThrMs; + } + + /** + * Gets abnormal disconnection reason code mask + */ + public long getAbnormalDisconnectionReasonCodeMask() { + return mAbnormalDisconnectionReasonCodeMask; + } + + /** + * Gets health monitor RSSI poll valid time in ms + */ + public int getHealthMonitorRssiPollValidTimeMs() { + return mHealthMonitorRssiPollValidTimeMs; + } + + /** + * Gets scan rssi valid time in ms when device is in non-stationary state + */ + public int getNonstationaryScanRssiValidTimeMs() { + return mNonstationaryScanRssiValidTimeMs; + } + + /** + * Gets scan rssi valid time in ms when device is in stationary state + */ + public int getStationaryScanRssiValidTimeMs() { + return mStationaryScanRssiValidTimeMs; + } + + /** + * Gets health monitor firmware alert valid time in ms, + * -1 disables firmware alert time check + */ + public int getHealthMonitorFwAlertValidTimeMs() { + return mHealthMonitorFwAlertValidTimeMs; + } } diff --git a/service/java/com/android/server/wifi/WifiDiagnostics.java b/service/java/com/android/server/wifi/WifiDiagnostics.java index a2328cd26..db9b075a4 100644 --- a/service/java/com/android/server/wifi/WifiDiagnostics.java +++ b/service/java/com/android/server/wifi/WifiDiagnostics.java @@ -473,6 +473,7 @@ class WifiDiagnostics extends BaseWifiDiagnostics { synchronized void onWifiAlert(int errorCode, @NonNull byte[] buffer) { captureAlertData(errorCode, buffer); mWifiMetrics.logFirmwareAlert(errorCode); + mWifiInjector.getWifiScoreCard().noteFirmwareAlert(errorCode); } /** diff --git a/service/java/com/android/server/wifi/WifiHealthMonitor.java b/service/java/com/android/server/wifi/WifiHealthMonitor.java index 8ab3a74a6..38da1578b 100644 --- a/service/java/com/android/server/wifi/WifiHealthMonitor.java +++ b/service/java/com/android/server/wifi/WifiHealthMonitor.java @@ -94,14 +94,11 @@ public class WifiHealthMonitor { private static final int MIN_NUM_BSSID_SCAN_2G = 2; // Minimum number of BSSIDs found above 2G with a normal scan private static final int MIN_NUM_BSSID_SCAN_ABOVE_2G = 2; - static final int DEFAULT_SCAN_RSSI_VALID_TIME_MS = 5_000; - static final int STATIONARY_SCAN_RSSI_VALID_TIME_MS = 20_000; - // Minimum Tx speed in Mbps for disconnection stats collection - // Disconnection events with Tx speed below this threshold are not - // included in connection stats collection. static final int HEALTH_MONITOR_COUNT_TX_SPEED_MIN_MBPS = 54; - static final int HEALTH_MONITOR_MIN_TX_PACKET_PER_SEC = 2; + // Minimum Tx packet per seconds for disconnection stats collection + static final int HEALTH_MONITOR_MIN_TX_PACKET_PER_SEC = 4; + private final Context mContext; private final WifiConfigManager mWifiConfigManager; private final WifiScoreCard mWifiScoreCard; @@ -222,7 +219,8 @@ public class WifiHealthMonitor { */ public int getScanRssiValidTimeMs() { return (mDeviceMobilityState == WifiManager.DEVICE_MOBILITY_STATE_STATIONARY) - ? STATIONARY_SCAN_RSSI_VALID_TIME_MS : DEFAULT_SCAN_RSSI_VALID_TIME_MS; + ? mDeviceConfigFacade.getStationaryScanRssiValidTimeMs() : + mDeviceConfigFacade.getNonstationaryScanRssiValidTimeMs(); } /** diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java index a704f10da..437d00261 100644 --- a/service/java/com/android/server/wifi/WifiMetrics.java +++ b/service/java/com/android/server/wifi/WifiMetrics.java @@ -6416,6 +6416,15 @@ public class WifiMetrics { } /** + * Sets health monitor RSSI poll valid time in ms + */ + public void setHealthMonitorRssiPollValidTimeMs(int rssiPollValidTimeMs) { + synchronized (mLock) { + mExperimentValues.healthMonitorRssiPollValidTimeMs = rssiPollValidTimeMs; + } + } + + /** * Increment connection duration while link layer stats report are on */ public void incrementConnectionDuration(int timeDeltaLastTwoPollsMs, diff --git a/service/java/com/android/server/wifi/WifiScoreCard.java b/service/java/com/android/server/wifi/WifiScoreCard.java index ca77e8396..64da835f0 100644 --- a/service/java/com/android/server/wifi/WifiScoreCard.java +++ b/service/java/com/android/server/wifi/WifiScoreCard.java @@ -70,7 +70,6 @@ import java.nio.ByteBuffer; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; -import java.util.Calendar; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -102,11 +101,6 @@ public class WifiScoreCard { public static final String PER_BSSID_DATA_NAME = "scorecard.proto"; public static final String PER_NETWORK_DATA_NAME = "perNetworkData"; - // Maximum connection duration in seconds to qualify short connection - private static final int SHORT_CONNECTION_DURATION_MAX_SEC = 20; - // Maximum interval between last RSSI poll and disconnection to qualify - // disconnection stats collection. - private static final int LAST_RSSI_POLL_MAX_INTERVAL_MS = 3_100; static final int INSUFFICIENT_RECENT_STATS = 0; static final int SUFFICIENT_RECENT_STATS_ONLY = 1; @@ -233,6 +227,8 @@ public class WifiScoreCard { private boolean mNonlocalDisconnection = false; private int mDisconnectionReason; + private long mFirmwareAlertTimeMs = TS_NONE; + /** * @param clock is the time source * @param l2KeySeed is for making our L2Keys usable only on this device @@ -292,6 +288,7 @@ public class WifiScoreCard { mPolled = false; mValidatedThisConnectionAtLeastOnce = false; mNonlocalDisconnection = false; + mFirmwareAlertTimeMs = TS_NONE; } /** @@ -410,6 +407,7 @@ public class WifiScoreCard { mPolled = false; mSsidPrev = mSsidCurr; mSsidCurr = ssid; + mFirmwareAlertTimeMs = TS_NONE; updatePerNetwork(Event.CONNECTION_ATTEMPT, ssid, scanRssi, LINK_SPEED_UNKNOWN, UNKNOWN_REASON); @@ -436,6 +434,14 @@ public class WifiScoreCard { } /** + * Record firmware alert timestamp and error code + */ + public void noteFirmwareAlert(int errorCode) { + mFirmwareAlertTimeMs = mClock.getElapsedSinceBootMillis(); + logd("firmware alert with error code: " + errorCode); + } + + /** * Updates the score card after a failed connection attempt * * @param wifiInfo object holding relevant values. @@ -870,7 +876,7 @@ public class WifiScoreCard { void updateEventStats(Event event, int rssi, int txSpeed, int failureReason) { finishPendingRead(); - long currTimeMs = mClock.getWallClockMillis(); + long currTimeMs = mClock.getElapsedSinceBootMillis(); switch (event) { case SIGNAL_POLL: mLastRssiPoll = rssi; @@ -927,11 +933,9 @@ public class WifiScoreCard { public String toString() { StringBuilder sb = new StringBuilder(); sb.append("SSID: ").append(ssid).append("\n"); - Calendar c = Calendar.getInstance(); if (mLastRssiPollTimeMs != TS_NONE) { sb.append(" LastRssiPollTime: "); - c.setTimeInMillis(mLastRssiPollTimeMs); - sb.append(String.format("%tm-%td %tH:%tM:%tS", c, c, c, c, c)); + sb.append(mLastRssiPollTimeMs); } sb.append(" LastRssiPoll: " + mLastRssiPoll); sb.append(" LastTxSpeedPoll: " + mLastTxSpeedPoll); @@ -943,21 +947,33 @@ public class WifiScoreCard { } private void handleDisconnection() { if (mConnectionSessionStartTimeMs > TS_NONE) { - long currTimeMs = mClock.getWallClockMillis(); - int currSessionDurationSec = (int) ((currTimeMs - - mConnectionSessionStartTimeMs) / 1000); + long currTimeMs = mClock.getElapsedSinceBootMillis(); + int currSessionDurationMs = (int) (currTimeMs - mConnectionSessionStartTimeMs); + int currSessionDurationSec = currSessionDurationMs / 1000; mRecentStats.accumulate(CNT_CONNECTION_DURATION_SEC, currSessionDurationSec); long timeSinceLastRssiPollMs = currTimeMs - mLastRssiPollTimeMs; - boolean hasRecentRssiPoll = (mLastRssiPollTimeMs > TS_NONE - && timeSinceLastRssiPollMs <= LAST_RSSI_POLL_MAX_INTERVAL_MS); + boolean hasRecentRssiPoll = mLastRssiPollTimeMs > TS_NONE + && timeSinceLastRssiPollMs <= mDeviceConfigFacade + .getHealthMonitorRssiPollValidTimeMs(); if (hasRecentRssiPoll) { mRecentStats.incrementCount(CNT_DISCONNECTION); } + int fwAlertValidTimeMs = mDeviceConfigFacade.getHealthMonitorFwAlertValidTimeMs(); + long timeSinceLastFirmAlert = currTimeMs - mFirmwareAlertTimeMs; + boolean isInvalidFwAlertTime = mFirmwareAlertTimeMs == TS_NONE; + boolean disableFwAlertCheck = fwAlertValidTimeMs == -1; + boolean passFirmwareAlertCheck = disableFwAlertCheck ? true : (isInvalidFwAlertTime + ? false : timeSinceLastFirmAlert < fwAlertValidTimeMs); + boolean hasHighRssiOrHighTxSpeed = + mLastRssiPoll >= mDeviceConfigFacade.getHealthMonitorMinRssiThrDbm() + || mLastTxSpeedPoll >= HEALTH_MONITOR_COUNT_TX_SPEED_MIN_MBPS; if (mNonlocalDisconnection && hasRecentRssiPoll - && (mLastRssiPoll >= mDeviceConfigFacade.getHealthMonitorMinRssiThrDbm() - || mLastTxSpeedPoll >= HEALTH_MONITOR_COUNT_TX_SPEED_MIN_MBPS)) { + && isAbnormalDisconnectionReason(mDisconnectionReason) + && passFirmwareAlertCheck + && hasHighRssiOrHighTxSpeed) { mRecentStats.incrementCount(CNT_DISCONNECTION_NONLOCAL); - if (currSessionDurationSec <= SHORT_CONNECTION_DURATION_MAX_SEC) { + if (currSessionDurationMs <= mDeviceConfigFacade + .getHealthMonitorShortConnectionDurationThrMs()) { mRecentStats.incrementCount(CNT_SHORT_CONNECTION_NONLOCAL); } } @@ -968,6 +984,13 @@ public class WifiScoreCard { mConnectionSessionStartTimeMs = TS_NONE; mLastRssiPollTimeMs = TS_NONE; } + + private boolean isAbnormalDisconnectionReason(int disconnectionReason) { + long mask = mDeviceConfigFacade.getAbnormalDisconnectionReasonCodeMask(); + return disconnectionReason >= 0 && disconnectionReason <= 63 + && ((mask >> disconnectionReason) & 0x1) == 0x1; + } + @NonNull NetworkConnectionStats getRecentStats() { return mRecentStats; } diff --git a/service/proto/src/metrics.proto b/service/proto/src/metrics.proto index 01ad65093..e7c0ec89a 100644 --- a/service/proto/src/metrics.proto +++ b/service/proto/src/metrics.proto @@ -2140,6 +2140,9 @@ message ExperimentValues { // Threshold of CCA level above which to trigger a data stall in percentage optional int32 data_stall_cca_level_thr = 9; + + // Health monitor RSSI poll valid time in ms + optional int32 health_monitor_rssi_poll_valid_time_ms = 10; } message BssidBlocklistStats { diff --git a/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java b/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java index ce3eed098..bb03d42d7 100644 --- a/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java +++ b/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java @@ -84,6 +84,12 @@ public class DeviceConfigFacadeTest extends WifiBaseTest { return def; } }); + when(DeviceConfig.getLong(anyString(), anyString(), anyLong())) + .then(new AnswerWithArguments() { + public long answer(String namespace, String field, long def) { + return def; + } + }); when(DeviceConfig.getString(anyString(), anyString(), anyString())) .then(new AnswerWithArguments() { public String answer(String namespace, String field, String def) { @@ -187,6 +193,18 @@ public class DeviceConfigFacadeTest extends WifiBaseTest { mDeviceConfigFacade.getTxLinkSpeedLowThresholdMbps()); assertEquals(DeviceConfigFacade.DEFAULT_RX_LINK_SPEED_LOW_THRESHOLD_MBPS, mDeviceConfigFacade.getRxLinkSpeedLowThresholdMbps()); + assertEquals(DeviceConfigFacade.DEFAULT_HEALTH_MONITOR_RSSI_POLL_VALID_TIME_MS, + mDeviceConfigFacade.getHealthMonitorRssiPollValidTimeMs()); + assertEquals(DeviceConfigFacade.DEFAULT_HEALTH_MONITOR_SHORT_CONNECTION_DURATION_THR_MS, + mDeviceConfigFacade.getHealthMonitorShortConnectionDurationThrMs()); + assertEquals(DeviceConfigFacade.DEFAULT_ABNORMAL_DISCONNECTION_REASON_CODE_MASK, + mDeviceConfigFacade.getAbnormalDisconnectionReasonCodeMask()); + assertEquals(DeviceConfigFacade.DEFAULT_NONSTATIONARY_SCAN_RSSI_VALID_TIME_MS, + mDeviceConfigFacade.getNonstationaryScanRssiValidTimeMs()); + assertEquals(DeviceConfigFacade.DEFAULT_STATIONARY_SCAN_RSSI_VALID_TIME_MS, + mDeviceConfigFacade.getStationaryScanRssiValidTimeMs()); + assertEquals(DeviceConfigFacade.DEFAULT_HEALTH_MONITOR_FW_ALERT_VALID_TIME_MS, + mDeviceConfigFacade.getHealthMonitorFwAlertValidTimeMs()); } /** @@ -277,7 +295,18 @@ public class DeviceConfigFacadeTest extends WifiBaseTest { anyInt())).thenReturn(9); when(DeviceConfig.getInt(anyString(), eq("rx_link_speed_low_threshold_mbps"), anyInt())).thenReturn(10); - + when(DeviceConfig.getInt(anyString(), eq("health_monitor_short_connection_duration_thr_ms"), + anyInt())).thenReturn(30_000); + when(DeviceConfig.getLong(anyString(), eq("abnormal_disconnection_reason_code_mask"), + anyLong())).thenReturn(0xffff_fff3_0000_ffffL); + when(DeviceConfig.getInt(anyString(), eq("health_monitor_rssi_poll_valid_time_ms"), + anyInt())).thenReturn(2000); + when(DeviceConfig.getInt(anyString(), eq("nonstationary_scan_rssi_valid_time_ms"), + anyInt())).thenReturn(4000); + when(DeviceConfig.getInt(anyString(), eq("stationary_scan_rssi_valid_time_ms"), + anyInt())).thenReturn(3000); + when(DeviceConfig.getInt(anyString(), eq("health_monitor_fw_alert_valid_time_ms"), + anyInt())).thenReturn(1000); mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null); // Verifying fields are updated to the new values @@ -326,5 +355,13 @@ public class DeviceConfigFacadeTest extends WifiBaseTest { assertEquals(50000, mDeviceConfigFacade.getOverlappingConnectionDurationThresholdMs()); assertEquals(9, mDeviceConfigFacade.getTxLinkSpeedLowThresholdMbps()); assertEquals(10, mDeviceConfigFacade.getRxLinkSpeedLowThresholdMbps()); + assertEquals(30_000, + mDeviceConfigFacade.getHealthMonitorShortConnectionDurationThrMs()); + assertEquals(0xffff_fff3_0000_ffffL, + mDeviceConfigFacade.getAbnormalDisconnectionReasonCodeMask()); + assertEquals(2000, mDeviceConfigFacade.getHealthMonitorRssiPollValidTimeMs()); + assertEquals(4000, mDeviceConfigFacade.getNonstationaryScanRssiValidTimeMs()); + assertEquals(3000, mDeviceConfigFacade.getStationaryScanRssiValidTimeMs()); + assertEquals(1000, mDeviceConfigFacade.getHealthMonitorFwAlertValidTimeMs()); } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java index c89fe675a..e72f80887 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiDiagnosticsTest.java @@ -73,6 +73,7 @@ public class WifiDiagnosticsTest extends WifiBaseTest { @Mock WifiMetrics mWifiMetrics; @Mock Clock mClock; @Mock BugreportManager mBugreportManager; + @Mock WifiScoreCard mWifiScoreCard; private long mBootTimeMs = 0L; MockResources mResources; WifiDiagnostics mWifiDiagnostics; @@ -136,6 +137,7 @@ public class WifiDiagnosticsTest extends WifiBaseTest { when(mWifiInjector.getJavaRuntime()).thenReturn(mJavaRuntime); when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics); when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade); + when(mWifiInjector.getWifiScoreCard()).thenReturn(mWifiScoreCard); when(mDeviceConfigFacade.getBugReportMinWindowMs()).thenReturn(BUG_REPORT_MIN_WINDOW_MS); // needed to for the loop in WifiDiagnostics.readLogcatStreamLinesWithTimeout(). doAnswer(new AnswerWithArguments() { @@ -744,6 +746,7 @@ public class WifiDiagnosticsTest extends WifiBaseTest { assertArrayEquals(ALERT_DATA, alertReport.alertData); verify(mWifiMetrics).logFirmwareAlert(ALERT_REASON_CODE); + verify(mWifiScoreCard).noteFirmwareAlert(ALERT_REASON_CODE); } /** Verifies that we skip the firmware and driver dumps if verbose is not enabled. */ diff --git a/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java b/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java index 264fe9048..8bf1e2a4a 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiHealthMonitorTest.java @@ -200,6 +200,18 @@ public class WifiHealthMonitorTest extends WifiBaseTest { DeviceConfigFacade.DEFAULT_HEALTH_MONITOR_RATIO_THR_NUMERATOR); when(mDeviceConfigFacade.getHealthMonitorMinNumConnectionAttempt()).thenReturn( DeviceConfigFacade.DEFAULT_HEALTH_MONITOR_MIN_NUM_CONNECTION_ATTEMPT); + when(mDeviceConfigFacade.getHealthMonitorShortConnectionDurationThrMs()).thenReturn( + DeviceConfigFacade.DEFAULT_HEALTH_MONITOR_SHORT_CONNECTION_DURATION_THR_MS); + when(mDeviceConfigFacade.getAbnormalDisconnectionReasonCodeMask()).thenReturn( + DeviceConfigFacade.DEFAULT_ABNORMAL_DISCONNECTION_REASON_CODE_MASK); + when(mDeviceConfigFacade.getHealthMonitorRssiPollValidTimeMs()).thenReturn( + DeviceConfigFacade.DEFAULT_HEALTH_MONITOR_RSSI_POLL_VALID_TIME_MS); + when(mDeviceConfigFacade.getHealthMonitorFwAlertValidTimeMs()).thenReturn( + DeviceConfigFacade.DEFAULT_HEALTH_MONITOR_FW_ALERT_VALID_TIME_MS); + when(mDeviceConfigFacade.getNonstationaryScanRssiValidTimeMs()).thenReturn( + DeviceConfigFacade.DEFAULT_NONSTATIONARY_SCAN_RSSI_VALID_TIME_MS); + when(mDeviceConfigFacade.getStationaryScanRssiValidTimeMs()).thenReturn( + DeviceConfigFacade.DEFAULT_STATIONARY_SCAN_RSSI_VALID_TIME_MS); mWifiHealthMonitor = new WifiHealthMonitor(mContext, mWifiInjector, mClock, mWifiConfigManager, mWifiScoreCard, new Handler(mLooper.getLooper()), mWifiNative, "some seed", mDeviceConfigFacade); @@ -294,7 +306,7 @@ public class WifiHealthMonitorTest extends WifiBaseTest { millisecondsPass(1000); mWifiScoreCard.noteSignalPoll(mWifiInfo); millisecondsPass(2000); - int disconnectionReason = 3; + int disconnectionReason = 0; mWifiScoreCard.noteNonlocalDisconnect(disconnectionReason); millisecondsPass(10); mWifiScoreCard.resetConnectionState(); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java b/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java index 1ad767c6e..e5739a1c8 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiScoreCardTest.java @@ -104,7 +104,6 @@ public class WifiScoreCardTest extends WifiBaseTest { void millisecondsPass(long ms) { mMilliSecondsSinceBoot += ms; when(mClock.getElapsedSinceBootMillis()).thenReturn(mMilliSecondsSinceBoot); - when(mClock.getWallClockMillis()).thenReturn(mMilliSecondsSinceBoot + 1_500_000_000_000L); } void secondsPass(long s) { @@ -158,6 +157,13 @@ 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.getHealthMonitorShortConnectionDurationThrMs()).thenReturn( + DeviceConfigFacade.DEFAULT_HEALTH_MONITOR_SHORT_CONNECTION_DURATION_THR_MS); + when(mDeviceConfigFacade.getAbnormalDisconnectionReasonCodeMask()).thenReturn( + DeviceConfigFacade.DEFAULT_ABNORMAL_DISCONNECTION_REASON_CODE_MASK); + when(mDeviceConfigFacade.getHealthMonitorRssiPollValidTimeMs()).thenReturn(3000); + // Disable FW alert time check by default + when(mDeviceConfigFacade.getHealthMonitorFwAlertValidTimeMs()).thenReturn(-1); when(mDeviceConfigFacade.getBugReportThresholdExtraRatio()).thenReturn(1); mWifiScoreCard.enableVerboseLogging(true); } @@ -916,7 +922,7 @@ public class WifiScoreCardTest extends WifiBaseTest { // Disconnect from SSID_1 millisecondsPass(100); - int disconnectionReason = 3; + int disconnectionReason = 4; mWifiScoreCard.noteNonlocalDisconnect(disconnectionReason); millisecondsPass(100); mWifiScoreCard.resetConnectionState(); @@ -954,7 +960,7 @@ public class WifiScoreCardTest extends WifiBaseTest { checkShortConnectionExample(dailyStats, 0); } - private void makeShortConnectionExample() { + private void makeShortConnectionExample(boolean addFwAlert) { mWifiScoreCard.noteConnectionAttempt(mWifiInfo, -53, mWifiInfo.getSSID()); millisecondsPass(5000); mWifiInfo.setTxLinkSpeedMbps(100); @@ -964,8 +970,11 @@ public class WifiScoreCardTest extends WifiBaseTest { millisecondsPass(1000); mWifiScoreCard.noteSignalPoll(mWifiInfo); millisecondsPass(2000); - int disconnectionReason = 3; + int disconnectionReason = 34; mWifiScoreCard.noteNonlocalDisconnect(disconnectionReason); + if (addFwAlert) { + mWifiScoreCard.noteFirmwareAlert(6); + } millisecondsPass(1000); mWifiScoreCard.resetConnectionState(); } @@ -1007,12 +1016,13 @@ public class WifiScoreCardTest extends WifiBaseTest { } /** - * Check network stats after RSSI poll and disconnection. + * Check network stats after RSSI poll and disconnection, pass FW alert check */ @Test - public void testNetworkRssiPollShortNonlocalDisconnection() throws Exception { + public void testNetworkRssiPollShortNonlocalDisconnectionPassFwAlertCheck() throws Exception { + when(mDeviceConfigFacade.getHealthMonitorFwAlertValidTimeMs()).thenReturn(2000); // 1st connection session - makeShortConnectionExample(); + makeShortConnectionExample(/*addFwAlert*/true); // 2nd connection session makeNormalConnectionExample(); @@ -1029,6 +1039,23 @@ public class WifiScoreCardTest extends WifiBaseTest { } /** + * Check network stats after RSSI poll and disconnection, fail FW alert check + */ + @Test + public void testNetworkRssiPollShortNonlocalDisconnectionFailFwAlertCheck() throws Exception { + when(mDeviceConfigFacade.getHealthMonitorFwAlertValidTimeMs()).thenReturn(2000); + // 1st connection session + makeShortConnectionExample(/*addFwAlert*/false); + // 2nd connection session + makeNormalConnectionExample(); + + PerNetwork perNetwork = mWifiScoreCard.fetchByNetwork(mWifiInfo.getSSID()); + NetworkConnectionStats dailyStats = perNetwork.getRecentStats(); + assertEquals(0, dailyStats.getCount(CNT_SHORT_CONNECTION_NONLOCAL)); + assertEquals(0, dailyStats.getCount(CNT_DISCONNECTION_NONLOCAL)); + } + + /** * Check network stats after short connection with an old RSSI polling */ @Test @@ -1130,7 +1157,7 @@ public class WifiScoreCardTest extends WifiBaseTest { @Test public void testUpdateAfterDailyDetection() throws Exception { for (int i = 0; i < DEFAULT_HEALTH_MONITOR_MIN_NUM_CONNECTION_ATTEMPT; i++) { - makeShortConnectionExample(); + makeShortConnectionExample(/*addFwAlert*/false); } PerNetwork perNetwork = mWifiScoreCard.fetchByNetwork(mWifiInfo.getSSID()); @@ -1145,7 +1172,7 @@ public class WifiScoreCardTest extends WifiBaseTest { @Test public void testUpdateAfterSwBuildChange() throws Exception { for (int i = 0; i < DEFAULT_HEALTH_MONITOR_MIN_NUM_CONNECTION_ATTEMPT; i++) { - makeShortConnectionExample(); + makeShortConnectionExample(/*addFwAlert*/false); } PerNetwork perNetwork = mWifiScoreCard.fetchByNetwork(mWifiInfo.getSSID()); perNetwork.updateAfterDailyDetection(); @@ -1165,7 +1192,7 @@ public class WifiScoreCardTest extends WifiBaseTest { private void makeRecentStatsWithShortConnection() { for (int i = 0; i < DEFAULT_HEALTH_MONITOR_MIN_NUM_CONNECTION_ATTEMPT; i++) { - makeShortConnectionExample(); + makeShortConnectionExample(/*addFwAlert*/false); } } @@ -1196,7 +1223,7 @@ public class WifiScoreCardTest extends WifiBaseTest { @Test public void testDailyDetectionWithInsufficientRecentStats() throws Exception { PerNetwork perNetwork = mWifiScoreCard.lookupNetwork(mWifiInfo.getSSID()); - makeShortConnectionExample(); + makeShortConnectionExample(/*addFwAlert*/false); FailureStats statsDec = new FailureStats(); FailureStats statsInc = new FailureStats(); @@ -1269,7 +1296,7 @@ public class WifiScoreCardTest extends WifiBaseTest { makeRecentStatsWithGoodConnection(); // Add a small number of failures for each failure type after the SW build change for (int i = 0; i < mDeviceConfigFacade.getAuthFailureCountMin() - 1; i++) { - makeShortConnectionExample(); + makeShortConnectionExample(/*addFwAlert*/false); makeAssocTimeOutExample(); makeAuthFailureExample(); } |