diff options
4 files changed, 138 insertions, 139 deletions
diff --git a/service/java/com/android/server/wifi/ExtendedWifiInfo.java b/service/java/com/android/server/wifi/ExtendedWifiInfo.java index 6b7ae5ab6..93c508288 100644 --- a/service/java/com/android/server/wifi/ExtendedWifiInfo.java +++ b/service/java/com/android/server/wifi/ExtendedWifiInfo.java @@ -16,6 +16,7 @@ package com.android.server.wifi; +import android.annotation.NonNull; import android.net.wifi.WifiInfo; /** @@ -24,13 +25,18 @@ import android.net.wifi.WifiInfo; 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 static final int SOURCE_UNKNOWN = 0; + private static final int SOURCE_TRAFFIC_COUNTERS = 1; + private static final int SOURCE_LLSTATS = 2; + private int mLastSource = SOURCE_UNKNOWN; private long mLastPacketCountUpdateTimeStamp = RESET_TIME_STAMP; private boolean mEnableConnectedMacRandomization = false; @Override public void reset() { super.reset(); + mLastSource = SOURCE_UNKNOWN; mLastPacketCountUpdateTimeStamp = RESET_TIME_STAMP; if (mEnableConnectedMacRandomization) { setMacAddress(DEFAULT_MAC_ADDRESS); @@ -43,84 +49,59 @@ public class ExtendedWifiInfo extends WifiInfo { * @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; - } + public void updatePacketRates(@NonNull WifiLinkLayerStats stats, long timeStamp) { + 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 txbad = stats.lostmpdu_be + stats.lostmpdu_bk + stats.lostmpdu_vi + stats.lostmpdu_vo; + long rxgood = stats.rxmpdu_be + stats.rxmpdu_bk + stats.rxmpdu_vi + stats.rxmpdu_vo; + update(SOURCE_LLSTATS, txgood, txretries, txbad, rxgood, timeStamp); } /** * 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); + public void updatePacketRates(long txPackets, long rxPackets, long timeStamp) { + update(SOURCE_TRAFFIC_COUNTERS, txPackets, 0, 0, rxPackets, timeStamp); + } + + private void update(int source, long txgood, long txretries, long txbad, long rxgood, + long timeStamp) { + if (source == mLastSource + && 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; + mLastSource = source; } - txSuccess = txPackets; - rxSuccess = rxPackets; + txBad = txbad; + txSuccess = txgood; + rxSuccess = rxgood; + txRetries = txretries; + mLastPacketCountUpdateTimeStamp = timeStamp; } /** diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 4a0a24a21..18241d57a 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -314,8 +314,6 @@ public class WifiStateMachine extends StateMachine { private final NetworkCapabilities mDfltNetworkCapabilities; private SupplicantStateTracker mSupplicantStateTracker; - private int mWifiLinkLayerStatsSupported = 4; // Temporary disable - // Indicates that framework is attempting to roam, set true on CMD_START_ROAM, set false when // wifi connects or fails to connect private boolean mIsAutoRoaming = false; @@ -696,15 +694,6 @@ public class WifiStateMachine extends StateMachine { */ private long mSupplicantScanIntervalMs; - private final int mThresholdQualifiedRssi24; - private final int mThresholdQualifiedRssi5; - private final int mThresholdSaturatedRssi24; - private final int mThresholdSaturatedRssi5; - private final int mThresholdMinimumRssi5; - private final int mThresholdMinimumRssi24; - private final boolean mEnableChipWakeUpWhenAssociated; - private final boolean mEnableRssiPollWhenAssociated; - int mRunningBeaconCount = 0; /* Default parent state */ @@ -903,22 +892,6 @@ public class WifiStateMachine extends StateMachine { mTcpBufferSizes = mContext.getResources().getString( com.android.internal.R.string.config_wifi_tcp_buffers); - // Load Device configs - mThresholdQualifiedRssi24 = context.getResources().getInteger( - R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_24GHz); - mThresholdQualifiedRssi5 = context.getResources().getInteger( - R.integer.config_wifi_framework_wifi_score_low_rssi_threshold_5GHz); - mThresholdSaturatedRssi24 = context.getResources().getInteger( - R.integer.config_wifi_framework_wifi_score_good_rssi_threshold_24GHz); - mThresholdSaturatedRssi5 = context.getResources().getInteger( - R.integer.config_wifi_framework_wifi_score_good_rssi_threshold_5GHz); - mThresholdMinimumRssi5 = context.getResources().getInteger( - R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz); - mThresholdMinimumRssi24 = context.getResources().getInteger( - R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz); - mEnableChipWakeUpWhenAssociated = true; - mEnableRssiPollWhenAssociated = true; - // CHECKSTYLE:OFF IndentationCheck addState(mDefaultState); addState(mConnectModeState, mDefaultState); @@ -1280,25 +1253,18 @@ public class WifiStateMachine extends StateMachine { loge("getWifiLinkLayerStats called without an interface"); return null; } - WifiLinkLayerStats stats = null; - if (mWifiLinkLayerStatsSupported > 0) { - stats = mWifiNative.getWifiLinkLayerStats(mInterfaceName); - if (stats == null && mWifiLinkLayerStatsSupported > 0) { - mWifiLinkLayerStatsSupported -= 1; - } else if (stats != null) { - lastLinkLayerStatsUpdate = mClock.getWallClockMillis(); - mOnTime = stats.on_time; - mTxTime = stats.tx_time; - mRxTime = stats.rx_time; - mRunningBeaconCount = stats.beacon_rx; - } - } - if (stats == null || mWifiLinkLayerStatsSupported <= 0) { + lastLinkLayerStatsUpdate = mClock.getWallClockMillis(); + WifiLinkLayerStats stats = mWifiNative.getWifiLinkLayerStats(mInterfaceName); + if (stats != null) { + mOnTime = stats.on_time; + mTxTime = stats.tx_time; + mRxTime = stats.rx_time; + mRunningBeaconCount = stats.beacon_rx; + mWifiInfo.updatePacketRates(stats, lastLinkLayerStatsUpdate); + } else { long mTxPkts = mFacade.getTxPackets(mInterfaceName); long mRxPkts = mFacade.getRxPackets(mInterfaceName); - mWifiInfo.updatePacketRates(mTxPkts, mRxPkts); - } else { - mWifiInfo.updatePacketRates(stats, lastLinkLayerStatsUpdate); + mWifiInfo.updatePacketRates(mTxPkts, mRxPkts, lastLinkLayerStatsUpdate); } return stats; } @@ -4873,28 +4839,15 @@ public class WifiStateMachine extends StateMachine { break; case CMD_RSSI_POLL: if (message.arg1 == mRssiPollToken) { - if (mEnableChipWakeUpWhenAssociated) { - if (mVerboseLoggingEnabled) { - log(" get link layer stats " + mWifiLinkLayerStatsSupported); - } - WifiLinkLayerStats stats = getWifiLinkLayerStats(); - if (stats != null) { - // Sanity check the results provided by driver - if (mWifiInfo.getRssi() != WifiInfo.INVALID_RSSI - && (stats.rssi_mgmt == 0 - || stats.beacon_rx == 0)) { - stats = null; - } - } - // Get Info and continue polling - fetchRssiLinkSpeedAndFrequencyNative(); - // Send the update score to network agent. - mWifiScoreReport.calculateAndReportScore( - mWifiInfo, mNetworkAgent, mWifiMetrics); - if (mWifiScoreReport.shouldCheckIpLayer()) { - mIpClient.confirmConfiguration(); - mWifiScoreReport.noteIpCheck(); - } + getWifiLinkLayerStats(); + // Get Info and continue polling + fetchRssiLinkSpeedAndFrequencyNative(); + // Send the update score to network agent. + mWifiScoreReport.calculateAndReportScore( + mWifiInfo, mNetworkAgent, mWifiMetrics); + if (mWifiScoreReport.shouldCheckIpLayer()) { + mIpClient.confirmConfiguration(); + mWifiScoreReport.noteIpCheck(); } sendMessageDelayed(obtainMessage(CMD_RSSI_POLL, mRssiPollToken, 0), mPollRssiIntervalMsecs); @@ -4905,11 +4858,7 @@ public class WifiStateMachine extends StateMachine { break; case CMD_ENABLE_RSSI_POLL: cleanWifiScore(); - if (mEnableRssiPollWhenAssociated) { - mEnableRssiPolling = (message.arg1 == 1); - } else { - mEnableRssiPolling = false; - } + mEnableRssiPolling = (message.arg1 == 1); mRssiPollToken++; if (mEnableRssiPolling) { // First poll diff --git a/tests/wifitests/src/com/android/server/wifi/WifiLinkLayerStatsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiLinkLayerStatsTest.java index 0189aed07..638b637c6 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiLinkLayerStatsTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiLinkLayerStatsTest.java @@ -17,6 +17,7 @@ package com.android.server.wifi; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; @@ -121,4 +122,43 @@ public class WifiLinkLayerStatsTest { mWifiInfo.updatePacketRates(mWifiLinkLayerStats, mWifiLinkLayerStats.timeStampInMs); assertEquals(0.33, mWifiInfo.txSuccessRate, 0.01); } + + /** + * Check for bad interactions with the alternative updatePacketRates method + */ + @Test + public void afterSourceSwitchTheRatesShouldGetReset() throws Exception { + // Do some updates using link layer stats + bumpCounters(mWifiLinkLayerStats, 999, 999, 999, 999); + mWifiLinkLayerStats.timeStampInMs = 999999999; + mWifiInfo.updatePacketRates(mWifiLinkLayerStats, mWifiLinkLayerStats.timeStampInMs); + assertEquals(0.0, mWifiInfo.txSuccessRate, 0.0001); + assertEquals(0.0, mWifiInfo.rxSuccessRate, 0.0001); + bumpCounters(mWifiLinkLayerStats, 1_000_000_000, 777000, 66600, 1_000_100_000); + mWifiLinkLayerStats.timeStampInMs += 10_000; + mWifiInfo.updatePacketRates(mWifiLinkLayerStats, mWifiLinkLayerStats.timeStampInMs); + assertTrue("" + mWifiInfo + " " + mWifiLinkLayerStats, mWifiInfo.txSuccessRate > 0.95e+8); + assertTrue("" + mWifiInfo + " " + mWifiLinkLayerStats, mWifiInfo.rxSuccessRate > 0.95e+8); + // Now update with traffic counters + mWifiLinkLayerStats.timeStampInMs += 10_000; + mWifiInfo.updatePacketRates(2_000_000_000L, 2_000_000_000L, + mWifiLinkLayerStats.timeStampInMs); + // Despite the increase, the rates should be zero after the change in source + assertEquals(0.0, mWifiInfo.txSuccessRate, 0.0001); + assertEquals(0.0, mWifiInfo.rxSuccessRate, 0.0001); + assertEquals(0, mWifiInfo.txBad); + assertEquals(0, mWifiInfo.txRetries); + // Make sure that updates from this source work, too + mWifiLinkLayerStats.timeStampInMs += 10_000; + mWifiInfo.updatePacketRates(3_000_000_000L, 3_000_000_000L, + mWifiLinkLayerStats.timeStampInMs); + assertTrue(mWifiInfo.txSuccessRate > 0.95e+8); + assertTrue(mWifiInfo.rxSuccessRate > 0.95e+8); + // Switch back to using link layer stats + mWifiLinkLayerStats.timeStampInMs += 10_000; + bumpCounters(mWifiLinkLayerStats, 1_000_000_000, 777000, 66600, 1_000_100_000); + mWifiInfo.updatePacketRates(mWifiLinkLayerStats, mWifiLinkLayerStats.timeStampInMs); + assertEquals(0.0, mWifiInfo.txSuccessRate, 0.0001); + assertEquals(0.0, mWifiInfo.rxSuccessRate, 0.0001); + } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index 86692c8ce..79966d7f1 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -2119,6 +2119,35 @@ public class WifiStateMachineTest { } /** + * Verify that RSSI and link layer stats polling works in connected mode + */ + @Test + public void verifyConnectedModeRssiPolling() throws Exception { + final long startMillis = 1_500_000_000_100L; + WifiLinkLayerStats llStats = new WifiLinkLayerStats(); + llStats.txmpdu_be = 1000; + llStats.rxmpdu_bk = 2000; + WifiNative.SignalPollResult signalPollResult = new WifiNative.SignalPollResult(); + signalPollResult.currentRssi = -42; + signalPollResult.txBitrate = 65; + signalPollResult.associationFrequency = sFreq; + when(mWifiNative.getWifiLinkLayerStats(any())).thenReturn(llStats); + when(mWifiNative.signalPoll(any())).thenReturn(signalPollResult); + when(mClock.getWallClockMillis()).thenReturn(startMillis + 0); + mWsm.enableRssiPolling(true); + connect(); + mLooper.dispatchAll(); + when(mClock.getWallClockMillis()).thenReturn(startMillis + 3333); + mLooper.dispatchAll(); + WifiInfo wifiInfo = mWsm.getWifiInfo(); + assertEquals(llStats.txmpdu_be, wifiInfo.txSuccess); + assertEquals(llStats.rxmpdu_bk, wifiInfo.rxSuccess); + assertEquals(signalPollResult.currentRssi, wifiInfo.getRssi()); + assertEquals(signalPollResult.txBitrate, wifiInfo.getLinkSpeed()); + assertEquals(sFreq, wifiInfo.getFrequency()); + } + + /** * Verify that calls to start and stop filtering multicast packets are passed on to the IpClient * instance. */ |