[WifiScoreReport] synchronize dumpsys
Fix the possibility of a concurrent modification exception during
dumpsys handling.
Bug: 69064836
Test: unit tests
Change-Id: Ib9de18b1b02bff1fade59b7642042e73d1ab3511
diff --git a/service/java/com/android/server/wifi/WifiScoreReport.java b/service/java/com/android/server/wifi/WifiScoreReport.java
index af53850..e5281ef 100644
--- a/service/java/com/android/server/wifi/WifiScoreReport.java
+++ b/service/java/com/android/server/wifi/WifiScoreReport.java
@@ -179,19 +179,23 @@
double txRetriesRate = wifiInfo.txRetriesRate;
double txBadRate = wifiInfo.txBadRate;
double rxSuccessRate = wifiInfo.rxSuccessRate;
+ String s;
try {
String timestamp = new SimpleDateFormat("MM-dd HH:mm:ss.SSS").format(new Date(now));
- String s = String.format(Locale.US, // Use US to avoid comma/decimal confusion
+ s = String.format(Locale.US, // Use US to avoid comma/decimal confusion
"%s,%d,%.1f,%.1f,%.1f,%d,%d,%.2f,%.2f,%.2f,%.2f,%d,%d,%d",
timestamp, mSessionNumber, rssi, filteredRssi, rssiThreshold, freq, linkSpeed,
txSuccessRate, txRetriesRate, txBadRate, rxSuccessRate,
s0, s1, s2);
- mLinkMetricsHistory.add(s);
} catch (Exception e) {
Log.e(TAG, "format problem", e);
+ return;
}
- while (mLinkMetricsHistory.size() > DUMPSYS_ENTRY_COUNT_LIMIT) {
- mLinkMetricsHistory.removeFirst();
+ synchronized (mLinkMetricsHistory) {
+ mLinkMetricsHistory.add(s);
+ while (mLinkMetricsHistory.size() > DUMPSYS_ENTRY_COUNT_LIMIT) {
+ mLinkMetricsHistory.removeFirst();
+ }
}
}
@@ -207,10 +211,15 @@
* @param args unused
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ LinkedList<String> history;
+ synchronized (mLinkMetricsHistory) {
+ history = new LinkedList<>(mLinkMetricsHistory);
+ }
pw.println("time,session,rssi,filtered_rssi,rssi_threshold,"
+ "freq,linkspeed,tx_good,tx_retry,tx_bad,rx,s0,s1,s2");
- for (String line : mLinkMetricsHistory) {
+ for (String line : history) {
pw.println(line);
}
+ history.clear();
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
index c334e7c..022d5dd 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
@@ -17,10 +17,13 @@
package com.android.server.wifi;
import static org.junit.Assert.assertTrue;
+import static org.mockito.AdditionalAnswers.answerVoid;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -266,6 +269,21 @@
}
/**
+ * This setup causes some reports to be generated when println
+ * methods are called, to check for "concurrent" modification
+ * errors.
+ */
+ private void setupToGenerateAReportWhenPrintlnIsCalled() {
+ int[] counter = new int[1];
+ doAnswer(answerVoid((String line) -> {
+ if (counter[0]++ < 3) {
+ mWifiScoreReport.calculateAndReportScore(
+ mWifiInfo, mNetworkAgent, mAggr, mWifiMetrics);
+ }
+ })).when(mPrintWriter).println(anyString());
+ }
+
+ /**
* Test data logging
*/
@Test
@@ -281,8 +299,9 @@
mWifiInfo.rxSuccessRate = 0.3 + i;
mWifiScoreReport.calculateAndReportScore(mWifiInfo, mNetworkAgent, mAggr, mWifiMetrics);
}
+ setupToGenerateAReportWhenPrintlnIsCalled();
mWifiScoreReport.dump(null, mPrintWriter, null);
- verify(mPrintWriter, atLeast(11)).println(anyString());
+ verify(mPrintWriter, times(11)).println(anyString());
}
/**