Merge "Add WakeupConfigStoreData for reading and writing to config store."
diff --git a/service/java/com/android/server/wifi/ExtendedWifiInfo.java b/service/java/com/android/server/wifi/ExtendedWifiInfo.java
new file mode 100644
index 0000000..5edbd34
--- /dev/null
+++ b/service/java/com/android/server/wifi/ExtendedWifiInfo.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2017 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;
+
+import android.net.wifi.WifiInfo;
+
+/**
+ * Extends WifiInfo with the methods for computing the averaged packet rates
+ */
+public class ExtendedWifiInfo extends WifiInfo {
+ private static final long RESET_TIME_STAMP = Long.MIN_VALUE;
+ private static final double FILTER_TIME_CONSTANT = 3000.0;
+
+ private long mLastPacketCountUpdateTimeStamp = RESET_TIME_STAMP;
+
+ @Override
+ public void reset() {
+ super.reset();
+ mLastPacketCountUpdateTimeStamp = RESET_TIME_STAMP;
+ }
+
+ /**
+ * Updates the packet rates using link layer stats
+ *
+ * @param stats WifiLinkLayerStats
+ * @param timeStamp time in milliseconds
+ */
+ public void updatePacketRates(WifiLinkLayerStats stats, long timeStamp) {
+ if (stats != null) {
+ long txgood = stats.txmpdu_be + stats.txmpdu_bk + stats.txmpdu_vi + stats.txmpdu_vo;
+ long txretries = stats.retries_be + stats.retries_bk
+ + stats.retries_vi + stats.retries_vo;
+ long rxgood = stats.rxmpdu_be + stats.rxmpdu_bk + stats.rxmpdu_vi + stats.rxmpdu_vo;
+ long txbad = stats.lostmpdu_be + stats.lostmpdu_bk
+ + stats.lostmpdu_vi + stats.lostmpdu_vo;
+
+ if (mLastPacketCountUpdateTimeStamp != RESET_TIME_STAMP
+ && mLastPacketCountUpdateTimeStamp < timeStamp
+ && txBad <= txbad
+ && txSuccess <= txgood
+ && rxSuccess <= rxgood
+ && txRetries <= txretries) {
+ long timeDelta = timeStamp - mLastPacketCountUpdateTimeStamp;
+ double lastSampleWeight = Math.exp(-1.0 * timeDelta / FILTER_TIME_CONSTANT);
+ double currentSampleWeight = 1.0 - lastSampleWeight;
+
+ txBadRate = txBadRate * lastSampleWeight
+ + (txbad - txBad) * 1000.0 / timeDelta
+ * currentSampleWeight;
+ txSuccessRate = txSuccessRate * lastSampleWeight
+ + (txgood - txSuccess) * 1000.0 / timeDelta
+ * currentSampleWeight;
+ rxSuccessRate = rxSuccessRate * lastSampleWeight
+ + (rxgood - rxSuccess) * 1000.0 / timeDelta
+ * currentSampleWeight;
+ txRetriesRate = txRetriesRate * lastSampleWeight
+ + (txretries - txRetries) * 1000.0 / timeDelta
+ * currentSampleWeight;
+ } else {
+ txBadRate = 0;
+ txSuccessRate = 0;
+ rxSuccessRate = 0;
+ txRetriesRate = 0;
+ }
+ txBad = txbad;
+ txSuccess = txgood;
+ rxSuccess = rxgood;
+ txRetries = txretries;
+ mLastPacketCountUpdateTimeStamp = timeStamp;
+ } else {
+ txBad = 0;
+ txSuccess = 0;
+ rxSuccess = 0;
+ txRetries = 0;
+ txBadRate = 0;
+ txSuccessRate = 0;
+ rxSuccessRate = 0;
+ txRetriesRate = 0;
+ mLastPacketCountUpdateTimeStamp = RESET_TIME_STAMP;
+ }
+ }
+
+ /**
+ * This function is less powerful and used if the WifiLinkLayerStats API is not implemented
+ * at the Wifi HAL
+ *
+ * @hide
+ */
+ public void updatePacketRates(long txPackets, long rxPackets) {
+ //paranoia
+ txBad = 0;
+ txRetries = 0;
+ txBadRate = 0;
+ txRetriesRate = 0;
+ if (txSuccess <= txPackets && rxSuccess <= rxPackets) {
+ txSuccessRate = (txSuccessRate * 0.5)
+ + ((double) (txPackets - txSuccess) * 0.5);
+ rxSuccessRate = (rxSuccessRate * 0.5)
+ + ((double) (rxPackets - rxSuccess) * 0.5);
+ } else {
+ txBadRate = 0;
+ txRetriesRate = 0;
+ }
+ txSuccess = txPackets;
+ rxSuccess = rxPackets;
+ }
+
+
+}
diff --git a/service/java/com/android/server/wifi/LegacyConnectedScore.java b/service/java/com/android/server/wifi/LegacyConnectedScore.java
index facab0a..3027696 100644
--- a/service/java/com/android/server/wifi/LegacyConnectedScore.java
+++ b/service/java/com/android/server/wifi/LegacyConnectedScore.java
@@ -63,6 +63,10 @@
private boolean mMultiBandScanResults;
private boolean mIsHomeNetwork;
private int mScore = 0;
+ private int mBadRssiCount;
+ private int mLinkStuckCount;
+ private int mLowRssiCount;
+
LegacyConnectedScore(Context context, WifiConfigManager wifiConfigManager, Clock clock) {
super(clock);
@@ -109,32 +113,32 @@
rssi += WifiConfiguration.HOME_NETWORK_RSSI_BOOST;
}
- if ((wifiInfo.txBadRate >= 1)
- && (wifiInfo.txSuccessRate < MAX_SUCCESS_RATE_OF_STUCK_LINK)
+ if ((wifiInfo.txBadRate * 5 >= 1)
+ && (wifiInfo.txSuccessRate * 5 < MAX_SUCCESS_RATE_OF_STUCK_LINK)
&& rssi < rssiThreshLow) {
// Link is stuck
- if (wifiInfo.linkStuckCount < MAX_STUCK_LINK_COUNT) {
- wifiInfo.linkStuckCount += 1;
+ if (mLinkStuckCount < MAX_STUCK_LINK_COUNT) {
+ mLinkStuckCount += 1;
}
- } else if (wifiInfo.txBadRate < MIN_TX_FAILURE_RATE_FOR_WORKING_LINK) {
- if (wifiInfo.linkStuckCount > 0) {
- wifiInfo.linkStuckCount -= 1;
+ } else if (wifiInfo.txBadRate * 5 < MIN_TX_FAILURE_RATE_FOR_WORKING_LINK) {
+ if (mLinkStuckCount > 0) {
+ mLinkStuckCount -= 1;
}
}
if (rssi < rssiThreshBad) {
- if (wifiInfo.badRssiCount < MAX_BAD_RSSI_COUNT) {
- wifiInfo.badRssiCount += 1;
+ if (mBadRssiCount < MAX_BAD_RSSI_COUNT) {
+ mBadRssiCount += 1;
}
} else if (rssi < rssiThreshLow) {
- wifiInfo.lowRssiCount = MAX_LOW_RSSI_COUNT; // Dont increment the lowRssi count above 1
- if (wifiInfo.badRssiCount > 0) {
+ mLowRssiCount = MAX_LOW_RSSI_COUNT; // Dont increment the lowRssi count above 1
+ if (mBadRssiCount > 0) {
// Decrement bad Rssi count
- wifiInfo.badRssiCount -= 1;
+ mBadRssiCount -= 1;
}
} else {
- wifiInfo.badRssiCount = 0;
- wifiInfo.lowRssiCount = 0;
+ mBadRssiCount = 0;
+ mLowRssiCount = 0;
}
// Ugh, we need to finish the score calculation while we have wifiInfo
@@ -155,6 +159,9 @@
@Override
public void reset() {
mScore = 0;
+ mBadRssiCount = 0;
+ mLinkStuckCount = 0;
+ mLowRssiCount = 0;
}
/**
@@ -182,18 +189,19 @@
int linkSpeed = wifiInfo.getLinkSpeed();
- if (wifiInfo.linkStuckCount > MIN_SUSTAINED_LINK_STUCK_COUNT) {
+ if (mLinkStuckCount > MIN_SUSTAINED_LINK_STUCK_COUNT) {
// Once link gets stuck for more than 3 seconds, start reducing the score
- score = score - LINK_STUCK_PENALTY * (wifiInfo.linkStuckCount - 1);
+ score = score - LINK_STUCK_PENALTY * (mLinkStuckCount - 1);
}
if (linkSpeed < linkspeedThreshBad) {
score -= BAD_LINKSPEED_PENALTY;
- } else if ((linkSpeed >= linkspeedThreshGood) && (wifiInfo.txSuccessRate > 5)) {
+ } else if ((linkSpeed >= linkspeedThreshGood)
+ && (wifiInfo.txSuccessRate > 1)) {
score += GOOD_LINKSPEED_BONUS; // So as bad rssi alone doesn't kill us
}
- score -= wifiInfo.badRssiCount * BAD_RSSI_COUNT_PENALTY + wifiInfo.lowRssiCount;
+ score -= mBadRssiCount * BAD_RSSI_COUNT_PENALTY + mLowRssiCount;
if (rssi >= rssiThreshSaturated) score += 5;
diff --git a/service/java/com/android/server/wifi/VelocityBasedConnectedScore.java b/service/java/com/android/server/wifi/VelocityBasedConnectedScore.java
index 69643ce..38fd1ef 100644
--- a/service/java/com/android/server/wifi/VelocityBasedConnectedScore.java
+++ b/service/java/com/android/server/wifi/VelocityBasedConnectedScore.java
@@ -146,6 +146,8 @@
return mThresholdMinimumRssi + mThresholdAdjustment;
}
+ private double mMinimumPpsForMeasuringSuccess = 2.0;
+
/**
* Adjusts the threshold if appropriate
* <p>
@@ -159,11 +161,12 @@
if (mThresholdAdjustment < -7) return;
if (mFilteredRssi >= getAdjustedRssiThreshold() + 2.0) return;
if (Math.abs(mEstimatedRateOfRssiChange) >= 0.2) return;
- if (wifiInfo.txSuccessRate < 10) return;
- if (wifiInfo.rxSuccessRate < 10) return;
- double probabilityOfSuccessfulTx = (
- wifiInfo.txSuccessRate / (wifiInfo.txSuccessRate + wifiInfo.txBadRate)
- );
+ double txSuccessPps = wifiInfo.txSuccessRate;
+ double rxSuccessPps = wifiInfo.rxSuccessRate;
+ if (txSuccessPps < mMinimumPpsForMeasuringSuccess) return;
+ if (rxSuccessPps < mMinimumPpsForMeasuringSuccess) return;
+ double txBadPps = wifiInfo.txBadRate;
+ double probabilityOfSuccessfulTx = txSuccessPps / (txSuccessPps + txBadPps);
if (probabilityOfSuccessfulTx >= 0.2) {
// May want this amount to vary with how close to threshold we are
mThresholdAdjustment -= 0.5;
diff --git a/service/java/com/android/server/wifi/WifiLinkLayerStats.java b/service/java/com/android/server/wifi/WifiLinkLayerStats.java
new file mode 100644
index 0000000..0c58670
--- /dev/null
+++ b/service/java/com/android/server/wifi/WifiLinkLayerStats.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2014 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;
+
+import java.util.Arrays;
+
+/**
+ * A class representing link layer statistics collected over a Wifi Interface.
+ */
+
+/**
+ * {@hide}
+ */
+public class WifiLinkLayerStats {
+
+ /** Number of beacons received from our own AP */
+ public int beacon_rx;
+
+ /** RSSI of management frames */
+ public int rssi_mgmt;
+
+ /* Packet counters */
+
+ /** WME Best Effort Access Category received mpdu */
+ public long rxmpdu_be;
+ /** WME Best Effort Access Category transmitted mpdu */
+ public long txmpdu_be;
+ /** WME Best Effort Access Category lost mpdu */
+ public long lostmpdu_be;
+ /** WME Best Effort Access Category number of transmission retries */
+ public long retries_be;
+
+ /** WME Background Access Category received mpdu */
+ public long rxmpdu_bk;
+ /** WME Background Access Category transmitted mpdu */
+ public long txmpdu_bk;
+ /** WME Background Access Category lost mpdu */
+ public long lostmpdu_bk;
+ /** WME Background Access Category number of transmission retries */
+ public long retries_bk;
+
+ /** WME Video Access Category received mpdu */
+ public long rxmpdu_vi;
+ /** WME Video Access Category transmitted mpdu */
+ public long txmpdu_vi;
+ /** WME Video Access Category lost mpdu */
+ public long lostmpdu_vi;
+ /** WME Video Access Category number of transmission retries */
+ public long retries_vi;
+
+ /** WME Voice Access Category received mpdu */
+ public long rxmpdu_vo;
+ /** WME Voice Access Category transmitted mpdu */
+ public long txmpdu_vo;
+ /** WME Voice Access Category lost mpdu */
+ public long lostmpdu_vo;
+ /** WME Voice Access Category number of transmission retries */
+ public long retries_vo;
+
+ /**
+ * Cumulative milliseconds when radio is awake
+ */
+ public int on_time;
+ /**
+ * Cumulative milliseconds of active transmission
+ */
+ public int tx_time;
+ /**
+ * Cumulative milliseconds per level of active transmission
+ */
+ public int[] tx_time_per_level;
+ /**
+ * Cumulative milliseconds of active receive
+ */
+ public int rx_time;
+ /**
+ * Cumulative milliseconds when radio is awake due to scan
+ */
+ public int on_time_scan;
+
+ /**
+ * TimeStamp - absolute milliseconds from boot when these stats were sampled.
+ */
+ public long timeStampInMs;
+
+ @Override
+ public String toString() {
+ StringBuilder sbuf = new StringBuilder();
+ sbuf.append(" WifiLinkLayerStats: ").append('\n');
+
+ sbuf.append(" my bss beacon rx: ").append(Integer.toString(this.beacon_rx)).append('\n');
+ sbuf.append(" RSSI mgmt: ").append(Integer.toString(this.rssi_mgmt)).append('\n');
+ sbuf.append(" BE : ").append(" rx=").append(Long.toString(this.rxmpdu_be))
+ .append(" tx=").append(Long.toString(this.txmpdu_be))
+ .append(" lost=").append(Long.toString(this.lostmpdu_be))
+ .append(" retries=").append(Long.toString(this.retries_be)).append('\n');
+ sbuf.append(" BK : ").append(" rx=").append(Long.toString(this.rxmpdu_bk))
+ .append(" tx=").append(Long.toString(this.txmpdu_bk))
+ .append(" lost=").append(Long.toString(this.lostmpdu_bk))
+ .append(" retries=").append(Long.toString(this.retries_bk)).append('\n');
+ sbuf.append(" VI : ").append(" rx=").append(Long.toString(this.rxmpdu_vi))
+ .append(" tx=").append(Long.toString(this.txmpdu_vi))
+ .append(" lost=").append(Long.toString(this.lostmpdu_vi))
+ .append(" retries=").append(Long.toString(this.retries_vi)).append('\n');
+ sbuf.append(" VO : ").append(" rx=").append(Long.toString(this.rxmpdu_vo))
+ .append(" tx=").append(Long.toString(this.txmpdu_vo))
+ .append(" lost=").append(Long.toString(this.lostmpdu_vo))
+ .append(" retries=").append(Long.toString(this.retries_vo)).append('\n');
+ sbuf.append(" on_time : ").append(Integer.toString(this.on_time))
+ .append(" rx_time=").append(Integer.toString(this.rx_time))
+ .append(" scan_time=").append(Integer.toString(this.on_time_scan)).append('\n')
+ .append(" tx_time=").append(Integer.toString(this.tx_time))
+ .append(" tx_time_per_level=" + Arrays.toString(tx_time_per_level));
+ sbuf.append(" ts=" + timeStampInMs);
+ return sbuf.toString();
+ }
+
+}
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index fc815f8..2f1b550 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -25,7 +25,6 @@
import android.net.wifi.RttManager.ResponderConfig;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiLinkLayerStats;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiWakeReasonAndCounts;
import android.os.SystemClock;
diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java
index 071fc07..46ded1c 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java
@@ -152,9 +152,8 @@
boolean hasQualifiedRssi =
(wifiInfo.is24GHz() && (currentRssi > mThresholdQualifiedRssi24))
|| (wifiInfo.is5GHz() && (currentRssi > mThresholdQualifiedRssi5));
- // getTxSuccessRate() and getRxSuccessRate() returns the packet rate in per 5 seconds unit.
- boolean hasActiveStream = (wifiInfo.getTxSuccessRatePps() > mStayOnNetworkMinimumTxRate)
- || (wifiInfo.getRxSuccessRatePps() > mStayOnNetworkMinimumRxRate);
+ boolean hasActiveStream = (wifiInfo.txSuccessRate > mStayOnNetworkMinimumTxRate)
+ || (wifiInfo.rxSuccessRate > mStayOnNetworkMinimumRxRate);
if (hasQualifiedRssi && hasActiveStream) {
localLog("Stay on current network because of good RSSI and ongoing traffic");
return true;
diff --git a/service/java/com/android/server/wifi/WifiScoreReport.java b/service/java/com/android/server/wifi/WifiScoreReport.java
index e5281ef..1c258e1 100644
--- a/service/java/com/android/server/wifi/WifiScoreReport.java
+++ b/service/java/com/android/server/wifi/WifiScoreReport.java
@@ -216,7 +216,7 @@
history = new LinkedList<>(mLinkMetricsHistory);
}
pw.println("time,session,rssi,filtered_rssi,rssi_threshold,"
- + "freq,linkspeed,tx_good,tx_retry,tx_bad,rx,s0,s1,s2");
+ + "freq,linkspeed,tx_good,tx_retry,tx_bad,rx_pps,s0,s1,s2");
for (String line : history) {
pw.println(line);
}
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 8db180f..8e6a819 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -69,7 +69,6 @@
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConnectionStatistics;
import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiLinkLayerStats;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
import android.net.wifi.WifiScanner;
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index e386654..b69d67b 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -71,7 +71,6 @@
import android.net.wifi.WifiConnectionStatistics;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiLinkLayerStats;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
@@ -370,7 +369,7 @@
private DhcpResults mDhcpResults;
// NOTE: Do not return to clients - see syncRequestConnectionInfo()
- private final WifiInfo mWifiInfo;
+ private final ExtendedWifiInfo mWifiInfo;
private NetworkInfo mNetworkInfo;
private final NetworkCapabilities mDfltNetworkCapabilities;
private SupplicantStateTracker mSupplicantStateTracker;
@@ -953,7 +952,7 @@
mWifiMonitor = mWifiInjector.getWifiMonitor();
mWifiDiagnostics = mWifiInjector.makeWifiDiagnostics(mWifiNative);
- mWifiInfo = new WifiInfo();
+ mWifiInfo = new ExtendedWifiInfo();
mSupplicantStateTracker =
mFacade.makeSupplicantStateTracker(context, mWifiConfigManager, getHandler());
diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java
index d552e7d..f1d2add 100644
--- a/service/java/com/android/server/wifi/WifiVendorHal.java
+++ b/service/java/com/android/server/wifi/WifiVendorHal.java
@@ -59,7 +59,6 @@
import android.net.wifi.RttManager.ResponderConfig;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiLinkLayerStats;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
@@ -868,7 +867,6 @@
static WifiLinkLayerStats frameworkFromHalLinkLayerStats(StaLinkLayerStats stats) {
if (stats == null) return null;
WifiLinkLayerStats out = new WifiLinkLayerStats();
- // unpopulated: out.status, out.SSID, out.BSSID
out.beacon_rx = stats.iface.beaconRx;
out.rssi_mgmt = stats.iface.avgRssiMgmt;
// Statistics are broken out by Wireless Multimedia Extensions categories
@@ -904,7 +902,7 @@
out.rx_time = radioStats.rxTimeInMs;
out.on_time_scan = radioStats.onTimeInMsForScan;
}
- // unused: stats.timeStampInMs;
+ out.timeStampInMs = stats.timeStampInMs;
return out;
}
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java
index d6bec5f..f0a86bb 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java
@@ -83,7 +83,7 @@
awareIsDown();
}
}
- }, null);
+ }, mHandler);
if (mHalDeviceManager.isStarted()) {
mHalDeviceManager.registerInterfaceAvailableForRequestListener(
IfaceType.NAN, mInterfaceAvailableForRequestListener, mHandler);
diff --git a/tests/wifitests/src/com/android/server/wifi/VelocityBasedConnectedScoreTest.java b/tests/wifitests/src/com/android/server/wifi/VelocityBasedConnectedScoreTest.java
index 263cbed..6a72522 100644
--- a/tests/wifitests/src/com/android/server/wifi/VelocityBasedConnectedScoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/VelocityBasedConnectedScoreTest.java
@@ -100,9 +100,9 @@
public void allowLowRssiIfErrorRateIsLowAndSomeDataIsMoving() throws Exception {
mWifiInfo.setRssi(mRssiExitThreshold2GHz - 2);
mWifiInfo.setLinkSpeed(6); // Mbps
- mWifiInfo.txSuccessRate = 10.1; // proportional to pps
+ mWifiInfo.txSuccessRate = 2.1; // proportional to pps
mWifiInfo.txBadRate = .5;
- mWifiInfo.rxSuccessRate = 10.1;
+ mWifiInfo.rxSuccessRate = 2.1;
for (int i = 0; i < 10; i++) {
mVelocityBasedConnectedScore.updateUsingWifiInfo(mWifiInfo,
mClock.getWallClockMillis());
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiLinkLayerStatsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiLinkLayerStatsTest.java
new file mode 100644
index 0000000..0189aed
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/WifiLinkLayerStatsTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2017 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;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Random;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.WifiLinkLayerStats}.
+ */
+public class WifiLinkLayerStatsTest {
+
+ ExtendedWifiInfo mWifiInfo;
+ WifiLinkLayerStats mWifiLinkLayerStats;
+ Random mRandom = new Random();
+
+ /**
+ * Sets up for unit test
+ */
+ @Before
+ public void setUp() throws Exception {
+ mWifiInfo = new ExtendedWifiInfo();
+ mWifiLinkLayerStats = new WifiLinkLayerStats();
+ }
+
+ /**
+ * Increments the counters
+ *
+ * The values are carved up among the 4 classes (be, bk, vi, vo) so the totals come out right.
+ */
+ private void bumpCounters(WifiLinkLayerStats s, int txg, int txr, int txb, int rxg) {
+ int a = mRandom.nextInt(31);
+ int b = mRandom.nextInt(31);
+ int m0 = a & b;
+ int m1 = a & ~b;
+ int m2 = ~a & b;
+ int m3 = ~a & ~b;
+ assertEquals(-1, m0 + m1 + m2 + m3);
+
+ s.rxmpdu_be += rxg & m0;
+ s.txmpdu_be += txg & m0;
+ s.lostmpdu_be += txb & m0;
+ s.retries_be += txr & m0;
+
+ s.rxmpdu_bk += rxg & m1;
+ s.txmpdu_bk += txg & m1;
+ s.lostmpdu_bk += txb & m1;
+ s.retries_bk += txr & m1;
+
+ s.rxmpdu_vi += rxg & m2;
+ s.txmpdu_vi += txg & m2;
+ s.lostmpdu_vi += txb & m2;
+ s.retries_vi += txr & m2;
+
+ s.rxmpdu_vo += rxg & m3;
+ s.txmpdu_vo += txg & m3;
+ s.lostmpdu_vo += txb & m3;
+ s.retries_vo += txr & m3;
+ }
+
+ /**
+ *
+ * Check that average rates converge to the right values
+ *
+ * Check that the total packet counts are correct
+ *
+ */
+ @Test
+ public void checkThatAverageRatesConvergeToTheRightValuesAndTotalsAreRight() throws Exception {
+ int txg = mRandom.nextInt(1000);
+ int txr = mRandom.nextInt(100);
+ int txb = mRandom.nextInt(100);
+ int rxg = mRandom.nextInt(1000);
+ int n = 3 * 5; // Time constant is 3 seconds, 5 times time constant should get 99% there
+ for (int i = 0; i < n; i++) {
+ bumpCounters(mWifiLinkLayerStats, txg, txr, txb, rxg);
+ mWifiLinkLayerStats.timeStampInMs += 1000;
+ mWifiInfo.updatePacketRates(mWifiLinkLayerStats, mWifiLinkLayerStats.timeStampInMs);
+ }
+ // assertEquals(double, double, double) takes a tolerance as the third argument
+ assertEquals((double) txg, mWifiInfo.txSuccessRate, txg * 0.02);
+ assertEquals((double) txr, mWifiInfo.txRetriesRate, txr * 0.02);
+ assertEquals((double) txb, mWifiInfo.txBadRate, txb * 0.02);
+ assertEquals((double) rxg, mWifiInfo.rxSuccessRate, rxg * 0.02);
+
+ assertEquals(mWifiInfo.txSuccess, n * txg);
+ assertEquals(mWifiInfo.txRetries, n * txr);
+ assertEquals(mWifiInfo.txBad, n * txb);
+ assertEquals(mWifiInfo.rxSuccess, n * rxg);
+ }
+
+ /**
+ * A single packet in a short period of time should have small effect
+ */
+ @Test
+ public void aSinglePacketInAShortPeriodOfTimeShouldHaveSmallEffect() throws Exception {
+ bumpCounters(mWifiLinkLayerStats, 999999999, 999999999, 999999999, 99999999);
+ mWifiLinkLayerStats.timeStampInMs = 999999999;
+ mWifiInfo.updatePacketRates(mWifiLinkLayerStats, mWifiLinkLayerStats.timeStampInMs);
+ assertEquals(0.0, mWifiInfo.txSuccessRate, 0.0001);
+ bumpCounters(mWifiLinkLayerStats, 1, 1, 1, 1);
+ mWifiLinkLayerStats.timeStampInMs += 1;
+ mWifiInfo.updatePacketRates(mWifiLinkLayerStats, mWifiLinkLayerStats.timeStampInMs);
+ assertEquals(0.33, mWifiInfo.txSuccessRate, 0.01);
+ }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
index 3d3af36..b56da5d 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java
@@ -613,8 +613,8 @@
// Rssi after connected.
when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi2G + 1);
// No streaming traffic.
- when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
- when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
+ mWifiInfo.txSuccessRate = 0.0;
+ mWifiInfo.rxSuccessRate = 0.0;
// Do not perform selection on 2GHz if current network is good and no 5GHz available
testStayOrTryToSwitch(
@@ -640,8 +640,8 @@
// Rssi after connected.
when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi2G + 1);
// No streaming traffic.
- when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
- when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
+ mWifiInfo.txSuccessRate = 0.0;
+ mWifiInfo.rxSuccessRate = 0.0;
// When on 2GHz, even with "good" signal strength, run selection if 5GHz available
testStayOrTryToSwitch(
@@ -670,8 +670,8 @@
// Rssi after connected.
when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi5G - 1);
// No streaming traffic.
- when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
- when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
+ mWifiInfo.txSuccessRate = 0.0;
+ mWifiInfo.rxSuccessRate = 0.0;
// Run Selection when the current 5Ghz network has low RSSI.
testStayOrTryToSwitch(
@@ -695,8 +695,8 @@
// Rssi after connected.
when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi5G + 1);
// No streaming traffic.
- when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
- when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
+ mWifiInfo.txSuccessRate = 0.0;
+ mWifiInfo.rxSuccessRate = 0.0;
// Connected to a high quality 5Ghz network, so the other result is irrelevant
testStayOrTryToSwitch(
@@ -719,8 +719,8 @@
// Rssi after connected.
when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi2G + 1);
// No streaming traffic.
- when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
- when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
+ mWifiInfo.txSuccessRate = 0.0;
+ mWifiInfo.rxSuccessRate = 0.0;
testStayOrTryToSwitch(
// Parameters for network1:
@@ -747,8 +747,8 @@
// Rssi after connected.
when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi2G - 1);
// No streaming traffic.
- when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
- when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
+ mWifiInfo.txSuccessRate = 0.0;
+ mWifiInfo.rxSuccessRate = 0.0;
testStayOrTryToSwitch(
mThresholdQualifiedRssi2G + 1 /* rssi before connected */,
@@ -769,9 +769,8 @@
// Rssi after connected.
when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi2G + 1);
// Streaming traffic
- when(mWifiInfo.getTxSuccessRatePps()).thenReturn(
- (double) (mStayOnNetworkMinimumTxRate + 1));
- when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
+ mWifiInfo.txSuccessRate = ((double) (mStayOnNetworkMinimumTxRate + 1));
+ mWifiInfo.rxSuccessRate = 0.0;
testStayOrTryToSwitch(
mThresholdQualifiedRssi2G + 1 /* rssi before connected */,
@@ -792,9 +791,8 @@
// Rssi after connected.
when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi2G + 1);
// Streaming traffic
- when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
- when(mWifiInfo.getRxSuccessRatePps()).thenReturn(
- (double) (mStayOnNetworkMinimumRxRate + 1));
+ mWifiInfo.txSuccessRate = 0.0;
+ mWifiInfo.rxSuccessRate = ((double) (mStayOnNetworkMinimumRxRate + 1));
testStayOrTryToSwitch(
mThresholdQualifiedRssi2G + 1 /* rssi before connected */,
@@ -815,9 +813,8 @@
// Rssi after connected.
when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi5G + 1);
// Streaming traffic
- when(mWifiInfo.getTxSuccessRatePps()).thenReturn(
- (double) (mStayOnNetworkMinimumTxRate + 1));
- when(mWifiInfo.getRxSuccessRatePps()).thenReturn(0.0);
+ mWifiInfo.txSuccessRate = ((double) (mStayOnNetworkMinimumTxRate + 1));
+ mWifiInfo.rxSuccessRate = 0.0;
testStayOrTryToSwitch(
mThresholdQualifiedRssi5G + 1 /* rssi before connected */,
@@ -838,9 +835,8 @@
// Rssi after connected.
when(mWifiInfo.getRssi()).thenReturn(mThresholdQualifiedRssi5G + 1);
// Streaming traffic
- when(mWifiInfo.getTxSuccessRatePps()).thenReturn(0.0);
- when(mWifiInfo.getRxSuccessRatePps()).thenReturn(
- (double) (mStayOnNetworkMinimumRxRate + 1));
+ mWifiInfo.txSuccessRate = 0.0;
+ mWifiInfo.rxSuccessRate = ((double) (mStayOnNetworkMinimumRxRate + 1));
testStayOrTryToSwitch(
mThresholdQualifiedRssi5G + 1 /* rssi before connected */,
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java b/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
index af8bda4..812ef03 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
@@ -77,7 +77,6 @@
import android.net.apf.ApfCapabilities;
import android.net.wifi.RttManager;
import android.net.wifi.ScanResult;
-import android.net.wifi.WifiLinkLayerStats;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
@@ -704,13 +703,13 @@
randomizePacketStats(r, stats.iface.wmeVoPktStats);
randomizeRadioStats(r, stats.radios);
- stats.timeStampInMs = 42; // currently dropped in conversion
+ stats.timeStampInMs = r.nextLong() & 0xFFFFFFFFFFL;
- String expected = numbersOnly(stats.toString());
+ String expected = numbersOnly(stats.toString() + " ");
WifiLinkLayerStats converted = WifiVendorHal.frameworkFromHalLinkLayerStats(stats);
- String actual = numbersOnly(converted.toString());
+ String actual = numbersOnly(converted.toString() + " ");
// Do the required fixups to the both expected and actual
expected = rmValue(expected, stats.radios.get(0).rxTimeInMs);
@@ -718,7 +717,6 @@
actual = rmValue(actual, stats.radios.get(0).rxTimeInMs);
actual = rmValue(actual, stats.radios.get(0).onTimeInMsForScan);
- actual = actual + "42 ";
// The remaining fields should agree
assertEquals(expected, actual);