Bug fix channel utilization during high traffic

In some wifi hal implmentation, 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
diff --git a/service/java/com/android/server/wifi/WifiChannelUtilization.java b/service/java/com/android/server/wifi/WifiChannelUtilization.java
index 906e2d0..5e8cde6 100644
--- a/service/java/com/android/server/wifi/WifiChannelUtilization.java
+++ b/service/java/com/android/server/wifi/WifiChannelUtilization.java
@@ -19,6 +19,8 @@
 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 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 @@
     @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 @@
     private long mLastChannelStatsMapTimeStamp;
     private int mLastChannelStatsMapMobilityState;
 
-    WifiChannelUtilization(Clock clock) {
+    WifiChannelUtilization(Clock clock, Context context) {
+        mContext = context;
         mClock = clock;
     }
 
@@ -85,7 +90,7 @@
     }
 
     /**
-     * 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 @@
      * @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 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 248a48d..ef1a5a2 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -209,9 +209,8 @@
         Looper wifiLooper = mWifiHandlerThread.getLooper();
         Handler wifiHandler = new Handler(wifiLooper);
 
-        mWifiChannelUtilizationScan = new WifiChannelUtilization(mClock);
-
         mContext = context;
+        mWifiChannelUtilizationScan = new WifiChannelUtilization(mClock, mContext);
         mWifiInfo = new ExtendedWifiInfo(context);
         mSettingsMigrationDataHolder = new SettingsMigrationDataHolder(mContext);
         mConnectionFailureNotificationBuilder = new ConnectionFailureNotificationBuilder(
@@ -353,7 +352,8 @@
                 (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE),
                 this, mWifiConfigManager,
                 mWifiPermissionsUtil, mWifiMetrics, mClock, wifiHandler, mSettingsConfigStore);
-        WifiChannelUtilization wifiChannelUtilizationConnected = new WifiChannelUtilization(mClock);
+        WifiChannelUtilization wifiChannelUtilizationConnected =
+                new WifiChannelUtilization(mClock, mContext);
         mWifiDataStall = new WifiDataStall(mFrameworkFacade, mWifiMetrics, mContext,
                 mDeviceConfigFacade, wifiChannelUtilizationConnected, mClock, wifiHandler,
                 mThroughputPredictor);
diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index 2356c3f..5f79847 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -415,6 +415,15 @@
     <!-- Integer indicating the RSSI and link layer stats polling interval in milliseconds when device is connected and screen is on -->
     <integer translatable="false" name="config_wifiPollRssiIntervalMilliseconds">3000</integer>
 
+    <!-- Override channel utilization estimation with fixed value -->
+    <bool translatable="false" name="config_wifiChannelUtilizationOverrideEnabled">true</bool>
+    <!-- Integer values represent the channel utilization in different RF bands when
+          config_wifiChannelUtilizationOverridingEnabled is true.
+         They should be set to [0, 255] corresponding to utilization ratio between 0 and 1 -->
+    <integer translatable="false" name="config_wifiChannelUtilizationOverride2g">80</integer>
+    <integer translatable="false" name="config_wifiChannelUtilizationOverride5g">15</integer>
+    <integer translatable="false" name="config_wifiChannelUtilizationOverride6g">10</integer>
+
     <!-- Enable WPA2 to WPA3 auto-upgrade -->
     <bool translatable="false" name="config_wifiSaeUpgradeEnabled">true</bool>
 
diff --git a/service/res/values/overlayable.xml b/service/res/values/overlayable.xml
index dfd7d67..786c551 100644
--- a/service/res/values/overlayable.xml
+++ b/service/res/values/overlayable.xml
@@ -130,6 +130,10 @@
           <item type="integer" name="config_wifiHighMovementNetworkSelectionOptimizationRssiDelta" />
           <item type="integer" name="config_wifiRttBackgroundExecGapMs" />
           <item type="integer" name="config_wifiPollRssiIntervalMilliseconds" />
+          <item type="bool" name="config_wifiChannelUtilizationOverrideEnabled" />
+          <item type="integer" name="config_wifiChannelUtilizationOverride2g" />
+          <item type="integer" name="config_wifiChannelUtilizationOverride5g" />
+          <item type="integer" name="config_wifiChannelUtilizationOverride6g" />
           <item type="bool" name="config_wifiSaeUpgradeEnabled" />
           <item type="bool" name="config_wifiSaeUpgradeOffloadEnabled" />
           <item type="integer" name="config_wifiMaxNativeFailureSelfRecoveryPerHour" />
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiChannelUtilizationTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiChannelUtilizationTest.java
index 31fc7b7..bb6ff74 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiChannelUtilizationTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiChannelUtilizationTest.java
@@ -30,10 +30,13 @@
 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 @@
 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 @@
         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/service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
index 61979f1..b1eb5e9 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
@@ -212,7 +212,7 @@
     }
 
     /**
-     * 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