summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Su <dysu@google.com>2019-05-22 09:44:24 -0700
committerandroid-build-merger <android-build-merger@google.com>2019-05-22 09:44:24 -0700
commit9cf15a3a841992b94271fa52fb9d23432572a46d (patch)
tree7938d5dca8b07c3fa021b378b771774415fa4fdf
parent328f6b90bb7f14559a744814775ca3db6240534e (diff)
parentea1688cfc1965d9a61682173276cb9446ce101bb (diff)
Merge "Adjust link probe manager parameters using experiment results" into qt-dev
am: ea1688cfc1 Change-Id: I9341c770add4c77782b39f57997874cd8fff6c2d
-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();
+ }
+ }
+}