From 2800851c885bd0f228e42a587c1db33da98f29ce Mon Sep 17 00:00:00 2001 From: Kai Shi Date: Thu, 25 Jun 2020 23:29:12 -0700 Subject: Bug fix channel utilization during high traffic In some wifi hal implmentations, ccaBusyTime includes the device's own packet Rx time which results in high channel utilization during full-buffer downlink throughput test. The fix is to add config_wifiChannelUtilizationOverridingEnabled to allow OEM to use fixed band-dependent values. These band-dependent values are programmable through overlay. Test: atest com.android.server.wifi Test: manually check reported cca level during iperf downlink and uplink test Bug: 159866355 Change-Id: If8432929f767ceaf6f18a7d269636dcaf909f33a Merged-In: I6e131f149d242e5dbf0b8b0087303e85ed428f9f --- .../server/wifi/WifiChannelUtilization.java | 27 +++++++++++++++++-- .../java/com/android/server/wifi/WifiInjector.java | 4 +-- service/res/values/config.xml | 9 +++++++ service/res/values/overlayable.xml | 4 +++ .../server/wifi/WifiChannelUtilizationTest.java | 30 +++++++++++++++++++++- .../com/android/server/wifi/WifiDataStallTest.java | 2 +- 6 files changed, 70 insertions(+), 6 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiChannelUtilization.java b/service/java/com/android/server/wifi/WifiChannelUtilization.java index 906e2d04c..5e8cde61d 100644 --- a/service/java/com/android/server/wifi/WifiChannelUtilization.java +++ b/service/java/com/android/server/wifi/WifiChannelUtilization.java @@ -19,6 +19,8 @@ package com.android.server.wifi; import static android.net.wifi.WifiManager.DEVICE_MOBILITY_STATE_STATIONARY; import static android.net.wifi.WifiManager.DEVICE_MOBILITY_STATE_UNKNOWN; +import android.content.Context; +import android.net.wifi.ScanResult; import android.net.wifi.WifiManager.DeviceMobilityState; import android.util.Log; import android.util.SparseArray; @@ -27,6 +29,7 @@ import android.util.SparseIntArray; import com.android.internal.annotations.VisibleForTesting; import com.android.server.wifi.WifiLinkLayerStats.ChannelStats; import com.android.server.wifi.util.InformationElementUtil.BssLoad; +import com.android.wifi.resources.R; import java.util.ArrayDeque; import java.util.Iterator; @@ -60,6 +63,7 @@ public class WifiChannelUtilization { @VisibleForTesting static final int CHANNEL_STATS_CACHE_SIZE = 5; private final Clock mClock; + private final Context mContext; private @DeviceMobilityState int mDeviceMobilityState = DEVICE_MOBILITY_STATE_UNKNOWN; private int mCacheUpdateIntervalMinMs = DEFAULT_CACHE_UPDATE_INTERVAL_MIN_MS; @@ -72,7 +76,8 @@ public class WifiChannelUtilization { private long mLastChannelStatsMapTimeStamp; private int mLastChannelStatsMapMobilityState; - WifiChannelUtilization(Clock clock) { + WifiChannelUtilization(Clock clock, Context context) { + mContext = context; mClock = clock; } @@ -85,7 +90,7 @@ public class WifiChannelUtilization { } /** - * Initialize internal variables and status after wifi is enabled + * (Re)initialize internal variables and status * @param wifiLinkLayerStats The latest wifi link layer stats */ public void init(WifiLinkLayerStats wifiLinkLayerStats) { @@ -120,6 +125,19 @@ public class WifiChannelUtilization { * @return Utilization ratio value if it is available; BssLoad.INVALID otherwise */ public int getUtilizationRatio(int frequency) { + if (mContext.getResources().getBoolean( + R.bool.config_wifiChannelUtilizationOverrideEnabled)) { + if (ScanResult.is24GHz(frequency)) { + return mContext.getResources().getInteger( + R.integer.config_wifiChannelUtilizationOverride2g); + } + if (ScanResult.is5GHz(frequency)) { + return mContext.getResources().getInteger( + R.integer.config_wifiChannelUtilizationOverride5g); + } + return mContext.getResources().getInteger( + R.integer.config_wifiChannelUtilizationOverride6g); + } return mChannelUtilizationMap.get(frequency, BssLoad.INVALID); } @@ -153,6 +171,11 @@ public class WifiChannelUtilization { */ public void refreshChannelStatsAndChannelUtilization(WifiLinkLayerStats wifiLinkLayerStats, int frequency) { + if (mContext.getResources().getBoolean( + R.bool.config_wifiChannelUtilizationOverrideEnabled)) { + return; + } + if (wifiLinkLayerStats == null) { return; } diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index 8f6465b00..b9aa0521f 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -329,7 +329,7 @@ public class WifiInjector { mWifiDiagnostics = new WifiDiagnostics( mContext, this, mWifiNative, mBuildProperties, new LastMileLogger(this), mClock); - mWifiChannelUtilizationConnected = new WifiChannelUtilization(mClock); + mWifiChannelUtilizationConnected = new WifiChannelUtilization(mClock, mContext); mWifiDataStall = new WifiDataStall(mFrameworkFacade, mWifiMetrics, mContext, mDeviceConfigFacade, mWifiChannelUtilizationConnected, mClock, wifiHandler, mThroughputPredictor); @@ -617,7 +617,7 @@ public class WifiInjector { mBssidBlocklistMonitor = new BssidBlocklistMonitor(mContext, mWifiConnectivityHelper, mWifiLastResortWatchdog, mClock, mConnectivityLocalLog, mWifiScoreCard); mWifiMetrics.setBssidBlocklistMonitor(mBssidBlocklistMonitor); - mWifiChannelUtilizationScan = new WifiChannelUtilization(mClock); + mWifiChannelUtilizationScan = new WifiChannelUtilization(mClock, mContext); return new WifiConnectivityManager(mContext, getScoringParams(), clientModeImpl, this, mWifiConfigManager, mWifiNetworkSuggestionsManager, clientModeImpl.getWifiInfo(), diff --git a/service/res/values/config.xml b/service/res/values/config.xml index 4ea23adc0..cc80f608c 100644 --- a/service/res/values/config.xml +++ b/service/res/values/config.xml @@ -422,6 +422,15 @@ 3000 + + true + + 80 + 15 + 10 + true diff --git a/service/res/values/overlayable.xml b/service/res/values/overlayable.xml index b02eb9e77..a4b7011b0 100644 --- a/service/res/values/overlayable.xml +++ b/service/res/values/overlayable.xml @@ -132,6 +132,10 @@ + + + + diff --git a/tests/wifitests/src/com/android/server/wifi/WifiChannelUtilizationTest.java b/tests/wifitests/src/com/android/server/wifi/WifiChannelUtilizationTest.java index 31fc7b7a9..bb6ff74a3 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiChannelUtilizationTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiChannelUtilizationTest.java @@ -30,10 +30,13 @@ import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.*; import static org.mockito.Mockito.validateMockitoUsage; +import android.content.Context; + import androidx.test.filters.SmallTest; import com.android.server.wifi.WifiLinkLayerStats.ChannelStats; import com.android.server.wifi.util.InformationElementUtil.BssLoad; +import com.android.wifi.resources.R; import org.junit.After; import org.junit.Before; @@ -48,13 +51,19 @@ import org.mockito.MockitoAnnotations; public class WifiChannelUtilizationTest extends WifiBaseTest { private WifiChannelUtilization mWifiChannelUtilization; @Mock private Clock mClock; + @Mock Context mContext; + MockResources mMockResources = new MockResources(); /** * Called before each test */ @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mWifiChannelUtilization = new WifiChannelUtilization(mClock); + when(mContext.getResources()).thenReturn(mMockResources); + mMockResources.setBoolean( + R.bool.config_wifiChannelUtilizationOverrideEnabled, + false); + mWifiChannelUtilization = new WifiChannelUtilization(mClock, mContext); mWifiChannelUtilization.init(null); } @@ -428,4 +437,23 @@ public class WifiChannelUtilizationTest extends WifiBaseTest { mWifiChannelUtilization.setUtilizationRatio(freq, utilizationRatio); assertEquals(utilizationRatio, mWifiChannelUtilization.getUtilizationRatio(freq)); } + + @Test + public void verifyOverridingUtilizationRatio() throws Exception { + mMockResources.setBoolean( + R.bool.config_wifiChannelUtilizationOverrideEnabled, + true); + mMockResources.setInteger( + R.integer.config_wifiChannelUtilizationOverride2g, + 60); + mMockResources.setInteger( + R.integer.config_wifiChannelUtilizationOverride5g, + 20); + mMockResources.setInteger( + R.integer.config_wifiChannelUtilizationOverride6g, + 10); + assertEquals(60, mWifiChannelUtilization.getUtilizationRatio(2412)); + assertEquals(20, mWifiChannelUtilization.getUtilizationRatio(5810)); + assertEquals(10, mWifiChannelUtilization.getUtilizationRatio(6710)); + } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java b/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java index 61979f1e8..b1eb5e9a8 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java @@ -212,7 +212,7 @@ public class WifiDataStallTest extends WifiBaseTest { } /** - * Verify throughtput when Rx link speed is unavailable. + * Verify throughput when Rx link speed is unavailable. * Also verify the logging of channel utilization and throughput. */ @Test -- cgit v1.2.3 From 2b435c05d7d588b665d9ad0f1728b9d0bb02395b Mon Sep 17 00:00:00 2001 From: Kai Shi Date: Mon, 29 Jun 2020 18:56:30 -0700 Subject: Bug fix of Tx PER when packet count is low Use default Tx PER when packet count is low because PER estimation is unreliable with low Tx packet count. Bug: 159866355 Test: atest com.android.server.wifi Change-Id: Ide48ab41420c9c907fc50a32aef10b47360209d4 --- service/java/com/android/server/wifi/DeviceConfigFacade.java | 2 +- service/java/com/android/server/wifi/WifiDataStall.java | 8 +++++--- .../wifitests/src/com/android/server/wifi/WifiDataStallTest.java | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/service/java/com/android/server/wifi/DeviceConfigFacade.java b/service/java/com/android/server/wifi/DeviceConfigFacade.java index 0e43a0891..0b707701f 100644 --- a/service/java/com/android/server/wifi/DeviceConfigFacade.java +++ b/service/java/com/android/server/wifi/DeviceConfigFacade.java @@ -66,7 +66,7 @@ public class DeviceConfigFacade { // Denominator part of default threshold of L2 throughput over L3 throughput ratio public static final int DEFAULT_TPUT_SUFFICIENT_RATIO_THR_DEN = 1; // Default threshold of Tx packet per second - public static final int DEFAULT_TX_PACKET_PER_SECOND_THR = 1; + public static final int DEFAULT_TX_PACKET_PER_SECOND_THR = 2; // Default threshold of Rx packet per second public static final int DEFAULT_RX_PACKET_PER_SECOND_THR = 1; // Default high threshold values for various connection/disconnection cases diff --git a/service/java/com/android/server/wifi/WifiDataStall.java b/service/java/com/android/server/wifi/WifiDataStall.java index 7ae577900..ebc184773 100644 --- a/service/java/com/android/server/wifi/WifiDataStall.java +++ b/service/java/com/android/server/wifi/WifiDataStall.java @@ -296,7 +296,8 @@ public class WifiDataStall { } logd(" ccaLevel = " + ccaLevel); - int txPer = updateTxPer(txSuccessDelta, txRetriesDelta, isSameBssidAndFreq); + int txPer = updateTxPer(txSuccessDelta, txRetriesDelta, isSameBssidAndFreq, + isTxTrafficHigh); boolean isTxTputLow = false; boolean isRxTputLow = false; @@ -397,12 +398,13 @@ public class WifiDataStall { return WifiIsUnusableEvent.TYPE_UNKNOWN; } - private int updateTxPer(long txSuccessDelta, long txRetriesDelta, boolean isSameBssidAndFreq) { + private int updateTxPer(long txSuccessDelta, long txRetriesDelta, boolean isSameBssidAndFreq, + boolean isTxTrafficHigh) { if (!isSameBssidAndFreq) { return DEFAULT_TX_PACKET_ERROR_RATE; } long txAttempts = txSuccessDelta + txRetriesDelta; - if (txAttempts <= 0) { + if (txAttempts <= 0 || !isTxTrafficHigh) { return DEFAULT_TX_PACKET_ERROR_RATE; } return (int) (txRetriesDelta * 100 / txAttempts); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java b/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java index 61979f1e8..4ed08a3d1 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java @@ -342,7 +342,7 @@ public class WifiDataStallTest extends WifiBaseTest { assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN, mWifiDataStall .checkDataStallAndThroughputSufficiency(mOldLlStats, mNewLlStats, mWifiInfo)); assertEquals(true, mWifiDataStall.isThroughputSufficient()); - assertEquals(4804, mWifiDataStall.getTxThroughputKbps()); + assertEquals(9128, mWifiDataStall.getTxThroughputKbps()); assertEquals(-1, mWifiDataStall.getRxThroughputKbps()); verify(mWifiMetrics, never()).logWifiIsUnusableEvent(anyInt()); } @@ -400,7 +400,7 @@ public class WifiDataStallTest extends WifiBaseTest { assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN, mWifiDataStall .checkDataStallAndThroughputSufficiency(mOldLlStats, mNewLlStats, mWifiInfo)); assertEquals(true, mWifiDataStall.isThroughputSufficient()); - assertEquals(4707, mWifiDataStall.getTxThroughputKbps()); + assertEquals(8943, mWifiDataStall.getTxThroughputKbps()); assertEquals(9414, mWifiDataStall.getRxThroughputKbps()); } -- cgit v1.2.3