summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java11
-rw-r--r--service/java/com/android/server/wifi/DeviceConfigFacade.java23
-rw-r--r--service/java/com/android/server/wifi/WifiMetrics.java13
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java6
-rw-r--r--tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java9
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java25
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));
+ }
}