diff options
6 files changed, 82 insertions, 5 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index 99fa7f585..68c8aee23 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -2904,7 +2904,16 @@ public class ClientModeImpl extends StateMachine { */ private void reportConnectionAttemptStart( WifiConfiguration config, String targetBSSID, int roamType) { - mWifiMetrics.startConnectionEvent(config, targetBSSID, roamType); + int overlapWithLastConnectionMs = + mWifiMetrics.startConnectionEvent(config, targetBSSID, roamType); + DeviceConfigFacade deviceConfigFacade = mWifiInjector.getDeviceConfigFacade(); + if (deviceConfigFacade.isOverlappingConnectionBugreportEnabled() + && overlapWithLastConnectionMs + > deviceConfigFacade.getOverlappingConnectionDurationThresholdMs()) { + String bugTitle = "Wi-Fi BugReport"; + String bugDetail = "Detect abnormal overlapping connection"; + takeBugReport(bugTitle, bugDetail); + } mWifiDiagnostics.reportConnectionEvent(WifiDiagnostics.CONNECTION_EVENT_STARTED); mWrongPasswordNotifier.onNewConnectionAttempt(); removeMessages(CMD_DIAGS_CONNECT_TIMEOUT); diff --git a/service/java/com/android/server/wifi/DeviceConfigFacade.java b/service/java/com/android/server/wifi/DeviceConfigFacade.java index 67cc01ce9..d25a50a10 100644 --- a/service/java/com/android/server/wifi/DeviceConfigFacade.java +++ b/service/java/com/android/server/wifi/DeviceConfigFacade.java @@ -95,6 +95,8 @@ public class DeviceConfigFacade { // 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; + // Default overlapping connection duration threshold in ms to trigger bug report + static final int DEFAULT_OVERLAPPING_CONNECTION_DURATION_THRESHOLD_MS = 75_000; // Cached values of fields updated via updateDeviceConfigFlags() private boolean mIsAbnormalConnectionBugreportEnabled; @@ -132,6 +134,8 @@ public class DeviceConfigFacade { private int mHealthMonitorMinNumConnectionAttempt; private int mBugReportMinWindowMs; private int mBugReportThresholdExtraRatio; + private boolean mIsOverlappingConnectionBugreportEnabled; + private int mOverlappingConnectionDurationThresholdMs; public DeviceConfigFacade(Context context, Handler handler, WifiMetrics wifiMetrics) { mContext = context; @@ -245,6 +249,11 @@ public class DeviceConfigFacade { mBugReportThresholdExtraRatio = DeviceConfig.getInt(NAMESPACE, "report_bug_report_threshold_extra_ratio", DEFAULT_BUG_REPORT_THRESHOLD_EXTRA_RATIO); + mIsOverlappingConnectionBugreportEnabled = DeviceConfig.getBoolean(NAMESPACE, + "overlapping_connection_bugreport_enabled", false); + mOverlappingConnectionDurationThresholdMs = DeviceConfig.getInt(NAMESPACE, + "overlapping_connection_duration_threshold_ms", + DEFAULT_OVERLAPPING_CONNECTION_DURATION_THRESHOLD_MS); } private Set<String> getUnmodifiableSetQuoted(String key) { @@ -508,4 +517,18 @@ public class DeviceConfigFacade { public int getBugReportThresholdExtraRatio() { return mBugReportThresholdExtraRatio; } + + /** + * Gets the feature flag for reporting overlapping connection. + */ + public boolean isOverlappingConnectionBugreportEnabled() { + return mIsOverlappingConnectionBugreportEnabled; + } + + /** + * Gets overlapping connection duration threshold in ms + */ + public int getOverlappingConnectionDurationThresholdMs() { + return mOverlappingConnectionDurationThresholdMs; + } } diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java index 031c495cc..03c824968 100644 --- a/service/java/com/android/server/wifi/WifiMetrics.java +++ b/service/java/com/android/server/wifi/WifiMetrics.java @@ -1390,18 +1390,24 @@ public class WifiMetrics { private static final int SCREEN_OFF = 0; /** - * Create a new connection event. Call when wifi attempts to make a new network connection + * Create a new connection event and check if the new one overlaps with previous one. + * Call when wifi attempts to make a new network connection * If there is a current 'un-ended' connection event, it will be ended with UNKNOWN connectivity * failure code. * Gathers and sets the RouterFingerPrint data as well * * @param config WifiConfiguration of the config used for the current connection attempt * @param roamType Roam type that caused connection attempt, see WifiMetricsProto.WifiLog.ROAM_X + * @return The duration in ms since the last unfinished connection attempt, + * or 0 if there is no unfinished connection */ - public void startConnectionEvent(WifiConfiguration config, String targetBSSID, int roamType) { + public int startConnectionEvent( + WifiConfiguration config, String targetBSSID, int roamType) { synchronized (mLock) { - // Check if this is overlapping another current connection event + int overlapWithLastConnectionMs = 0; if (mCurrentConnectionEvent != null) { + overlapWithLastConnectionMs = (int) (mClock.getElapsedSinceBootMillis() + - mCurrentConnectionEvent.mRealStartTime); //Is this new Connection Event the same as the current one if (mCurrentConnectionEvent.mConfigSsid != null && mCurrentConnectionEvent.mConfigBssid != null @@ -1505,6 +1511,7 @@ public class WifiMetrics { recentStats.getCount(WifiScoreCard.CNT_CONSECUTIVE_CONNECTION_FAILURE); } } + return overlapWithLastConnectionMs; } } diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java index 66bde2fc0..2923315d6 100644 --- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java @@ -557,6 +557,9 @@ public class ClientModeImplTest extends WifiBaseTest { when(mWifiScoreCard.getL2KeyAndGroupHint(any())).thenReturn(new Pair<>(null, null)); when(mDeviceConfigFacade.isAbnormalDisconnectionBugreportEnabled()).thenReturn(true); when(mDeviceConfigFacade.isAbnormalConnectionFailureBugreportEnabled()).thenReturn(true); + when(mDeviceConfigFacade.isOverlappingConnectionBugreportEnabled()).thenReturn(true); + when(mDeviceConfigFacade.getOverlappingConnectionDurationThresholdMs()).thenReturn( + DeviceConfigFacade.DEFAULT_OVERLAPPING_CONNECTION_DURATION_THRESHOLD_MS); when(mWifiScoreCard.detectAbnormalConnectionFailure(anyString())) .thenReturn(WifiHealthMonitor.REASON_NO_FAILURE); when(mWifiScoreCard.detectAbnormalDisconnection()) @@ -1744,6 +1747,7 @@ public class ClientModeImplTest extends WifiBaseTest { */ @Test public void testEapSimErrorVendorSpecific() throws Exception { + when(mWifiMetrics.startConnectionEvent(any(), anyString(), anyInt())).thenReturn(80000); initializeAndAddNetworkAndVerifySuccess(); IActionListener connectActionListener = mock(IActionListener.class); @@ -1778,7 +1782,7 @@ public class ClientModeImplTest extends WifiBaseTest { mockSession.finishMocking(); verify(mDeviceConfigFacade).isAbnormalConnectionFailureBugreportEnabled(); verify(mWifiScoreCard).detectAbnormalConnectionFailure(anyString()); - verify(mWifiDiagnostics).takeBugReport(anyString(), anyString()); + verify(mWifiDiagnostics, times(2)).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 b7136d986..e6b169960 100644 --- a/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java +++ b/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java @@ -176,6 +176,9 @@ public class DeviceConfigFacadeTest extends WifiBaseTest { mDeviceConfigFacade.getHealthMonitorMinNumConnectionAttempt()); assertEquals(DeviceConfigFacade.DEFAULT_BUG_REPORT_MIN_WINDOW_MS, mDeviceConfigFacade.getBugReportMinWindowMs()); + assertEquals(false, mDeviceConfigFacade.isOverlappingConnectionBugreportEnabled()); + assertEquals(DeviceConfigFacade.DEFAULT_OVERLAPPING_CONNECTION_DURATION_THRESHOLD_MS, + mDeviceConfigFacade.getOverlappingConnectionDurationThresholdMs()); } /** @@ -254,6 +257,10 @@ public class DeviceConfigFacadeTest extends WifiBaseTest { anyInt())).thenReturn(20); when(DeviceConfig.getInt(anyString(), eq("bug_report_min_window_ms"), anyInt())).thenReturn(1000); + when(DeviceConfig.getBoolean(anyString(), eq("overlapping_connection_bugreport_enabled"), + anyBoolean())).thenReturn(true); + when(DeviceConfig.getInt(anyString(), eq("overlapping_connection_duration_threshold_ms"), + anyInt())).thenReturn(50000); mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null); @@ -297,5 +304,7 @@ public class DeviceConfigFacadeTest extends WifiBaseTest { assertEquals(true, mDeviceConfigFacade.isAbnormalDisconnectionBugreportEnabled()); assertEquals(20, mDeviceConfigFacade.getHealthMonitorMinNumConnectionAttempt()); assertEquals(1000, mDeviceConfigFacade.getBugReportMinWindowMs()); + assertEquals(true, mDeviceConfigFacade.isOverlappingConnectionBugreportEnabled()); + assertEquals(50000, mDeviceConfigFacade.getOverlappingConnectionDurationThresholdMs()); } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java index f03d094cb..5b5cc7dfe 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java @@ -4834,4 +4834,29 @@ public class WifiMetricsTest extends WifiBaseTest { assertHistogramBucketsEqual(expectedFailureScanHistogram, mDecodedProto.initPartialScanStats.failedScanChannelCountHistogram); } + + /** + * Test overlapping and non-overlapping connection events return overlapping duration correctly + */ + @Test + public void testOverlappingConnectionEvent() throws Exception { + // Connection event 1 + when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 0); + mWifiMetrics.startConnectionEvent(mTestWifiConfig, "TestNetwork", + WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE); + when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 1000); + // Connection event 2 overlaps with 1 + assertEquals(1000, mWifiMetrics.startConnectionEvent(mTestWifiConfig, "TestNetwork", + WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE)); + + // Connection event 2 ends + mWifiMetrics.endConnectionEvent( + WifiMetrics.ConnectionEvent.FAILURE_NONE, + WifiMetricsProto.ConnectionEvent.HLF_NONE, + WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN); + when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 2000); + // Connection event 3 doesn't overlap with 2 + assertEquals(0, mWifiMetrics.startConnectionEvent(mTestWifiConfig, "TestNetwork", + WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE)); + } } |