summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java4
-rw-r--r--service/java/com/android/server/wifi/LinkProbeManager.java152
-rw-r--r--service/java/com/android/server/wifi/WifiMetrics.java44
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java6
-rw-r--r--tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java22
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java29
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiMetricsTestUtil.java38
7 files changed, 260 insertions, 35 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index e7de1ca4f..59d72d30f 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -4917,7 +4917,7 @@ public class ClientModeImpl extends StateMachine {
public void enter() {
mRssiPollToken++;
if (mEnableRssiPolling) {
- mLinkProbeManager.reset();
+ mLinkProbeManager.resetOnNewConnection();
sendMessage(CMD_RSSI_POLL, mRssiPollToken, 0);
}
if (mNetworkAgent != null) {
@@ -5139,7 +5139,7 @@ public class ClientModeImpl extends StateMachine {
if (mEnableRssiPolling) {
// First poll
mLastSignalLevel = -1;
- mLinkProbeManager.reset();
+ mLinkProbeManager.resetOnScreenTurnedOn();
fetchRssiLinkSpeedAndFrequencyNative();
sendMessageDelayed(obtainMessage(CMD_RSSI_POLL, mRssiPollToken, 0),
mPollRssiIntervalMsecs);
diff --git a/service/java/com/android/server/wifi/LinkProbeManager.java b/service/java/com/android/server/wifi/LinkProbeManager.java
index ff26991f1..b91ba67f4 100644
--- a/service/java/com/android/server/wifi/LinkProbeManager.java
+++ b/service/java/com/android/server/wifi/LinkProbeManager.java
@@ -30,6 +30,8 @@ import com.android.internal.annotations.VisibleForTesting;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
/**
* Tracks state that decides if a link probe should be performed. If so, trigger a link probe to
@@ -48,6 +50,10 @@ public class LinkProbeManager {
@VisibleForTesting
static final long LINK_PROBE_INTERVAL_MS = 15 * 1000;
+ @VisibleForTesting
+ static final int[] EXPERIMENT_DELAYS_MS = {3000, 6000, 9000, 12000, 15000};
+ private List<Experiment> mExperiments = new ArrayList<>();
+
private final Clock mClock;
private final WifiNative mWifiNative;
private final WifiMetrics mWifiMetrics;
@@ -63,7 +69,7 @@ public class LinkProbeManager {
/**
* Tracks the last timestamp when wifiInfo.txSuccess was increased i.e. the last time a Tx was
* successful. Link probing only occurs when at least {@link #LINK_PROBE_INTERVAL_MS} has passed
- * since the last Tx succcess.
+ * since the last Tx success.
* This is also reset to the current time when {@link #reset()} is called, so that a link probe
* only occurs at least {@link #LINK_PROBE_INTERVAL_MS} after a new connection is made.
*/
@@ -79,19 +85,22 @@ public class LinkProbeManager {
mContext = context;
mLinkProbingSupported = mContext.getResources()
.getBoolean(R.bool.config_wifi_link_probing_supported);
- if (!mLinkProbingSupported) return;
- mFrameworkFacade.registerContentObserver(mContext, Settings.Global.getUriFor(
- Settings.Global.WIFI_LINK_PROBING_ENABLED), false,
- new ContentObserver(new Handler(looper)) {
- @Override
- public void onChange(boolean selfChange) {
- updateLinkProbeSetting();
- }
- });
- updateLinkProbeSetting();
+ if (mLinkProbingSupported) {
+ mFrameworkFacade.registerContentObserver(mContext, Settings.Global.getUriFor(
+ Settings.Global.WIFI_LINK_PROBING_ENABLED), false,
+ new ContentObserver(new Handler(looper)) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateLinkProbeSetting();
+ }
+ });
+ updateLinkProbeSetting();
- reset();
+ reset();
+ }
+
+ initExperiments();
}
private void updateLinkProbeSetting() {
@@ -117,11 +126,7 @@ public class LinkProbeManager {
pw.println("LinkProbeManager - mLastTxSuccessCount: " + mLastTxSuccessCount);
}
- /**
- * When connecting to a different network or when RSSI poll events are stopped and restarted,
- * reset internal state.
- */
- public void reset() {
+ private void reset() {
if (!mLinkProbingSupported) return;
long now = mClock.getElapsedSinceBootMillis();
@@ -131,6 +136,23 @@ public class LinkProbeManager {
}
/**
+ * When connecting to a new network, reset internal state.
+ */
+ public void resetOnNewConnection() {
+ mExperiments.forEach(Experiment::resetOnNewConnection);
+ reset();
+ }
+
+ /**
+ * When RSSI poll events are stopped and restarted (usually screen turned off then back on),
+ * reset internal state.
+ */
+ public void resetOnScreenTurnedOn() {
+ mExperiments.forEach(Experiment::resetOnScreenTurnedOn);
+ reset();
+ }
+
+ /**
* Based on network conditions provided by WifiInfo, decides if a link probe should be
* performed. If so, trigger a link probe and report the results to WifiMetrics.
*
@@ -138,6 +160,8 @@ public class LinkProbeManager {
* @param interfaceName the interface that the link probe should be performed on, if applicable.
*/
public void updateConnectionStats(WifiInfo wifiInfo, String interfaceName) {
+ mExperiments.forEach(e -> e.updateConnectionStats(wifiInfo));
+
if (!mLinkProbingSupported) return;
long now = mClock.getElapsedSinceBootMillis();
@@ -209,4 +233,98 @@ public class LinkProbeManager {
mLastLinkProbeTimestampMs = mClock.getElapsedSinceBootMillis();
}
+
+ private void initExperiments() {
+ for (int screenOnDelayMs : EXPERIMENT_DELAYS_MS) {
+ for (int noTxDelayMs : EXPERIMENT_DELAYS_MS) {
+ for (int delayBetweenProbesMs : EXPERIMENT_DELAYS_MS) {
+ Experiment experiment = new Experiment(mClock, mWifiMetrics,
+ screenOnDelayMs, noTxDelayMs, delayBetweenProbesMs);
+ mExperiments.add(experiment);
+ }
+ }
+ }
+ }
+
+ // TODO(b/131091030): remove once experiment is over
+ private static class Experiment {
+
+ private final Clock mClock;
+ private final WifiMetrics mWifiMetrics;
+ private final int mScreenOnDelayMs;
+ private final int mNoTxDelayMs;
+ private final int mDelayBetweenProbesMs;
+ private final String mExperimentId;
+
+ private long mLastLinkProbeTimestampMs;
+ private long mLastTxSuccessIncreaseTimestampMs;
+ private long mLastTxSuccessCount;
+
+ Experiment(Clock clock, WifiMetrics wifiMetrics,
+ int screenOnDelayMs, int noTxDelayMs, int delayBetweenProbesMs) {
+ mClock = clock;
+ mWifiMetrics = wifiMetrics;
+ mScreenOnDelayMs = screenOnDelayMs;
+ mNoTxDelayMs = noTxDelayMs;
+ mDelayBetweenProbesMs = delayBetweenProbesMs;
+
+ mExperimentId = getExperimentId();
+
+ resetOnNewConnection();
+ }
+
+ private String getExperimentId() {
+ return "[screenOnDelay=" + mScreenOnDelayMs + ','
+ + "noTxDelay=" + mNoTxDelayMs + ','
+ + "delayBetweenProbes=" + mDelayBetweenProbesMs + ']';
+ }
+
+ void resetOnNewConnection() {
+ long now = mClock.getElapsedSinceBootMillis();
+ mLastLinkProbeTimestampMs = now;
+ mLastTxSuccessIncreaseTimestampMs = now;
+ mLastTxSuccessCount = 0;
+ }
+
+ void resetOnScreenTurnedOn() {
+ long now = mClock.getElapsedSinceBootMillis();
+ long firstPossibleLinkProbeAfterScreenOnTimestampMs = now + mScreenOnDelayMs;
+ mLastLinkProbeTimestampMs = Math.max(mLastLinkProbeTimestampMs,
+ firstPossibleLinkProbeAfterScreenOnTimestampMs - mDelayBetweenProbesMs);
+ // don't reset mLastTxSuccessIncreaseTimestampMs and mLastTxSuccessCount since no new
+ // connection was established
+ }
+
+ void updateConnectionStats(WifiInfo wifiInfo) {
+ long now = mClock.getElapsedSinceBootMillis();
+
+ if (mLastTxSuccessCount < wifiInfo.txSuccess) {
+ mLastTxSuccessIncreaseTimestampMs = now;
+ }
+ mLastTxSuccessCount = wifiInfo.txSuccess;
+
+ long timeSinceLastLinkProbeMs = now - mLastLinkProbeTimestampMs;
+ if (timeSinceLastLinkProbeMs < mDelayBetweenProbesMs) {
+ return;
+ }
+
+ // if tx succeeded at least once in the last LINK_PROBE_INTERVAL_MS, don't need to probe
+ long timeSinceLastTxSuccessIncreaseMs = now - mLastTxSuccessIncreaseTimestampMs;
+ if (timeSinceLastTxSuccessIncreaseMs < mNoTxDelayMs) {
+ return;
+ }
+
+ // can skip probing if RSSI is valid and high and link speed is fast
+ int rssi = wifiInfo.getRssi();
+ int linkSpeed = wifiInfo.getLinkSpeed();
+ if (rssi != WifiInfo.INVALID_RSSI && rssi > LINK_PROBE_RSSI_THRESHOLD
+ && linkSpeed > LINK_PROBE_LINK_SPEED_THRESHOLD_MBPS) {
+ return;
+ }
+
+ mWifiMetrics.incrementLinkProbeExperimentProbeCount(mExperimentId);
+
+ mLastLinkProbeTimestampMs = mClock.getElapsedSinceBootMillis();
+ }
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index 8d6a5f1bd..539fe3dee 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -60,6 +60,7 @@ import com.android.server.wifi.nano.WifiMetricsProto.ConnectToNetworkNotificatio
import com.android.server.wifi.nano.WifiMetricsProto.DeviceMobilityStatePnoScanStats;
import com.android.server.wifi.nano.WifiMetricsProto.ExperimentValues;
import com.android.server.wifi.nano.WifiMetricsProto.LinkProbeStats;
+import com.android.server.wifi.nano.WifiMetricsProto.LinkProbeStats.ExperimentProbeCounts;
import com.android.server.wifi.nano.WifiMetricsProto.LinkProbeStats.LinkProbeFailureReasonCount;
import com.android.server.wifi.nano.WifiMetricsProto.LinkSpeedCount;
import com.android.server.wifi.nano.WifiMetricsProto.NetworkSelectionExperimentDecisions;
@@ -86,6 +87,7 @@ import com.android.server.wifi.util.InformationElementUtil;
import com.android.server.wifi.util.IntCounter;
import com.android.server.wifi.util.IntHistogram;
import com.android.server.wifi.util.MetricsUtils;
+import com.android.server.wifi.util.ObjectCounter;
import com.android.server.wifi.util.ScanResultUtil;
import org.json.JSONArray;
@@ -321,6 +323,12 @@ public class WifiMetrics {
LINK_PROBE_ELAPSED_TIME_MS_HISTOGRAM_BUCKETS);
private final IntCounter mLinkProbeFailureReasonCounts = new IntCounter();
+ /**
+ * Maps a String link probe experiment ID to the number of link probes that were sent for this
+ * experiment.
+ */
+ private final ObjectCounter<String> mLinkProbeExperimentProbeCounts = new ObjectCounter<>();
+
private final LinkedList<WifiUsabilityStatsEntry> mWifiUsabilityStatsEntriesList =
new LinkedList<>();
private final LinkedList<WifiUsabilityStats> mWifiUsabilityStatsListBad = new LinkedList<>();
@@ -2749,6 +2757,7 @@ public class WifiMetrics {
pw.println("mLinkProbeSuccessElapsedTimeMsHistogram:"
+ mLinkProbeSuccessElapsedTimeMsHistogram);
pw.println("mLinkProbeFailureReasonCounts:" + mLinkProbeFailureReasonCounts);
+ pw.println("mLinkProbeExperimentProbeCounts:" + mLinkProbeExperimentProbeCounts);
pw.println("mNetworkSelectionExperimentPairNumChoicesCounts:"
+ mNetworkSelectionExperimentPairNumChoicesCounts);
@@ -2774,7 +2783,6 @@ public class WifiMetrics {
+ mWifiLogProto.numAddOrUpdateNetworkCalls);
pw.println("mWifiLogProto.numEnableNetworkCalls="
+ mWifiLogProto.numEnableNetworkCalls);
-
}
}
}
@@ -3261,14 +3269,22 @@ public class WifiMetrics {
mLinkProbeFailureSecondsSinceLastTxSuccessHistogram.toProto();
linkProbeStats.successElapsedTimeMsHistogram =
mLinkProbeSuccessElapsedTimeMsHistogram.toProto();
- linkProbeStats.failureReasonCounts =
- mLinkProbeFailureReasonCounts.toProto(LinkProbeFailureReasonCount.class,
- (reason, count) -> {
- LinkProbeFailureReasonCount c = new LinkProbeFailureReasonCount();
- c.failureReason = linkProbeFailureReasonToProto(reason);
- c.count = count;
- return c;
- });
+ linkProbeStats.failureReasonCounts = mLinkProbeFailureReasonCounts.toProto(
+ LinkProbeFailureReasonCount.class,
+ (reason, count) -> {
+ LinkProbeFailureReasonCount c = new LinkProbeFailureReasonCount();
+ c.failureReason = linkProbeFailureReasonToProto(reason);
+ c.count = count;
+ return c;
+ });
+ linkProbeStats.experimentProbeCounts = mLinkProbeExperimentProbeCounts.toProto(
+ ExperimentProbeCounts.class,
+ (experimentId, probeCount) -> {
+ ExperimentProbeCounts c = new ExperimentProbeCounts();
+ c.experimentId = experimentId;
+ c.probeCount = probeCount;
+ return c;
+ });
mWifiLogProto.linkProbeStats = linkProbeStats;
mWifiLogProto.networkSelectionExperimentDecisionsList =
@@ -3483,6 +3499,7 @@ public class WifiMetrics {
mLinkProbeFailureSecondsSinceLastTxSuccessHistogram.clear();
mLinkProbeSuccessElapsedTimeMsHistogram.clear();
mLinkProbeFailureReasonCounts.clear();
+ mLinkProbeExperimentProbeCounts.clear();
mNetworkSelectionExperimentPairNumChoicesCounts.clear();
mWifiNetworkSuggestionApiLog.clear();
mWifiNetworkSuggestionApiLog.clear();
@@ -4734,6 +4751,15 @@ public class WifiMetrics {
}
/**
+ * Increments the number of probes triggered by the experiment `experimentId`.
+ */
+ public void incrementLinkProbeExperimentProbeCount(String experimentId) {
+ synchronized (mLock) {
+ mLinkProbeExperimentProbeCounts.increment(experimentId);
+ }
+ }
+
+ /**
* Update wifi config store read duration.
*
* @param timeMs Time it took to complete the operation, in milliseconds
diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index 46fce6aa4..69dff1edd 100644
--- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -3274,7 +3274,8 @@ public class ClientModeImplTest {
connect();
// reset() should be called when RSSI polling is enabled and entering L2ConnectedState
- verify(mLinkProbeManager).reset();
+ verify(mLinkProbeManager).resetOnNewConnection(); // called first time here
+ verify(mLinkProbeManager, never()).resetOnScreenTurnedOn(); // not called
verify(mLinkProbeManager).updateConnectionStats(any(), any());
mCmi.enableRssiPolling(false);
@@ -3283,7 +3284,8 @@ public class ClientModeImplTest {
// becomes enabled
mCmi.enableRssiPolling(true);
mLooper.dispatchAll();
- verify(mLinkProbeManager, times(2)).reset();
+ verify(mLinkProbeManager, times(1)).resetOnNewConnection(); // verify not called again
+ verify(mLinkProbeManager).resetOnScreenTurnedOn(); // verify called here
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java b/tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java
index 614ec7e57..35f63149c 100644
--- a/tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java
@@ -16,9 +16,12 @@
package com.android.server.wifi;
+import static junit.framework.Assert.assertEquals;
+
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -40,6 +43,8 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.HashSet;
+
/**
* Unit tests for LinkProbeManager
*/
@@ -102,7 +107,7 @@ public class LinkProbeManagerTest {
*/
@Test
public void testLinkProbeTriggeredAndAcked() throws Exception {
- mLinkProbeManager.reset();
+ mLinkProbeManager.resetOnNewConnection();
// initialize tx success counter
mWifiInfo.txSuccess = 50;
@@ -111,6 +116,7 @@ public class LinkProbeManagerTest {
mLinkProbeManager.updateConnectionStats(mWifiInfo, TEST_IFACE_NAME);
// should not probe yet
verify(mWifiNative, never()).probeLink(any(), any(), any(), anyInt());
+ verify(mWifiMetrics, never()).incrementLinkProbeExperimentProbeCount(any());
// tx success counter did not change since last update
mWifiInfo.txSuccess = 50;
@@ -130,6 +136,12 @@ public class LinkProbeManagerTest {
ArgumentCaptor.forClass(WifiNative.SendMgmtFrameCallback.class);
verify(mWifiNative).probeLink(eq(TEST_IFACE_NAME), any(), callbackCaptor.capture(),
anyInt());
+ ArgumentCaptor<String> experimentIdCaptor = ArgumentCaptor.forClass(String.class);
+ verify(mWifiMetrics, atLeastOnce()).incrementLinkProbeExperimentProbeCount(
+ experimentIdCaptor.capture());
+ int len = LinkProbeManager.EXPERIMENT_DELAYS_MS.length;
+ int numExperimentIds = len * len * len;
+ assertEquals(numExperimentIds, new HashSet<>(experimentIdCaptor.getAllValues()).size());
callbackCaptor.getValue().onAck(TEST_ELAPSED_TIME_MS);
verify(mWifiMetrics).logLinkProbeSuccess(TEST_TIMESTAMP_MS, timeDelta, rssi, linkSpeed,
@@ -142,7 +154,7 @@ public class LinkProbeManagerTest {
*/
@Test
public void testLinkProbeTriggeredAndFailed() throws Exception {
- mLinkProbeManager.reset();
+ mLinkProbeManager.resetOnNewConnection();
// initialize tx success counter
mWifiInfo.txSuccess = 50;
@@ -203,7 +215,7 @@ public class LinkProbeManagerTest {
*/
@Test
public void testLinkProbeNotTriggeredWhenTxSucceeded() throws Exception {
- mLinkProbeManager.reset();
+ mLinkProbeManager.resetOnNewConnection();
// initialize tx success counter
mWifiInfo.txSuccess = 50;
@@ -243,7 +255,7 @@ public class LinkProbeManagerTest {
eq(Settings.Global.WIFI_LINK_PROBING_ENABLED), anyInt())).thenReturn(0);
mContentObserver.onChange(false);
- mLinkProbeManager.reset();
+ mLinkProbeManager.resetOnNewConnection();
// initialize tx success counter
mWifiInfo.txSuccess = 50;
@@ -278,7 +290,7 @@ public class LinkProbeManagerTest {
mResources.setBoolean(R.bool.config_wifi_link_probing_supported, false);
initLinkProbeManager();
- mLinkProbeManager.reset();
+ mLinkProbeManager.resetOnNewConnection();
// initialize tx success counter
mWifiInfo.txSuccess = 50;
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
index 4fa4e48bb..88ff48838 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -21,11 +21,13 @@ import static android.net.wifi.WifiManager.DEVICE_MOBILITY_STATE_STATIONARY;
import static android.net.wifi.WifiManager.DEVICE_MOBILITY_STATE_UNKNOWN;
import static com.android.server.wifi.WifiMetricsTestUtil.assertDeviceMobilityStatePnoScanStatsEqual;
+import static com.android.server.wifi.WifiMetricsTestUtil.assertExperimentProbeCountsEqual;
import static com.android.server.wifi.WifiMetricsTestUtil.assertHistogramBucketsEqual;
import static com.android.server.wifi.WifiMetricsTestUtil.assertKeyCountsEqual;
import static com.android.server.wifi.WifiMetricsTestUtil.assertLinkProbeFailureReasonCountsEqual;
import static com.android.server.wifi.WifiMetricsTestUtil.assertLinkProbeStaEventsEqual;
import static com.android.server.wifi.WifiMetricsTestUtil.buildDeviceMobilityStatePnoScanStats;
+import static com.android.server.wifi.WifiMetricsTestUtil.buildExperimentProbeCounts;
import static com.android.server.wifi.WifiMetricsTestUtil.buildHistogramBucketInt32;
import static com.android.server.wifi.WifiMetricsTestUtil.buildInt32Count;
import static com.android.server.wifi.WifiMetricsTestUtil.buildLinkProbeFailureReasonCount;
@@ -85,6 +87,7 @@ import com.android.server.wifi.nano.WifiMetricsProto.DeviceMobilityStatePnoScanS
import com.android.server.wifi.nano.WifiMetricsProto.HistogramBucketInt32;
import com.android.server.wifi.nano.WifiMetricsProto.Int32Count;
import com.android.server.wifi.nano.WifiMetricsProto.LinkProbeStats;
+import com.android.server.wifi.nano.WifiMetricsProto.LinkProbeStats.ExperimentProbeCounts;
import com.android.server.wifi.nano.WifiMetricsProto.LinkProbeStats.LinkProbeFailureReasonCount;
import com.android.server.wifi.nano.WifiMetricsProto.NetworkSelectionExperimentDecisions;
import com.android.server.wifi.nano.WifiMetricsProto.PasspointProfileTypeCount;
@@ -3457,6 +3460,32 @@ public class WifiMetricsTest {
}
/**
+ * Tests counting the number of link probes triggered per day for each experiment.
+ */
+ @Test
+ public void testIncrementLinkProbeExperimentProbeCount() throws Exception {
+ String experimentId1 = "screenOnDelay=6000,noTxDelay=3000,delayBetweenProbes=9000,"
+ + "rssiThreshold=-70,linkSpeedThreshold=15,";
+ mWifiMetrics.incrementLinkProbeExperimentProbeCount(experimentId1);
+
+ String experimentId2 = "screenOnDelay=9000,noTxDelay=12000,delayBetweenProbes=15000,"
+ + "rssiThreshold=-72,linkSpeedThreshold=20,";
+ mWifiMetrics.incrementLinkProbeExperimentProbeCount(experimentId2);
+ mWifiMetrics.incrementLinkProbeExperimentProbeCount(experimentId2);
+
+ dumpProtoAndDeserialize();
+
+ ExperimentProbeCounts[] actual = mDecodedProto.linkProbeStats.experimentProbeCounts;
+
+ ExperimentProbeCounts[] expected = {
+ buildExperimentProbeCounts(experimentId1, 1),
+ buildExperimentProbeCounts(experimentId2, 2)
+ };
+
+ assertExperimentProbeCountsEqual(expected, actual);
+ }
+
+ /**
* Tests logNetworkSelectionDecision()
*/
@Test
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTestUtil.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTestUtil.java
index 407d20932..0e9f661ca 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTestUtil.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTestUtil.java
@@ -23,6 +23,7 @@ import android.net.wifi.WifiManager;
import com.android.server.wifi.nano.WifiMetricsProto.DeviceMobilityStatePnoScanStats;
import com.android.server.wifi.nano.WifiMetricsProto.HistogramBucketInt32;
import com.android.server.wifi.nano.WifiMetricsProto.Int32Count;
+import com.android.server.wifi.nano.WifiMetricsProto.LinkProbeStats.ExperimentProbeCounts;
import com.android.server.wifi.nano.WifiMetricsProto.LinkProbeStats.LinkProbeFailureReasonCount;
import com.android.server.wifi.nano.WifiMetricsProto.StaEvent;
@@ -227,4 +228,41 @@ public class WifiMetricsTestUtil {
}
}
}
+
+ /**
+ * The constructor we wish ExperimentProbeCounts had.
+ */
+ public static ExperimentProbeCounts buildExperimentProbeCounts(
+ String experimentId, int probeCount) {
+ ExperimentProbeCounts counts = new ExperimentProbeCounts();
+ counts.experimentId = experimentId;
+ counts.probeCount = probeCount;
+ return counts;
+ }
+
+ /**
+ * Asserts that the two arrays are equal (ignoring order),
+ * reporting any difference between them.
+ */
+ public static void assertExperimentProbeCountsEqual(
+ ExperimentProbeCounts[] expected, ExperimentProbeCounts[] actual) {
+
+ assertEquals("Number of ExperimentProbeCounts do not match!",
+ expected.length, actual.length);
+
+ Arrays.sort(expected, Comparator.comparing(x -> x.experimentId));
+ Arrays.sort(actual, Comparator.comparing(x -> x.experimentId));
+
+ for (int i = 0; i < expected.length; i++) {
+ ExperimentProbeCounts expectedCounts = expected[i];
+ ExperimentProbeCounts actualCounts = actual[i];
+
+ assertEquals(String.format(
+ "ExperimentProbeCounts[%d].experimentId does not match!", i),
+ expectedCounts.experimentId, actualCounts.experimentId);
+ assertEquals(String.format(
+ "ExperimentProbeCounts[%d].probeCount does not match!", i),
+ expectedCounts.probeCount, actualCounts.probeCount);
+ }
+ }
}