summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Su <dysu@google.com>2019-05-15 16:19:27 -0700
committerDavid Su <dysu@google.com>2019-05-21 16:07:42 -0700
commit53648549ec4cc4a6aae5a70370b7e92ff5ebcb69 (patch)
tree87a0c7ab3d475861d1b8614281851b215d1c73a9
parent353e8733c58131f4f78e63f2adb6a4f6379a1d59 (diff)
Adjust link probe manager parameters using experiment results
Shorten minimum delay between link probes to 6000ms to trigger link probes more frequently using the results of the experiment. Bug: 131091030 Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh Change-Id: I11f387b16cf56dd1a6dd0520c348ea4dc58b6c83
-rw-r--r--service/java/com/android/server/wifi/LinkProbeManager.java145
-rw-r--r--service/java/com/android/server/wifi/WifiMetrics.java52
-rw-r--r--service/java/com/android/server/wifi/util/TimedQuotaManager.java85
-rw-r--r--tests/wifitests/Android.mk1
-rw-r--r--tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java185
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java42
-rw-r--r--tests/wifitests/src/com/android/server/wifi/util/TimedQuotaManagerTest.java99
7 files changed, 482 insertions, 127 deletions
diff --git a/service/java/com/android/server/wifi/LinkProbeManager.java b/service/java/com/android/server/wifi/LinkProbeManager.java
index b91ba67f4..89c84f76f 100644
--- a/service/java/com/android/server/wifi/LinkProbeManager.java
+++ b/service/java/com/android/server/wifi/LinkProbeManager.java
@@ -27,9 +27,11 @@ import android.util.Log;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wifi.util.TimedQuotaManager;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
@@ -43,15 +45,25 @@ public class LinkProbeManager {
private static final int WIFI_LINK_PROBING_ENABLED_DEFAULT = 1; // 1 = enabled
// TODO(112029045): Use constants from ScoringParams instead
- @VisibleForTesting
- static final int LINK_PROBE_RSSI_THRESHOLD = -70;
- @VisibleForTesting
- static final int LINK_PROBE_LINK_SPEED_THRESHOLD_MBPS = 15; // in megabits per second
- @VisibleForTesting
- static final long LINK_PROBE_INTERVAL_MS = 15 * 1000;
-
- @VisibleForTesting
- static final int[] EXPERIMENT_DELAYS_MS = {3000, 6000, 9000, 12000, 15000};
+ @VisibleForTesting static final int RSSI_THRESHOLD = -70;
+ @VisibleForTesting static final int LINK_SPEED_THRESHOLD_MBPS = 15; // in megabits per second
+ /** Minimum delay before probing after the last probe. */
+ @VisibleForTesting static final long DELAY_BETWEEN_PROBES_MS = 6000;
+ /** Minimum delay before probing after screen turned on. */
+ @VisibleForTesting static final long SCREEN_ON_DELAY_MS = 6000;
+ /**
+ * Minimum delay before probing after last increase of the Tx success counter (which indicates
+ * that a data frame (i.e. not counting management frame) was successfully transmitted).
+ */
+ @VisibleForTesting static final long DELAY_AFTER_TX_SUCCESS_MS = 6000;
+
+ @VisibleForTesting static final long MAX_PROBE_COUNT_IN_PERIOD =
+ WifiMetrics.MAX_LINK_PROBE_STA_EVENTS;
+ @VisibleForTesting static final long PERIOD_MILLIS = Duration.ofDays(1).toMillis();
+
+ @VisibleForTesting static final int[] EXPERIMENT_DELAYS_MS = {3000, 6000, 9000, 12000, 15000};
+ @VisibleForTesting static final int[] EXPERIMENT_RSSIS = {-65, -70, -75};
+ @VisibleForTesting static final int[] EXPERIMENT_LINK_SPEEDS = {10, 15, 20};
private List<Experiment> mExperiments = new ArrayList<>();
private final Clock mClock;
@@ -65,16 +77,32 @@ public class LinkProbeManager {
private boolean mVerboseLoggingEnabled = false;
+ /**
+ * Tracks the last timestamp when a link probe was triggered. Link probing only occurs when at
+ * least {@link #DELAY_BETWEEN_PROBES_MS} has passed since the last link probe.
+ */
private long mLastLinkProbeTimestampMs;
/**
- * 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 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.
+ * Tracks the last timestamp when {@link WifiInfo#txSuccess} was increased i.e. the last time a
+ * Tx was successful. Link probing only occurs when at least {@link #DELAY_AFTER_TX_SUCCESS_MS}
+ * has passed since the last Tx success.
+ * This is also reset to the current time when {@link #resetOnNewConnection()} is called, so
+ * that a link probe only occurs at least {@link #DELAY_AFTER_TX_SUCCESS_MS} after a new
+ * connection is made.
*/
private long mLastTxSuccessIncreaseTimestampMs;
+ /**
+ * Stores the last value of {@link WifiInfo#txSuccess}. The current value of
+ * {@link WifiInfo#txSuccess} is compared against the last value to determine whether there was
+ * a successful Tx.
+ */
private long mLastTxSuccessCount;
+ /**
+ * Tracks the last timestamp when the screen turned on. Link probing only occurs when at least
+ * {@link #SCREEN_ON_DELAY_MS} has passed since the last time the screen was turned on.
+ */
+ private long mLastScreenOnTimestampMs;
+ private final TimedQuotaManager mTimedQuotaManager;
public LinkProbeManager(Clock clock, WifiNative wifiNative, WifiMetrics wifiMetrics,
FrameworkFacade frameworkFacade, Looper looper, Context context) {
@@ -85,6 +113,7 @@ public class LinkProbeManager {
mContext = context;
mLinkProbingSupported = mContext.getResources()
.getBoolean(R.bool.config_wifi_link_probing_supported);
+ mTimedQuotaManager = new TimedQuotaManager(clock, MAX_PROBE_COUNT_IN_PERIOD, PERIOD_MILLIS);
if (mLinkProbingSupported) {
mFrameworkFacade.registerContentObserver(mContext, Settings.Global.getUriFor(
@@ -97,7 +126,8 @@ public class LinkProbeManager {
});
updateLinkProbeSetting();
- reset();
+ resetOnNewConnection();
+ resetOnScreenTurnedOn();
}
initExperiments();
@@ -124,9 +154,15 @@ public class LinkProbeManager {
pw.println("LinkProbeManager - mLastTxSuccessIncreaseTimestampMs: "
+ mLastTxSuccessIncreaseTimestampMs);
pw.println("LinkProbeManager - mLastTxSuccessCount: " + mLastTxSuccessCount);
+ pw.println("LinkProbeManager - mLastScreenOnTimestampMs: " + mLastScreenOnTimestampMs);
+ pw.println("LinkProbeManager - mTimedQuotaManager: " + mTimedQuotaManager);
}
- private void reset() {
+ /**
+ * When connecting to a new network, reset internal state.
+ */
+ public void resetOnNewConnection() {
+ mExperiments.forEach(Experiment::resetOnNewConnection);
if (!mLinkProbingSupported) return;
long now = mClock.getElapsedSinceBootMillis();
@@ -136,20 +172,14 @@ 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();
+ if (!mLinkProbingSupported) return;
+
+ mLastScreenOnTimestampMs = mClock.getElapsedSinceBootMillis();
}
/**
@@ -172,23 +202,33 @@ public class LinkProbeManager {
}
mLastTxSuccessCount = wifiInfo.txSuccess;
- // maximum 1 link probe every LINK_PROBE_INTERVAL_MS
+ // maximum 1 link probe every DELAY_BETWEEN_PROBES_MS
long timeSinceLastLinkProbeMs = now - mLastLinkProbeTimestampMs;
- if (timeSinceLastLinkProbeMs < LINK_PROBE_INTERVAL_MS) {
+ if (timeSinceLastLinkProbeMs < DELAY_BETWEEN_PROBES_MS) {
return;
}
- // if tx succeeded at least once in the last LINK_PROBE_INTERVAL_MS, don't need to probe
+ // if tx succeeded at least once in the last DELAY_AFTER_TX_SUCCESS_MS, don't need to probe
long timeSinceLastTxSuccessIncreaseMs = now - mLastTxSuccessIncreaseTimestampMs;
- if (timeSinceLastTxSuccessIncreaseMs < LINK_PROBE_INTERVAL_MS) {
+ if (timeSinceLastTxSuccessIncreaseMs < DELAY_AFTER_TX_SUCCESS_MS) {
+ return;
+ }
+
+ // if not enough time has passed since the screen last turned on, don't probe
+ long timeSinceLastScreenOnMs = now - mLastScreenOnTimestampMs;
+ if (timeSinceLastScreenOnMs < SCREEN_ON_DELAY_MS) {
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) {
+ if (rssi != WifiInfo.INVALID_RSSI && rssi > RSSI_THRESHOLD
+ && linkSpeed > LINK_SPEED_THRESHOLD_MBPS) {
+ return;
+ }
+
+ if (!mTimedQuotaManager.requestQuota()) {
return;
}
@@ -201,8 +241,6 @@ public class LinkProbeManager {
rssi, linkSpeed));
}
- long wallClockTimestampMs = mClock.getWallClockMillis();
-
// TODO(b/112029045): also report MCS rate to metrics when supported by driver
mWifiNative.probeLink(
interfaceName,
@@ -214,7 +252,7 @@ public class LinkProbeManager {
Log.d(TAG, "link probing success, elapsedTimeMs="
+ elapsedTimeMs);
}
- mWifiMetrics.logLinkProbeSuccess(wallClockTimestampMs,
+ mWifiMetrics.logLinkProbeSuccess(
timeSinceLastTxSuccessIncreaseMs, rssi, linkSpeed,
elapsedTimeMs);
}
@@ -224,7 +262,7 @@ public class LinkProbeManager {
if (mVerboseLoggingEnabled) {
Log.d(TAG, "link probing failure, reason=" + reason);
}
- mWifiMetrics.logLinkProbeFailure(wallClockTimestampMs,
+ mWifiMetrics.logLinkProbeFailure(
timeSinceLastTxSuccessIncreaseMs, rssi, linkSpeed, reason);
}
},
@@ -235,11 +273,11 @@ public class LinkProbeManager {
}
private void initExperiments() {
- for (int screenOnDelayMs : EXPERIMENT_DELAYS_MS) {
- for (int noTxDelayMs : EXPERIMENT_DELAYS_MS) {
- for (int delayBetweenProbesMs : EXPERIMENT_DELAYS_MS) {
+ for (int delay : EXPERIMENT_DELAYS_MS) {
+ for (int rssiThreshold : EXPERIMENT_RSSIS) {
+ for (int linkSpeedThreshold: EXPERIMENT_LINK_SPEEDS) {
Experiment experiment = new Experiment(mClock, mWifiMetrics,
- screenOnDelayMs, noTxDelayMs, delayBetweenProbesMs);
+ delay, delay, delay, rssiThreshold, linkSpeedThreshold);
mExperiments.add(experiment);
}
}
@@ -254,29 +292,38 @@ public class LinkProbeManager {
private final int mScreenOnDelayMs;
private final int mNoTxDelayMs;
private final int mDelayBetweenProbesMs;
+ private final int mRssiThreshold;
+ private final int mLinkSpeedThreshold;
private final String mExperimentId;
private long mLastLinkProbeTimestampMs;
private long mLastTxSuccessIncreaseTimestampMs;
private long mLastTxSuccessCount;
+ private long mLastScreenOnTimestampMs;
Experiment(Clock clock, WifiMetrics wifiMetrics,
- int screenOnDelayMs, int noTxDelayMs, int delayBetweenProbesMs) {
+ int screenOnDelayMs, int noTxDelayMs, int delayBetweenProbesMs,
+ int rssiThreshold, int linkSpeedThreshold) {
mClock = clock;
mWifiMetrics = wifiMetrics;
mScreenOnDelayMs = screenOnDelayMs;
mNoTxDelayMs = noTxDelayMs;
mDelayBetweenProbesMs = delayBetweenProbesMs;
+ mRssiThreshold = rssiThreshold;
+ mLinkSpeedThreshold = linkSpeedThreshold;
mExperimentId = getExperimentId();
resetOnNewConnection();
+ resetOnScreenTurnedOn();
}
private String getExperimentId() {
return "[screenOnDelay=" + mScreenOnDelayMs + ','
+ "noTxDelay=" + mNoTxDelayMs + ','
- + "delayBetweenProbes=" + mDelayBetweenProbesMs + ']';
+ + "delayBetweenProbes=" + mDelayBetweenProbesMs + ','
+ + "rssiThreshold=" + mRssiThreshold + ','
+ + "linkSpeedThreshold=" + mLinkSpeedThreshold + ']';
}
void resetOnNewConnection() {
@@ -287,12 +334,7 @@ public class LinkProbeManager {
}
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
+ mLastScreenOnTimestampMs = mClock.getElapsedSinceBootMillis();
}
void updateConnectionStats(WifiInfo wifiInfo) {
@@ -314,11 +356,16 @@ public class LinkProbeManager {
return;
}
+ long timeSinceLastScreenOnMs = now - mLastScreenOnTimestampMs;
+ if (timeSinceLastScreenOnMs < SCREEN_ON_DELAY_MS) {
+ 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) {
+ if (rssi != WifiInfo.INVALID_RSSI && rssi > mRssiThreshold
+ && linkSpeed > mLinkSpeedThreshold) {
return;
}
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index 539fe3dee..a62ad379c 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -212,6 +212,13 @@ public class WifiMetrics {
private int mProbeMcsRateSinceLastUpdate = -1;
private long mScoreBreachLowTimeMillis = -1;
+ public static final int MAX_STA_EVENTS = 768;
+ private LinkedList<StaEventWithTime> mStaEventList = new LinkedList<>();
+ private int mLastPollRssi = -127;
+ private int mLastPollLinkSpeed = -1;
+ private int mLastPollFreq = -1;
+ private int mLastScore = -1;
+
/** Tracks if we should be logging WifiIsUnusableEvent */
private boolean mUnusableEventLogging = false;
/** Tracks if we should be logging LinkSpeedCounts */
@@ -328,6 +335,8 @@ public class WifiMetrics {
* experiment.
*/
private final ObjectCounter<String> mLinkProbeExperimentProbeCounts = new ObjectCounter<>();
+ private int mLinkProbeStaEventCount = 0;
+ @VisibleForTesting static final int MAX_LINK_PROBE_STA_EVENTS = MAX_STA_EVENTS / 4;
private final LinkedList<WifiUsabilityStatsEntry> mWifiUsabilityStatsEntriesList =
new LinkedList<>();
@@ -2761,6 +2770,7 @@ public class WifiMetrics {
pw.println("mNetworkSelectionExperimentPairNumChoicesCounts:"
+ mNetworkSelectionExperimentPairNumChoicesCounts);
+ pw.println("mLinkProbeStaEventCount:" + mLinkProbeStaEventCount);
pw.println("mWifiNetworkRequestApiLog:\n" + mWifiNetworkRequestApiLog);
pw.println("mWifiNetworkRequestApiMatchSizeHistogram:\n"
@@ -3500,6 +3510,7 @@ public class WifiMetrics {
mLinkProbeSuccessElapsedTimeMsHistogram.clear();
mLinkProbeFailureReasonCounts.clear();
mLinkProbeExperimentProbeCounts.clear();
+ mLinkProbeStaEventCount = 0;
mNetworkSelectionExperimentPairNumChoicesCounts.clear();
mWifiNetworkSuggestionApiLog.clear();
mWifiNetworkSuggestionApiLog.clear();
@@ -3935,13 +3946,6 @@ public class WifiMetrics {
return sb.toString();
}
- public static final int MAX_STA_EVENTS = 768;
- private LinkedList<StaEventWithTime> mStaEventList = new LinkedList<StaEventWithTime>();
- private int mLastPollRssi = -127;
- private int mLastPollLinkSpeed = -1;
- private int mLastPollFreq = -1;
- private int mLastScore = -1;
-
/**
* Converts the first 31 bits of a BitSet to a little endian int
*/
@@ -4684,7 +4688,6 @@ public class WifiMetrics {
/**
* Reports stats for a successful link probe.
*
- * @param startTimestampMs The wall clock time when the link probe was started, in ms.
* @param timeSinceLastTxSuccessMs At {@code startTimestampMs}, the number of milliseconds since
* the last Tx success (according to
* {@link WifiInfo#txSuccess}).
@@ -4695,7 +4698,7 @@ public class WifiMetrics {
* probe was ACKed. Note: this number should be correlated with the number
* of retries that the driver attempted before the probe was ACKed.
*/
- public void logLinkProbeSuccess(long startTimestampMs, long timeSinceLastTxSuccessMs,
+ public void logLinkProbeSuccess(long timeSinceLastTxSuccessMs,
int rssi, int linkSpeed, int elapsedTimeMs) {
synchronized (mLock) {
mProbeStatusSinceLastUpdate =
@@ -4708,19 +4711,20 @@ public class WifiMetrics {
mLinkProbeSuccessLinkSpeedCounts.increment(linkSpeed);
mLinkProbeSuccessElapsedTimeMsHistogram.increment(elapsedTimeMs);
- StaEvent event = new StaEvent();
- event.type = StaEvent.TYPE_LINK_PROBE;
- event.linkProbeWasSuccess = true;
- event.linkProbeSuccessElapsedTimeMs = elapsedTimeMs;
- // TODO(129958996): Cap number of link probe StaEvents
- addStaEvent(event);
+ if (mLinkProbeStaEventCount < MAX_LINK_PROBE_STA_EVENTS) {
+ StaEvent event = new StaEvent();
+ event.type = StaEvent.TYPE_LINK_PROBE;
+ event.linkProbeWasSuccess = true;
+ event.linkProbeSuccessElapsedTimeMs = elapsedTimeMs;
+ addStaEvent(event);
+ }
+ mLinkProbeStaEventCount++;
}
}
/**
* Reports stats for an unsuccessful link probe.
*
- * @param startTimestampMs The wall clock time when the link probe was started, in ms.
* @param timeSinceLastTxSuccessMs At {@code startTimestampMs}, the number of milliseconds since
* the last Tx success (according to
* {@link WifiInfo#txSuccess}).
@@ -4728,7 +4732,7 @@ public class WifiMetrics {
* @param linkSpeed The Tx link speed in Mbps at {@code startTimestampMs}.
* @param reason The error code for the failure. See {@link WifiNative.SendMgmtFrameError}.
*/
- public void logLinkProbeFailure(long startTimestampMs, long timeSinceLastTxSuccessMs,
+ public void logLinkProbeFailure(long timeSinceLastTxSuccessMs,
int rssi, int linkSpeed, @WifiNative.SendMgmtFrameError int reason) {
synchronized (mLock) {
mProbeStatusSinceLastUpdate =
@@ -4741,12 +4745,14 @@ public class WifiMetrics {
mLinkProbeFailureLinkSpeedCounts.increment(linkSpeed);
mLinkProbeFailureReasonCounts.increment(reason);
- StaEvent event = new StaEvent();
- event.type = StaEvent.TYPE_LINK_PROBE;
- event.linkProbeWasSuccess = false;
- event.linkProbeFailureReason = linkProbeFailureReasonToProto(reason);
- // TODO(129958996): Cap number of link probe StaEvents
- addStaEvent(event);
+ if (mLinkProbeStaEventCount < MAX_LINK_PROBE_STA_EVENTS) {
+ StaEvent event = new StaEvent();
+ event.type = StaEvent.TYPE_LINK_PROBE;
+ event.linkProbeWasSuccess = false;
+ event.linkProbeFailureReason = linkProbeFailureReasonToProto(reason);
+ addStaEvent(event);
+ }
+ mLinkProbeStaEventCount++;
}
}
diff --git a/service/java/com/android/server/wifi/util/TimedQuotaManager.java b/service/java/com/android/server/wifi/util/TimedQuotaManager.java
new file mode 100644
index 000000000..bf78e9bc8
--- /dev/null
+++ b/service/java/com/android/server/wifi/util/TimedQuotaManager.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi.util;
+
+import com.android.server.wifi.Clock;
+
+/**
+ * Manages a quota that is reset at the beginning of each new time period.
+ */
+public class TimedQuotaManager {
+ private final Clock mClock;
+
+ private final long mQuota;
+ private final long mPeriodMillis;
+ private final long mStartTimeMillis;
+
+ /**
+ * The number of elapsed periods between {@link #mStartTimeMillis} and the time of the last call
+ * to {@link #requestQuota()}.
+ */
+ private long mLastPeriod;
+ /** How much quota has been consumed in the current period. */
+ private long mConsumedQuota;
+
+ /**
+ * Constructor.
+ * @param clock Clock instance.
+ * @param quota the maximum quota for a given period.
+ * @param periodMillis the quota will be reset at the beginning of each new period.
+ */
+ public TimedQuotaManager(Clock clock, long quota, long periodMillis) {
+ mClock = clock;
+ mQuota = quota;
+ mPeriodMillis = periodMillis;
+ mStartTimeMillis = clock.getElapsedSinceBootMillis();
+ mLastPeriod = 0;
+ mConsumedQuota = 0;
+ }
+
+ /**
+ * Requests one quota. If there is sufficient remaining quota for the current period,
+ * returns true and consumes one quota. Otherwise, returns false.
+ */
+ public boolean requestQuota() {
+ long currentPeriod = getCurrentPeriod();
+ if (mLastPeriod < currentPeriod) {
+ mLastPeriod = currentPeriod;
+ mConsumedQuota = 0;
+ }
+ if (mConsumedQuota < mQuota) {
+ mConsumedQuota++;
+ return true;
+ }
+ return false;
+ }
+
+ private long getCurrentPeriod() {
+ return (mClock.getElapsedSinceBootMillis() - mStartTimeMillis) / mPeriodMillis;
+ }
+
+ @Override
+ public String toString() {
+ return "TimedQuotaManager{"
+ + "mQuota=" + mQuota
+ + ", mPeriodMillis=" + mPeriodMillis
+ + ", mStartTimeMillis=" + mStartTimeMillis
+ + ", mLastPeriod=" + mLastPeriod
+ + ", mConsumedQuota=" + mConsumedQuota
+ + '}';
+ }
+}
diff --git a/tests/wifitests/Android.mk b/tests/wifitests/Android.mk
index 9b44ecedf..8e48f0c7f 100644
--- a/tests/wifitests/Android.mk
+++ b/tests/wifitests/Android.mk
@@ -59,6 +59,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
frameworks-base-testutils \
services \
wifi-service \
+ truth-prebuilt \
LOCAL_JAVA_LIBRARIES := \
android.test.runner \
diff --git a/tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java b/tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java
index 35f63149c..6884c03c0 100644
--- a/tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/LinkProbeManagerTest.java
@@ -23,6 +23,7 @@ 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.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@@ -54,7 +55,6 @@ public class LinkProbeManagerTest {
private static final String TEST_IFACE_NAME = "testIfaceName";
private static final String TEST_BSSID = "6c:f3:7f:ae:8c:f3";
private static final int TEST_ELAPSED_TIME_MS = 100;
- private static final long TEST_TIMESTAMP_MS = 1547837434690L;
private LinkProbeManager mLinkProbeManager;
@@ -107,8 +107,6 @@ public class LinkProbeManagerTest {
*/
@Test
public void testLinkProbeTriggeredAndAcked() throws Exception {
- mLinkProbeManager.resetOnNewConnection();
-
// initialize tx success counter
mWifiInfo.txSuccess = 50;
mTimeMs += 3000;
@@ -121,16 +119,15 @@ public class LinkProbeManagerTest {
// tx success counter did not change since last update
mWifiInfo.txSuccess = 50;
// below RSSI threshold
- int rssi = LinkProbeManager.LINK_PROBE_RSSI_THRESHOLD - 5;
+ int rssi = LinkProbeManager.RSSI_THRESHOLD - 5;
mWifiInfo.setRssi(rssi);
// above link speed threshold
- int linkSpeed = LinkProbeManager.LINK_PROBE_LINK_SPEED_THRESHOLD_MBPS + 10;
+ int linkSpeed = LinkProbeManager.LINK_SPEED_THRESHOLD_MBPS + 10;
mWifiInfo.setLinkSpeed(linkSpeed);
- // more than LINK_PROBE_INTERVAL_MS passed
- long timeDelta = LinkProbeManager.LINK_PROBE_INTERVAL_MS + 1000;
+ // more than DELAY_AFTER_TX_SUCCESS_MS passed
+ long timeDelta = LinkProbeManager.DELAY_AFTER_TX_SUCCESS_MS + 20000;
mTimeMs += timeDelta;
when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
- when(mClock.getWallClockMillis()).thenReturn(TEST_TIMESTAMP_MS);
mLinkProbeManager.updateConnectionStats(mWifiInfo, TEST_IFACE_NAME);
ArgumentCaptor<WifiNative.SendMgmtFrameCallback> callbackCaptor =
ArgumentCaptor.forClass(WifiNative.SendMgmtFrameCallback.class);
@@ -139,13 +136,13 @@ public class LinkProbeManagerTest {
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;
+ int numExperimentIds = LinkProbeManager.EXPERIMENT_DELAYS_MS.length
+ * LinkProbeManager.EXPERIMENT_RSSIS.length
+ * LinkProbeManager.EXPERIMENT_LINK_SPEEDS.length;
assertEquals(numExperimentIds, new HashSet<>(experimentIdCaptor.getAllValues()).size());
callbackCaptor.getValue().onAck(TEST_ELAPSED_TIME_MS);
- verify(mWifiMetrics).logLinkProbeSuccess(TEST_TIMESTAMP_MS, timeDelta, rssi, linkSpeed,
- TEST_ELAPSED_TIME_MS);
+ verify(mWifiMetrics).logLinkProbeSuccess(timeDelta, rssi, linkSpeed, TEST_ELAPSED_TIME_MS);
}
/**
@@ -154,8 +151,6 @@ public class LinkProbeManagerTest {
*/
@Test
public void testLinkProbeTriggeredAndFailed() throws Exception {
- mLinkProbeManager.resetOnNewConnection();
-
// initialize tx success counter
mWifiInfo.txSuccess = 50;
mTimeMs += 3000;
@@ -167,16 +162,15 @@ public class LinkProbeManagerTest {
// tx success counter did not change since last update
mWifiInfo.txSuccess = 50;
// above RSSI threshold
- int rssi = LinkProbeManager.LINK_PROBE_RSSI_THRESHOLD + 5;
+ int rssi = LinkProbeManager.RSSI_THRESHOLD + 5;
mWifiInfo.setRssi(rssi);
// below link speed threshold
- int linkSpeed = LinkProbeManager.LINK_PROBE_LINK_SPEED_THRESHOLD_MBPS - 2;
+ int linkSpeed = LinkProbeManager.LINK_SPEED_THRESHOLD_MBPS - 2;
mWifiInfo.setLinkSpeed(linkSpeed);
- // more than LINK_PROBE_INTERVAL_MS passed
- long timeDelta = LinkProbeManager.LINK_PROBE_INTERVAL_MS + 1000;
+ // more than DELAY_BETWEEN_PROBES_MS passed
+ long timeDelta = LinkProbeManager.DELAY_BETWEEN_PROBES_MS + 1000;
mTimeMs += timeDelta;
when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
- when(mClock.getWallClockMillis()).thenReturn(TEST_TIMESTAMP_MS);
mLinkProbeManager.updateConnectionStats(mWifiInfo, TEST_IFACE_NAME);
ArgumentCaptor<WifiNative.SendMgmtFrameCallback> callbackCaptor =
ArgumentCaptor.forClass(WifiNative.SendMgmtFrameCallback.class);
@@ -184,12 +178,12 @@ public class LinkProbeManagerTest {
anyInt());
callbackCaptor.getValue().onFailure(WifiNative.SEND_MGMT_FRAME_ERROR_NO_ACK);
- verify(mWifiMetrics).logLinkProbeFailure(TEST_TIMESTAMP_MS, timeDelta, rssi, linkSpeed,
+ verify(mWifiMetrics).logLinkProbeFailure(timeDelta, rssi, linkSpeed,
WifiNative.SEND_MGMT_FRAME_ERROR_NO_ACK);
}
/**
- * Tests that link probing is not triggered more than once every LINK_PROBE_INTERVAL_MS
+ * Tests that link probing is not triggered more than once every DELAY_BETWEEN_PROBES_MS
*/
@Test
public void testLinkProbeNotTriggeredTooFrequently() throws Exception {
@@ -198,11 +192,11 @@ public class LinkProbeManagerTest {
// tx success counter did not change since last update
mWifiInfo.txSuccess = 50;
// below RSSI threshold
- mWifiInfo.setRssi(LinkProbeManager.LINK_PROBE_RSSI_THRESHOLD - 5);
+ mWifiInfo.setRssi(LinkProbeManager.RSSI_THRESHOLD - 5);
// above link speed threshold
- mWifiInfo.setLinkSpeed(LinkProbeManager.LINK_PROBE_LINK_SPEED_THRESHOLD_MBPS + 10);
- // *** but less than LINK_PROBE_INTERVAL_MS has passed since last probe ***
- mTimeMs += LinkProbeManager.LINK_PROBE_INTERVAL_MS - 1000;
+ mWifiInfo.setLinkSpeed(LinkProbeManager.LINK_SPEED_THRESHOLD_MBPS + 10);
+ // *** but less than DELAY_BETWEEN_PROBES_MS has passed since last probe ***
+ mTimeMs += LinkProbeManager.DELAY_BETWEEN_PROBES_MS - 1000;
when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
mLinkProbeManager.updateConnectionStats(mWifiInfo, TEST_IFACE_NAME);
// should not probe
@@ -211,12 +205,10 @@ public class LinkProbeManagerTest {
/**
* Tests that link probing is not triggered when Tx has succeeded within the last
- * LINK_PROBE_INTERVAL_MS.
+ * DELAY_AFTER_TX_SUCCESS_MS.
*/
@Test
public void testLinkProbeNotTriggeredWhenTxSucceeded() throws Exception {
- mLinkProbeManager.resetOnNewConnection();
-
// initialize tx success counter
mWifiInfo.txSuccess = 50;
mTimeMs += 3000;
@@ -236,17 +228,67 @@ public class LinkProbeManagerTest {
// tx success counter did not change since last update
mWifiInfo.txSuccess = 55;
// below RSSI threshold
- mWifiInfo.setRssi(LinkProbeManager.LINK_PROBE_RSSI_THRESHOLD - 5);
+ mWifiInfo.setRssi(LinkProbeManager.RSSI_THRESHOLD - 5);
// above link speed threshold
- mWifiInfo.setLinkSpeed(LinkProbeManager.LINK_PROBE_LINK_SPEED_THRESHOLD_MBPS + 10);
- // *** but less than LINK_PROBE_INTERVAL_MS has passed since last tx success ***
- mTimeMs += LinkProbeManager.LINK_PROBE_INTERVAL_MS - 1000;
+ mWifiInfo.setLinkSpeed(LinkProbeManager.LINK_SPEED_THRESHOLD_MBPS + 10);
+ // *** but less than DELAY_AFTER_TX_SUCCESS_MS has passed since last tx success ***
+ mTimeMs += LinkProbeManager.DELAY_AFTER_TX_SUCCESS_MS - 1000;
when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
mLinkProbeManager.updateConnectionStats(mWifiInfo, TEST_IFACE_NAME);
verify(mWifiNative, never()).probeLink(any(), any(), any(), anyInt());
}
/**
+ * Tests that link probing is not triggered when screen was turned on within the last
+ * {@link LinkProbeManager#SCREEN_ON_DELAY_MS}.
+ */
+ @Test
+ public void testLinkProbeNotTriggeredWhenScreenJustTurnedOn() throws Exception {
+ mTimeMs += 30 * 1000;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
+ mLinkProbeManager.resetOnScreenTurnedOn();
+ // should not probe yet
+ verify(mWifiNative, never()).probeLink(any(), any(), any(), anyInt());
+
+ // tx success counter did not change since initialization
+ mWifiInfo.txSuccess = 0;
+ // below RSSI threshold
+ mWifiInfo.setRssi(LinkProbeManager.RSSI_THRESHOLD - 5);
+ // above link speed threshold
+ mWifiInfo.setLinkSpeed(LinkProbeManager.LINK_SPEED_THRESHOLD_MBPS + 10);
+ // *** but less than SCREEN_ON_DELAY_MS has passed since last screen on ***
+ mTimeMs += LinkProbeManager.SCREEN_ON_DELAY_MS - 1000;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
+ mLinkProbeManager.updateConnectionStats(mWifiInfo, TEST_IFACE_NAME);
+ verify(mWifiNative, never()).probeLink(any(), any(), any(), anyInt());
+ }
+
+ /**
+ * Tests that link probing is triggered when screen was turned on more than
+ * {@link LinkProbeManager#SCREEN_ON_DELAY_MS} ago.
+ */
+ @Test
+ public void testLinkProbeTriggeredAfterScreenTurnedOn() throws Exception {
+ mTimeMs += 30 * 1000;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
+ mLinkProbeManager.resetOnScreenTurnedOn();
+ // should not probe yet
+ verify(mWifiNative, never()).probeLink(any(), any(), any(), anyInt());
+
+ // tx success counter did not change since initialization
+ mWifiInfo.txSuccess = 0;
+ // below RSSI threshold
+ mWifiInfo.setRssi(LinkProbeManager.RSSI_THRESHOLD - 5);
+ // above link speed threshold
+ mWifiInfo.setLinkSpeed(LinkProbeManager.LINK_SPEED_THRESHOLD_MBPS + 10);
+ // *** more than SCREEN_ON_DELAY_MS has passed since last screen on ***
+ mTimeMs += LinkProbeManager.SCREEN_ON_DELAY_MS + 1000;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
+ mLinkProbeManager.updateConnectionStats(mWifiInfo, TEST_IFACE_NAME);
+ verify(mWifiNative).probeLink(eq(TEST_IFACE_NAME), any(), any(), anyInt());
+ }
+
+ /**
* Tests when link probing feature flag is disabled, no probes should run.
*/
@Test
@@ -255,8 +297,6 @@ public class LinkProbeManagerTest {
eq(Settings.Global.WIFI_LINK_PROBING_ENABLED), anyInt())).thenReturn(0);
mContentObserver.onChange(false);
- mLinkProbeManager.resetOnNewConnection();
-
// initialize tx success counter
mWifiInfo.txSuccess = 50;
mTimeMs += 3000;
@@ -268,16 +308,15 @@ public class LinkProbeManagerTest {
// tx success counter did not change since last update
mWifiInfo.txSuccess = 50;
// below RSSI threshold
- int rssi = LinkProbeManager.LINK_PROBE_RSSI_THRESHOLD - 5;
+ int rssi = LinkProbeManager.RSSI_THRESHOLD - 5;
mWifiInfo.setRssi(rssi);
// above link speed threshold
- int linkSpeed = LinkProbeManager.LINK_PROBE_LINK_SPEED_THRESHOLD_MBPS + 10;
+ int linkSpeed = LinkProbeManager.LINK_SPEED_THRESHOLD_MBPS + 10;
mWifiInfo.setLinkSpeed(linkSpeed);
- // more than LINK_PROBE_INTERVAL_MS passed
- long timeDelta = LinkProbeManager.LINK_PROBE_INTERVAL_MS + 1000;
+ // more than DELAY_AFTER_TX_SUCCESS_MS passed
+ long timeDelta = LinkProbeManager.DELAY_AFTER_TX_SUCCESS_MS + 1000;
mTimeMs += timeDelta;
when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
- when(mClock.getWallClockMillis()).thenReturn(TEST_TIMESTAMP_MS);
mLinkProbeManager.updateConnectionStats(mWifiInfo, TEST_IFACE_NAME);
verify(mWifiNative, never()).probeLink(any() , any(), any(), anyInt());
}
@@ -290,8 +329,6 @@ public class LinkProbeManagerTest {
mResources.setBoolean(R.bool.config_wifi_link_probing_supported, false);
initLinkProbeManager();
- mLinkProbeManager.resetOnNewConnection();
-
// initialize tx success counter
mWifiInfo.txSuccess = 50;
mTimeMs += 3000;
@@ -303,17 +340,73 @@ public class LinkProbeManagerTest {
// tx success counter did not change since last update
mWifiInfo.txSuccess = 50;
// below RSSI threshold
- int rssi = LinkProbeManager.LINK_PROBE_RSSI_THRESHOLD - 5;
+ int rssi = LinkProbeManager.RSSI_THRESHOLD - 5;
mWifiInfo.setRssi(rssi);
// above link speed threshold
- int linkSpeed = LinkProbeManager.LINK_PROBE_LINK_SPEED_THRESHOLD_MBPS + 10;
+ int linkSpeed = LinkProbeManager.LINK_SPEED_THRESHOLD_MBPS + 10;
mWifiInfo.setLinkSpeed(linkSpeed);
- // more than LINK_PROBE_INTERVAL_MS passed
- long timeDelta = LinkProbeManager.LINK_PROBE_INTERVAL_MS + 1000;
+ // more than DELAY_AFTER_TX_SUCCESS_MS passed
+ long timeDelta = LinkProbeManager.DELAY_AFTER_TX_SUCCESS_MS + 1000;
mTimeMs += timeDelta;
when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
- when(mClock.getWallClockMillis()).thenReturn(TEST_TIMESTAMP_MS);
mLinkProbeManager.updateConnectionStats(mWifiInfo, TEST_IFACE_NAME);
verify(mWifiNative, never()).probeLink(any() , any(), any(), anyInt());
}
+
+ /**
+ * Tests exhausting the daily link probe quota and verify that no more link probes are made
+ * after the limit is reached. Tests that the quota is reset upon entering a new day.
+ */
+ @Test
+ public void testLinkProbeQuotaExceeded() {
+ mTimeMs += 30 * 1000;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
+ // should not probe yet
+ verify(mWifiNative, never()).probeLink(any(), any(), any(), anyInt());
+
+ // tx success counter did not change since initialization
+ mWifiInfo.txSuccess = 0;
+ // below RSSI threshold
+ mWifiInfo.setRssi(LinkProbeManager.RSSI_THRESHOLD - 5);
+ // above link speed threshold
+ mWifiInfo.setLinkSpeed(LinkProbeManager.LINK_SPEED_THRESHOLD_MBPS + 10);
+
+ // exhaust quota
+ for (int i = 1; i <= LinkProbeManager.MAX_PROBE_COUNT_IN_PERIOD; i++) {
+ mTimeMs += LinkProbeManager.DELAY_BETWEEN_PROBES_MS + 1000;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
+ mLinkProbeManager.updateConnectionStats(mWifiInfo, TEST_IFACE_NAME);
+ verify(mWifiNative, times(i))
+ .probeLink(eq(TEST_IFACE_NAME), any(), any(), anyInt());
+ }
+ // verify no more quota
+ for (int i = 0; i < 10; i++) {
+ mTimeMs += LinkProbeManager.DELAY_BETWEEN_PROBES_MS + 1000;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
+ mLinkProbeManager.updateConnectionStats(mWifiInfo, TEST_IFACE_NAME);
+ verify(mWifiNative, times((int) LinkProbeManager.MAX_PROBE_COUNT_IN_PERIOD))
+ .probeLink(eq(TEST_IFACE_NAME), any(), any(), anyInt());
+ }
+
+ // start new period
+ mTimeMs += LinkProbeManager.PERIOD_MILLIS + 1000;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
+
+ // exhaust quota again
+ for (int i = 1; i <= LinkProbeManager.MAX_PROBE_COUNT_IN_PERIOD; i++) {
+ mTimeMs += LinkProbeManager.DELAY_BETWEEN_PROBES_MS + 1000;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
+ mLinkProbeManager.updateConnectionStats(mWifiInfo, TEST_IFACE_NAME);
+ verify(mWifiNative, times((int) (LinkProbeManager.MAX_PROBE_COUNT_IN_PERIOD + i)))
+ .probeLink(eq(TEST_IFACE_NAME), any(), any(), anyInt());
+ }
+ // verify no more quota again
+ for (int i = 0; i < 10; i++) {
+ mTimeMs += LinkProbeManager.DELAY_BETWEEN_PROBES_MS + 1000;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(mTimeMs);
+ mLinkProbeManager.updateConnectionStats(mWifiInfo, TEST_IFACE_NAME);
+ verify(mWifiNative, times((int) (2 * LinkProbeManager.MAX_PROBE_COUNT_IN_PERIOD)))
+ .probeLink(eq(TEST_IFACE_NAME), any(), any(), anyInt());
+ }
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
index 88ff48838..e45906a85 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -33,6 +33,7 @@ import static com.android.server.wifi.WifiMetricsTestUtil.buildInt32Count;
import static com.android.server.wifi.WifiMetricsTestUtil.buildLinkProbeFailureReasonCount;
import static com.android.server.wifi.WifiMetricsTestUtil.buildLinkProbeFailureStaEvent;
import static com.android.server.wifi.WifiMetricsTestUtil.buildLinkProbeSuccessStaEvent;
+import static com.android.server.wifi.nano.WifiMetricsProto.StaEvent.TYPE_LINK_PROBE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -115,6 +116,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
@@ -1953,6 +1955,29 @@ public class WifiMetricsTest {
}
/**
+ * Tests that link probe StaEvents do not exceed
+ * {@link WifiMetrics#MAX_LINK_PROBE_STA_EVENTS}.
+ */
+ @Test
+ public void testLinkProbeStaEventBounding() throws Exception {
+ for (int i = 0; i < WifiMetrics.MAX_LINK_PROBE_STA_EVENTS; i++) {
+ mWifiMetrics.logLinkProbeSuccess(0, 0, 0, 0);
+ mWifiMetrics.logLinkProbeFailure(0, 0, 0, 0);
+ }
+ for (int i = 0; i < 10; i++) {
+ mWifiMetrics.logStaEvent(StaEvent.TYPE_CMD_START_CONNECT);
+ }
+
+ dumpProtoAndDeserialize();
+
+ long numLinkProbeStaEvents = Arrays.stream(mDecodedProto.staEventList)
+ .filter(event -> event.type == TYPE_LINK_PROBE)
+ .count();
+ assertEquals(WifiMetrics.MAX_LINK_PROBE_STA_EVENTS, numLinkProbeStaEvents);
+ assertEquals(WifiMetrics.MAX_LINK_PROBE_STA_EVENTS + 10, mDecodedProto.staEventList.length);
+ }
+
+ /**
* Ensure WifiMetrics doesn't cause a null pointer exception when called with null args
*/
@Test
@@ -2803,12 +2828,11 @@ public class WifiMetricsTest {
WifiLinkLayerStats stats2 = nextRandomStats(stats1);
mWifiMetrics.incrementWifiScoreCount(60);
mWifiMetrics.incrementWifiUsabilityScoreCount(2, 55, 15);
- mWifiMetrics.logLinkProbeSuccess(nextRandInt(), nextRandInt(), nextRandInt(),
- nextRandInt(), 12);
+ mWifiMetrics.logLinkProbeSuccess(nextRandInt(), nextRandInt(), nextRandInt(), 12);
mWifiMetrics.updateWifiUsabilityStatsEntries(info, stats1);
mWifiMetrics.incrementWifiScoreCount(58);
mWifiMetrics.incrementWifiUsabilityScoreCount(3, 56, 15);
- mWifiMetrics.logLinkProbeFailure(nextRandInt(), nextRandInt(), nextRandInt(),
+ mWifiMetrics.logLinkProbeFailure(nextRandInt(), nextRandInt(),
nextRandInt(), nextRandInt());
mWifiMetrics.enterDeviceMobilityState(DEVICE_MOBILITY_STATE_HIGH_MVMT);
@@ -3375,14 +3399,14 @@ public class WifiMetricsTest {
*/
@Test
public void testLogLinkProbeMetrics() throws Exception {
- mWifiMetrics.logLinkProbeSuccess(1000, 10000, -75, 50, 5);
- mWifiMetrics.logLinkProbeFailure(2000, 30000, -80, 10,
+ mWifiMetrics.logLinkProbeSuccess(10000, -75, 50, 5);
+ mWifiMetrics.logLinkProbeFailure(30000, -80, 10,
WifiNative.SEND_MGMT_FRAME_ERROR_NO_ACK);
- mWifiMetrics.logLinkProbeSuccess(3000, 3000, -71, 160, 12);
- mWifiMetrics.logLinkProbeFailure(4000, 40000, -80, 6,
+ mWifiMetrics.logLinkProbeSuccess(3000, -71, 160, 12);
+ mWifiMetrics.logLinkProbeFailure(40000, -80, 6,
WifiNative.SEND_MGMT_FRAME_ERROR_NO_ACK);
- mWifiMetrics.logLinkProbeSuccess(5000, 5000, -73, 160, 10);
- mWifiMetrics.logLinkProbeFailure(6000, 2000, -78, 6,
+ mWifiMetrics.logLinkProbeSuccess(5000, -73, 160, 10);
+ mWifiMetrics.logLinkProbeFailure(2000, -78, 6,
WifiNative.SEND_MGMT_FRAME_ERROR_TIMEOUT);
dumpProtoAndDeserialize();
diff --git a/tests/wifitests/src/com/android/server/wifi/util/TimedQuotaManagerTest.java b/tests/wifitests/src/com/android/server/wifi/util/TimedQuotaManagerTest.java
new file mode 100644
index 000000000..3dcad7cd7
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/util/TimedQuotaManagerTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi.util;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.server.wifi.Clock;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.time.Duration;
+
+/**
+ * Unit tests for {@link TimedQuotaManager}.
+ */
+@SmallTest
+public class TimedQuotaManagerTest {
+
+ private static final long DAY_MILLIS = Duration.ofDays(1).toMillis();
+
+ @Mock private Clock mClock;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(100000000L);
+ }
+
+ /**
+ * Tests that {@link TimedQuotaManager#requestQuota()} returns true before the quota is exceeded
+ * and returns false after it is exceeded. Tests that upon entering a new time period, the quota
+ * is reset correctly.
+ */
+ @Test
+ public void exhaustQuota_newDay_exhaustQuotaAgain() {
+ TimedQuotaManager qm = new TimedQuotaManager(mClock, 10, DAY_MILLIS);
+
+ for (int i = 0; i < 10; i++) {
+ assertThat(qm.requestQuota()).isTrue();
+ }
+ for (int i = 0; i < 10; i++) {
+ assertThat(qm.requestQuota()).isFalse();
+ }
+
+ long now = mClock.getElapsedSinceBootMillis();
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(now + DAY_MILLIS + 1000);
+
+ for (int i = 0; i < 10; i++) {
+ assertThat(qm.requestQuota()).isTrue();
+ }
+ for (int i = 0; i < 10; i++) {
+ assertThat(qm.requestQuota()).isFalse();
+ }
+ }
+
+ /**
+ * Tests that {@link TimedQuotaManager#requestQuota()} returns true before the quota is exceeded
+ * and returns false after it is exceeded. Tests when advancing time within the same time
+ * period, the quota is still enforced.
+ */
+ @Test
+ public void exhaustQuota_sameDay_stillExhausted() {
+ TimedQuotaManager qm = new TimedQuotaManager(mClock, 10, DAY_MILLIS);
+
+ for (int i = 0; i < 10; i++) {
+ assertThat(qm.requestQuota()).isTrue();
+ }
+ for (int i = 0; i < 10; i++) {
+ assertThat(qm.requestQuota()).isFalse();
+ }
+
+ long now = mClock.getElapsedSinceBootMillis();
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(now + DAY_MILLIS - 1000);
+ for (int i = 0; i < 10; i++) {
+ assertThat(qm.requestQuota()).isFalse();
+ }
+ }
+}