diff options
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(); } |