Handle passing allowed channels for SoftAp

This commit handles passing of allowed channel frequencies for ACS in
SoftAp. This is part of support of the 6GHz band.

Bug: 146186687
Bug: 139354972
Test: Manual
Test: atest com.android.wifi.server
Change-Id: I302fc843e0a2b79c38dacd05a0dcc90c13df5f36
diff --git a/service/java/com/android/server/wifi/HostapdHal.java b/service/java/com/android/server/wifi/HostapdHal.java
index ce8b484..bac04c6 100644
--- a/service/java/com/android/server/wifi/HostapdHal.java
+++ b/service/java/com/android/server/wifi/HostapdHal.java
@@ -27,9 +27,11 @@
 import android.hidl.manager.V1_0.IServiceNotification;
 import android.net.MacAddress;
 import android.net.wifi.SoftApConfiguration;
+import android.net.wifi.SoftApConfiguration.BandType;
 import android.os.Handler;
 import android.os.HwRemoteBinder;
 import android.os.RemoteException;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -67,6 +69,9 @@
     private boolean mForceApChannel = false;
     private int mForcedApBand;
     private int mForcedApChannel;
+    private String mConfig2gChannelList;
+    private String mConfig5gChannelList;
+    private String mConfig6gChannelList;
 
     // Hostapd HAL interface objects
     private IServiceManager mIServiceManager = null;
@@ -339,6 +344,62 @@
         mForceApChannel = false;
     }
 
+    private boolean isSendFreqRangesNeeded(@BandType int band) {
+        // Fist we check if one of the selected bands has restrictions in the overlay file.
+        // Note,
+        //   - We store the config string here for future use, hence we need to check all bands.
+        //   - If there is no OEM restriction, we store the full band
+        boolean retVal = false;
+        if ((band & SoftApConfiguration.BAND_2GHZ) != 0) {
+            mConfig2gChannelList =
+                mContext.getResources().getString(R.string.config_wifiSoftap2gChannelList);
+            if (TextUtils.isEmpty(mConfig2gChannelList)) {
+                mConfig2gChannelList = "1-14";
+            } else {
+                retVal = true;
+            }
+        }
+
+        if ((band & SoftApConfiguration.BAND_5GHZ) != 0) {
+            mConfig5gChannelList =
+                mContext.getResources().getString(R.string.config_wifiSoftap5gChannelList);
+            if (TextUtils.isEmpty(mConfig5gChannelList)) {
+                mConfig5gChannelList = "34-173";
+            } else {
+                retVal = true;
+            }
+        }
+
+        if ((band & SoftApConfiguration.BAND_6GHZ) != 0) {
+            mConfig6gChannelList =
+                mContext.getResources().getString(R.string.config_wifiSoftap6gChannelList);
+            if (TextUtils.isEmpty(mConfig6gChannelList)) {
+                mConfig6gChannelList = "1-254";
+            } else {
+                retVal = true;
+            }
+        }
+
+        // If any of the selected band has restriction in the overlay file, we return true.
+        if (retVal) {
+            return true;
+        }
+
+        // Next, if only one of 5G or 6G is selected, then we need freqList to separate them
+        // Since there is no other way.
+        if (((band & SoftApConfiguration.BAND_5GHZ) != 0)
+                && ((band & SoftApConfiguration.BAND_6GHZ) == 0)) {
+            return true;
+        }
+        if (((band & SoftApConfiguration.BAND_5GHZ) == 0)
+                && ((band & SoftApConfiguration.BAND_6GHZ) != 0)) {
+            return true;
+        }
+
+        // In all other cases, we don't need to set the freqList
+        return false;
+    }
+
     /**
      * Add and start a new access point.
      *
@@ -396,18 +457,26 @@
                     android.hardware.wifi.hostapd.V1_1.IHostapd.IfaceParams ifaceParams1_1 =
                             new android.hardware.wifi.hostapd.V1_1.IHostapd.IfaceParams();
                     ifaceParams1_1.V1_0 = ifaceParams;
-                    if (ifaceParams.channelParams.enableAcs) {
-                        ifaceParams1_1.channelParams.acsChannelRanges.addAll(
-                                toAcsChannelRanges(mContext.getResources().getString(
-                                        R.string.config_wifi_softap_acs_supported_channel_list)));
-                    }
-
                     if (!isV1_2()) {
+                        ifaceParams.channelParams.band = getHalBand(band);
+
+                        if (ifaceParams.channelParams.enableAcs) {
+                            if ((band & SoftApConfiguration.BAND_2GHZ) != 0) {
+                                ifaceParams1_1.channelParams.acsChannelRanges.addAll(
+                                        toAcsChannelRanges(mContext.getResources().getString(
+                                            R.string.config_wifiSoftap2gChannelList)));
+                            }
+                            if ((band & SoftApConfiguration.BAND_5GHZ) != 0) {
+                                ifaceParams1_1.channelParams.acsChannelRanges.addAll(
+                                        toAcsChannelRanges(mContext.getResources().getString(
+                                            R.string.config_wifiSoftap5gChannelList)));
+                            }
+                        }
+
                         android.hardware.wifi.hostapd.V1_1.IHostapd iHostapdV1_1 =
                                 getHostapdMockableV1_1();
                         if (iHostapdV1_1 == null) return false;
 
-                        ifaceParams.channelParams.band = getHalBand(band);
                         status = iHostapdV1_1.addAccessPoint_1_1(ifaceParams1_1, nwParams);
                         if (!checkStatusAndLogFailure(status, methodStr)) {
                             return false;
@@ -441,6 +510,23 @@
                                     R.bool.config_wifiSoftapHeTwtSupported);
                         ifaceParams1_2.channelParams.bandMask = getHalBandMask(band);
 
+                        // Prepare freq ranges/lists if needed
+                        if (ifaceParams.channelParams.enableAcs
+                                && isSendFreqRangesNeeded(band)) {
+                            if ((band & SoftApConfiguration.BAND_2GHZ) != 0) {
+                                ifaceParams1_2.channelParams.acsChannelFreqRangesMhz.addAll(
+                                        toAcsFreqRanges(SoftApConfiguration.BAND_2GHZ));
+                            }
+                            if ((band & SoftApConfiguration.BAND_5GHZ) != 0) {
+                                ifaceParams1_2.channelParams.acsChannelFreqRangesMhz.addAll(
+                                        toAcsFreqRanges(SoftApConfiguration.BAND_5GHZ));
+                            }
+                            if ((band & SoftApConfiguration.BAND_6GHZ) != 0) {
+                                ifaceParams1_2.channelParams.acsChannelFreqRangesMhz.addAll(
+                                        toAcsFreqRanges(SoftApConfiguration.BAND_6GHZ));
+                            }
+                        }
+
                         android.hardware.wifi.hostapd.V1_2.IHostapd iHostapdV1_2 =
                                 getHostapdMockableV1_2();
                         if (iHostapdV1_2 == null) return false;
@@ -758,8 +844,8 @@
             toAcsChannelRanges(String channelListStr) {
         ArrayList<android.hardware.wifi.hostapd.V1_1.IHostapd.AcsChannelRange> acsChannelRanges =
                 new ArrayList<>();
-        String[] channelRanges = channelListStr.split(",");
-        for (String channelRange : channelRanges) {
+
+        for (String channelRange : channelListStr.split(",")) {
             android.hardware.wifi.hostapd.V1_1.IHostapd.AcsChannelRange acsChannelRange =
                     new android.hardware.wifi.hostapd.V1_1.IHostapd.AcsChannelRange();
             try {
@@ -769,8 +855,8 @@
                         Log.e(TAG, "Unrecognized channel range, length is " + channels.length);
                         continue;
                     }
-                    int start = Integer.parseInt(channels[0]);
-                    int end = Integer.parseInt(channels[1]);
+                    int start = Integer.parseInt(channels[0].trim());
+                    int end = Integer.parseInt(channels[1].trim());
                     if (start > end) {
                         Log.e(TAG, "Invalid channel range, from " + start + " to " + end);
                         continue;
@@ -778,7 +864,7 @@
                     acsChannelRange.start = start;
                     acsChannelRange.end = end;
                 } else {
-                    acsChannelRange.start = Integer.parseInt(channelRange);
+                    acsChannelRange.start = Integer.parseInt(channelRange.trim());
                     acsChannelRange.end = acsChannelRange.start;
                 }
             } catch (NumberFormatException e) {
@@ -792,6 +878,67 @@
     }
 
     /**
+     * Convert channel list string like '1-6,11' to list of AcsFreqRange
+     */
+    private List<android.hardware.wifi.hostapd.V1_2.IHostapd.AcsFrequencyRange>
+            toAcsFreqRanges(@BandType int band) {
+        List<android.hardware.wifi.hostapd.V1_2.IHostapd.AcsFrequencyRange>
+                acsFrequencyRanges = new ArrayList<>();
+
+        if (!ApConfigUtil.isBandValid(band) || ApConfigUtil.isMultiband(band)) {
+            Log.e(TAG, "Invalid band : " + band);
+            return acsFrequencyRanges;
+        }
+
+        String channelListStr;
+        switch (band) {
+            case SoftApConfiguration.BAND_2GHZ:
+                channelListStr = mConfig2gChannelList;
+                break;
+            case SoftApConfiguration.BAND_5GHZ:
+                channelListStr = mConfig5gChannelList;
+                break;
+            case SoftApConfiguration.BAND_6GHZ:
+                channelListStr = mConfig6gChannelList;
+                break;
+            default:
+                return acsFrequencyRanges;
+        }
+
+        for (String channelRange : channelListStr.split(",")) {
+            android.hardware.wifi.hostapd.V1_2.IHostapd.AcsFrequencyRange acsFrequencyRange =
+                    new android.hardware.wifi.hostapd.V1_2.IHostapd.AcsFrequencyRange();
+            try {
+                if (channelRange.contains("-")) {
+                    String[] channels  = channelRange.split("-");
+                    if (channels.length != 2) {
+                        Log.e(TAG, "Unrecognized channel range, length is " + channels.length);
+                        continue;
+                    }
+                    int start = Integer.parseInt(channels[0].trim());
+                    int end = Integer.parseInt(channels[1].trim());
+                    if (start > end) {
+                        Log.e(TAG, "Invalid channel range, from " + start + " to " + end);
+                        continue;
+                    }
+                    acsFrequencyRange.start = ApConfigUtil.convertChannelToFrequency(start, band);
+                    acsFrequencyRange.end = ApConfigUtil.convertChannelToFrequency(end, band);
+                } else {
+                    int channel = Integer.parseInt(channelRange.trim());
+                    acsFrequencyRange.start = ApConfigUtil.convertChannelToFrequency(channel, band);
+                    acsFrequencyRange.end = acsFrequencyRange.start;
+                }
+            } catch (NumberFormatException e) {
+                // Ignore malformed value
+                Log.e(TAG, "Malformed channel value detected: " + e);
+                continue;
+            }
+            acsFrequencyRanges.add(acsFrequencyRange);
+        }
+        return acsFrequencyRanges;
+    }
+
+    /**
      * Returns false if Hostapd is null, and logs failure to call methodStr
      */
     private boolean checkHostapdAndLogFailure(String methodStr) {
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index 9657883..58c7f7e 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -373,9 +373,8 @@
                 SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD);
 
         result = ApConfigUtil.updateApChannelConfig(
-                mWifiNative, mCountryCode,
-                mWifiApConfigStore.getAllowed2GChannel(), localConfigBuilder, config, acsEnabled);
-
+                mWifiNative, mContext.getResources(), mCountryCode, localConfigBuilder, config,
+                acsEnabled);
         if (result != SUCCESS) {
             Log.e(TAG, "Failed to update AP band and channel");
             return result;
diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java
index 756a753..0fee6f0 100644
--- a/service/java/com/android/server/wifi/WifiApConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiApConfigStore.java
@@ -40,7 +40,6 @@
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.security.SecureRandom;
-import java.util.ArrayList;
 import java.util.Random;
 
 import javax.annotation.Nullable;
@@ -200,21 +199,6 @@
         persistConfigAndTriggerBackupManagerProxy(config);
     }
 
-    public ArrayList<Integer> getAllowed2GChannel() {
-        String ap2GChannelListStr = mContext.getResources().getString(
-                R.string.config_wifi_framework_sap_2G_channel_list);
-        Log.d(TAG, "2G band allowed channels are:" + ap2GChannelListStr);
-
-        ArrayList<Integer> allowed2GChannels = new ArrayList<>();
-        if (ap2GChannelListStr != null) {
-            String[] channelList = ap2GChannelListStr.split(",");
-            for (String tmp : channelList) {
-                allowed2GChannels.add(Integer.parseInt(tmp));
-            }
-        }
-        return allowed2GChannels;
-    }
-
     private SoftApConfiguration sanitizePersistentApConfig(SoftApConfiguration config) {
         SoftApConfiguration.Builder convertedConfigBuilder = null;
 
diff --git a/service/java/com/android/server/wifi/util/ApConfigUtil.java b/service/java/com/android/server/wifi/util/ApConfigUtil.java
index 5d0e971..df38457 100644
--- a/service/java/com/android/server/wifi/util/ApConfigUtil.java
+++ b/service/java/com/android/server/wifi/util/ApConfigUtil.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.content.res.Resources;
 import android.net.MacAddress;
 import android.net.wifi.SoftApCapability;
 import android.net.wifi.SoftApConfiguration;
@@ -30,6 +31,7 @@
 import com.android.wifi.resources.R;
 
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Random;
 
 /**
@@ -63,7 +65,7 @@
      * @param band of channel to convert
      * @return center frequency in Mhz of the channel, -1 if no match
      */
-    public static int convertChannelToFrequency(int channel, int band) {
+    public static int convertChannelToFrequency(int channel, @BandType int band) {
         if (band == SoftApConfiguration.BAND_2GHZ) {
             if (channel == 14) {
                 return 2484;
@@ -177,35 +179,153 @@
     }
 
     /**
+     * Convert string to channel list
+     * Format of the list is a comma separated channel numbers, or range of channel numbers
+     * Example, "34-48, 149".
+     * @param channelString for a comma separated channel numbers, or range of channel numbers
+     *        such as "34-48, 149"
+     * @return list of channel numbers
+     */
+    public static List<Integer> convertStringToChannelList(String channelString) {
+        if (channelString == null) {
+            return null;
+        }
+
+        List<Integer> channelList = new ArrayList<Integer>();
+
+        for (String channelRange : channelString.split(",")) {
+            try {
+                if (channelRange.contains("-")) {
+                    String[] channels = channelRange.split("-");
+                    if (channels.length != 2) {
+                        Log.e(TAG, "Unrecognized channel range, Length is " + channels.length);
+                        continue;
+                    }
+                    int start = Integer.parseInt(channels[0].trim());
+                    int end = Integer.parseInt(channels[1].trim());
+                    if (start > end) {
+                        Log.e(TAG, "Invalid channel range, from " + start + " to " + end);
+                        continue;
+                    }
+
+                    for (int channel = start; channel <= end; channel++) {
+                        channelList.add(channel);
+                    }
+                } else {
+                    channelList.add(Integer.parseInt(channelRange.trim()));
+                }
+            } catch (NumberFormatException e) {
+                // Ignore malformed string
+                Log.e(TAG, "Malformed channel value detected: " + e);
+                continue;
+            }
+        }
+        return channelList;
+    }
+
+    /**
+     * Get channel frequencies for band that are allowed by both regulatory and OEM configuration
+     *
+     * @param band to get channels for
+     * @param wifiNative reference used to get regulatory restrictionsimport java.util.Arrays;
+     * @param resources used to get OEM restrictions
+     * @return A list of frequencies that are allowed, null on error.
+     */
+    public static List<Integer> getAvailableChannelFreqsForBand(
+            @BandType int band, WifiNative wifiNative, Resources resources) {
+        if (!isBandValid(band) || isMultiband(band)) {
+            return null;
+        }
+
+        List<Integer> configuredList;
+        int scannerBand;
+        switch (band) {
+            case SoftApConfiguration.BAND_2GHZ:
+                configuredList = convertStringToChannelList(resources.getString(
+                        R.string.config_wifiSoftap2gChannelList));
+                scannerBand = WifiScanner.WIFI_BAND_24_GHZ;
+                break;
+            case SoftApConfiguration.BAND_5GHZ:
+                configuredList = convertStringToChannelList(resources.getString(
+                        R.string.config_wifiSoftap5gChannelList));
+                scannerBand = WifiScanner.WIFI_BAND_5_GHZ;
+                break;
+            case SoftApConfiguration.BAND_6GHZ:
+                configuredList = convertStringToChannelList(resources.getString(
+                        R.string.config_wifiSoftap6gChannelList));
+                scannerBand = WifiScanner.WIFI_BAND_6_GHZ;
+                break;
+            default:
+                return null;
+        }
+
+        // Get the allowed list of channel frequencies in MHz
+        int[] regulatoryArray = wifiNative.getChannelsForBand(scannerBand);
+        List<Integer> regulatoryList = new ArrayList<Integer>();
+        for (int freq : regulatoryArray) {
+            regulatoryList.add(freq);
+        }
+
+        if (configuredList == null || configuredList.isEmpty()) {
+            return regulatoryList;
+        }
+
+        List<Integer> filteredList = new ArrayList<Integer>();
+        // Otherwise, filter the configured list
+        for (int channel : configuredList) {
+            int channelFreq = convertChannelToFrequency(channel, band);
+
+            if (regulatoryList.contains(channelFreq)) {
+                filteredList.add(channelFreq);
+            }
+        }
+        return filteredList;
+    }
+
+    /**
      * Return a channel number for AP setup based on the frequency band.
      * @param apBand one or combination of the values of SoftApConfiguration.BAND_*.
-     * @param allowed2GChannels list of allowed 2GHz channels
-     * @param allowed5GFreqList list of allowed 5GHz frequencies
-     * @param allowed6GFreqList list of allowed 6GHz frequencies
+     * @param wifiNative reference used to collect regulatory restrictions.
+     * @param resources the resources to use to get configured allowed channels.
      * @return a valid channel frequency on success, -1 on failure.
      */
-    public static int chooseApChannel(int apBand,
-                                      ArrayList<Integer> allowed2GChannels,
-                                      int[] allowed5GFreqList,
-                                      int[] allowed6GFreqList) {
+    public static int chooseApChannel(int apBand, WifiNative wifiNative, Resources resources) {
         if (!isBandValid(apBand)) {
             Log.e(TAG, "Invalid band: " + apBand);
             return -1;
         }
 
         int totalChannelCount = 0;
-        int size2gList = (allowed2GChannels != null) ? allowed2GChannels.size() : 0;
-        int size5gList = (allowed5GFreqList != null) ? allowed5GFreqList.length : 0;
-        int size6gList = (allowed6GFreqList != null) ? allowed6GFreqList.length : 0;
+        int size2gList = 0;
+        int size5gList = 0;
+        int size6gList = 0;
+        List<Integer> allowed2gFreqList = null;
+        List<Integer> allowed5gFreqList = null;
+        List<Integer> allowed6gFreqList = null;
 
         if ((apBand & SoftApConfiguration.BAND_2GHZ) != 0) {
-            totalChannelCount += size2gList;
+            allowed2gFreqList = getAvailableChannelFreqsForBand(SoftApConfiguration.BAND_2GHZ,
+                    wifiNative, resources);
+            if (allowed2gFreqList != null) {
+                size2gList = allowed2gFreqList.size();
+                totalChannelCount += size2gList;
+            }
         }
         if ((apBand & SoftApConfiguration.BAND_5GHZ) != 0) {
-            totalChannelCount += size5gList;
+            allowed5gFreqList = getAvailableChannelFreqsForBand(SoftApConfiguration.BAND_5GHZ,
+                    wifiNative, resources);
+            if (allowed5gFreqList != null) {
+                size5gList = allowed5gFreqList.size();
+                totalChannelCount += size5gList;
+            }
         }
         if ((apBand & SoftApConfiguration.BAND_6GHZ) != 0) {
-            totalChannelCount += size6gList;
+            allowed6gFreqList = getAvailableChannelFreqsForBand(SoftApConfiguration.BAND_6GHZ,
+                    wifiNative, resources);
+            if (allowed6gFreqList != null) {
+                size6gList = allowed6gFreqList.size();
+                totalChannelCount += size6gList;
+            }
         }
 
         if (totalChannelCount == 0) {
@@ -224,39 +344,37 @@
         // Pick a channel
         int selectedChannelIndex = sRandom.nextInt(totalChannelCount);
 
-        if ((apBand & SoftApConfiguration.BAND_2GHZ) != 0) {
+        if (size2gList != 0) {
             if (selectedChannelIndex < size2gList) {
-                return convertChannelToFrequency(
-                    allowed2GChannels.get(selectedChannelIndex).intValue(),
-                    SoftApConfiguration.BAND_2GHZ);
+                return allowed2gFreqList.get(selectedChannelIndex).intValue();
             } else {
                 selectedChannelIndex -= size2gList;
             }
         }
 
-        if ((apBand & SoftApConfiguration.BAND_5GHZ) != 0) {
+        if (size5gList != 0) {
             if (selectedChannelIndex < size5gList) {
-                return allowed5GFreqList[selectedChannelIndex];
+                return allowed5gFreqList.get(selectedChannelIndex).intValue();
             } else {
                 selectedChannelIndex -= size5gList;
             }
         }
 
-        return allowed6GFreqList[selectedChannelIndex];
+        return allowed6gFreqList.get(selectedChannelIndex).intValue();
     }
 
     /**
      * Update AP band and channel based on the provided country code and band.
      * This will also set
      * @param wifiNative reference to WifiNative
+     * @param resources the resources to use to get configured allowed channels.
      * @param countryCode country code
-     * @param allowed2GChannels list of allowed 2GHz channels
      * @param config configuration to update
      * @return an integer result code
      */
     public static int updateApChannelConfig(WifiNative wifiNative,
+                                            Resources resources,
                                             String countryCode,
-                                            ArrayList<Integer> allowed2GChannels,
                                             SoftApConfiguration.Builder configBuilder,
                                             SoftApConfiguration config,
                                             boolean acsEnabled) {
@@ -275,9 +393,7 @@
 
         /* Select a channel if it is not specified and ACS is not enabled */
         if ((config.getChannel() == 0) && !acsEnabled) {
-            int freq = chooseApChannel(config.getBand(), allowed2GChannels,
-                    wifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ),
-                    wifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ));
+            int freq = chooseApChannel(config.getBand(), wifiNative, resources);
             if (freq == -1) {
                 /* We're not able to get channel from wificond. */
                 Log.e(TAG, "Failed to get available channel.");
diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index e731269..dcde730 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -131,7 +131,21 @@
     <integer translatable="false" name="config_wifi_hardware_soft_ap_max_client_count">16</integer>
 
     <string  translatable="false" name="config_wifi_random_mac_oui">DA-A1-19</string>
-    <string  translatable="false" name="config_wifi_framework_sap_2G_channel_list">1,6,11</string>
+
+    <!-- List of allowed channels in 2GHz band for softap. If the device doesn't want to restrict
+         channels this should be empty. Values is a comma separated channel string and/or channel
+         range string like '1-6,11'. -->
+    <string  translatable="false" name="config_wifiSoftap2gChannelList">1,6,11</string>
+
+    <!-- List of allowed channels in 5GHz band for softap. If the device doesn't want to restrict
+         channels this should be empty. Values is a comma separated channel string and/or channel
+         range string like '36-48,149'. -->
+    <string  translatable="false" name="config_wifiSoftap5gChannelList"></string>
+
+    <!-- List of allowed channels in 6GHz band for softap. If the device doesn't want to restrict
+         channels this should be empty. Values is a comma separated channel string and/or channel
+         range string like '36-48,149'. -->
+    <string  translatable="false" name="config_wifiSoftap6gChannelList"></string>
 
     <!-- Integer indicating associated full scan max num active channels -->
     <integer translatable="false" name="config_wifi_framework_associated_partial_scan_max_num_active_channels">6</integer>
@@ -164,11 +178,6 @@
     <!-- Wifi driver supports WPA3 Simultaneous Authentication of Equals (WPA3-SAE) for softap -->
     <bool translatable="false" name="config_wifi_softap_sae_supported">false</bool>
 
-    <!-- Channel list restriction to Automatic channel selection (ACS) for softap. If the device
-         doesn't want to restrict channels this should be empty. Value is a comma separated channel
-         string and/or channel range string like '1-6,11' -->
-    <string translatable="false" name="config_wifi_softap_acs_supported_channel_list"></string>
-
     <!-- Wifi driver supports IEEE80211AC for softap -->
     <bool translatable="false" name="config_wifi_softap_ieee80211ac_supported">false</bool>
 
diff --git a/service/res/values/overlayable.xml b/service/res/values/overlayable.xml
index 5da010b..420c012 100644
--- a/service/res/values/overlayable.xml
+++ b/service/res/values/overlayable.xml
@@ -56,7 +56,9 @@
           <item type="integer" name="config_wifiFrameworkScoreGoodRssiThreshold6ghz" />
           <item type="integer" name="config_wifi_framework_soft_ap_timeout_delay" />
           <item type="string"  name="config_wifi_random_mac_oui" />
-          <item type="string"  name="config_wifi_framework_sap_2G_channel_list" />
+          <item type="string"  name="config_wifiSoftap2gChannelList" />
+          <item type="string"  name="config_wifiSoftap5gChannelList" />
+          <item type="string"  name="config_wifiSoftap6gChannelList" />
           <item type="integer" name="config_wifi_framework_associated_partial_scan_max_num_active_channels" />
           <item type="integer" name="config_wifi_framework_recovery_timeout_delay" />
           <item type="bool" name="config_wifi_framework_enable_associated_network_selection" />
@@ -67,7 +69,6 @@
           <item type="bool" name="config_wifi_sofap_client_force_disconnect_supported" />
           <item type="bool" name="config_wifi_softap_acs_supported" />
           <item type="bool" name="config_wifi_softap_sae_supported" />
-          <item type="string" name="config_wifi_softap_acs_supported_channel_list" />
           <item type="bool" name="config_wifi_softap_ieee80211ac_supported" />
           <item type="bool" name="config_wifiSoftapIeee80211axSupported" />
           <item type="bool" name="config_wifiSoftap6ghzSupported" />
diff --git a/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java b/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
index 349fb57..14f40fd 100644
--- a/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
@@ -130,7 +130,9 @@
         mResources.setBoolean(R.bool.config_wifi_softap_ieee80211ac_supported, false);
         mResources.setBoolean(R.bool.config_wifiSoftapIeee80211axSupported, false);
         mResources.setBoolean(R.bool.config_wifiSoftap6ghzSupported, false);
-        mResources.setString(R.string.config_wifi_softap_acs_supported_channel_list, "");
+        mResources.setString(R.string.config_wifiSoftap2gChannelList, "");
+        mResources.setString(R.string.config_wifiSoftap5gChannelList, "");
+        mResources.setString(R.string.config_wifiSoftap6gChannelList, "");
 
         mStatusSuccess = createHostapdStatus(HostapdStatusCode.SUCCESS);
         mStatusFailure = createHostapdStatus(HostapdStatusCode.FAILURE_UNKNOWN);
@@ -496,7 +498,9 @@
                 .thenReturn(IServiceManager.Transport.HWBINDER);
         mIHostapdMockV11 = mock(android.hardware.wifi.hostapd.V1_1.IHostapd.class);
         // Enable ACS and set available channels in the config.
-        final String acsChannelStr = "1,6,11-13,40";
+        final String acsChannelStr2g = "1,6,11-13";
+        final String acsChannelStr5g = "40";
+        final String acsChannelStr6g = "";
         android.hardware.wifi.hostapd.V1_1.IHostapd.AcsChannelRange channelRange1 =
                 new android.hardware.wifi.hostapd.V1_1.IHostapd.AcsChannelRange();
         android.hardware.wifi.hostapd.V1_1.IHostapd.AcsChannelRange channelRange2 =
@@ -517,7 +521,9 @@
         acsChannelRanges.add(channelRange3);
         acsChannelRanges.add(channelRange4);
         mResources.setBoolean(R.bool.config_wifi_softap_acs_supported, true);
-        mResources.setString(R.string.config_wifi_softap_acs_supported_channel_list, acsChannelStr);
+        mResources.setString(R.string.config_wifiSoftap2gChannelList, acsChannelStr2g);
+        mResources.setString(R.string.config_wifiSoftap5gChannelList, acsChannelStr5g);
+        mResources.setString(R.string.config_wifiSoftap6gChannelList, acsChannelStr6g);
         mHostapdHal = new HostapdHalSpy();
 
         when(mIHostapdMockV11.addAccessPoint_1_1(
diff --git a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
index 142838e..d382e62 100644
--- a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -109,7 +109,7 @@
     private static final int TEST_AP_BANDWIDTH_FROM_IFACE_CALLBACK =
             SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT;
     private static final int TEST_AP_BANDWIDTH_IN_SOFTAPINFO = SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT;
-
+    private static final int[] EMPTY_CHANNEL_ARRAY = {};
     private final SoftApConfiguration mDefaultApConfig = createDefaultApConfig();
 
     private ContentObserver mContentObserver;
@@ -567,7 +567,8 @@
                 WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
                 noAcsCapability);
 
-        when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ)).thenReturn(null);
+        when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ))
+                .thenReturn(EMPTY_CHANNEL_ARRAY);
         when(mWifiNative.setupInterfaceForSoftApMode(any())).thenReturn(TEST_INTERFACE_NAME);
         when(mWifiNative.isHalStarted()).thenReturn(true);
 
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
index 46b4bd4..fd524b6 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
@@ -110,7 +110,7 @@
 
         /* Setup expectations for Resources to return some default settings. */
         mResources = new MockResources();
-        mResources.setString(R.string.config_wifi_framework_sap_2G_channel_list,
+        mResources.setString(R.string.config_wifiSoftap2gChannelList,
                              TEST_DEFAULT_2G_CHANNEL_LIST);
         mResources.setString(R.string.wifi_tether_configure_ssid_default,
                              TEST_DEFAULT_AP_SSID);
@@ -848,21 +848,6 @@
     }
 
     /**
-     * Verify the default 2GHz channel list is properly returned.
-     */
-    @Test
-    public void testDefault2GHzChannelListReturned() {
-        // first build known good list
-        WifiApConfigStore store = createWifiApConfigStore();
-        ArrayList<Integer> channels = store.getAllowed2GChannel();
-
-        assertEquals(mKnownGood2GChannelList.size(), channels.size());
-        for (int channel : channels) {
-            assertTrue(mKnownGood2GChannelList.contains(channel));
-        }
-    }
-
-    /**
      * Verify the default configuration security when SAE support.
      */
     @Test
diff --git a/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java
index e4d02ee..69563d9 100644
--- a/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java
@@ -18,7 +18,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.when;
 
@@ -41,7 +40,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 
 /**
@@ -115,20 +113,15 @@
             6100, SoftApConfiguration.BAND_6GHZ, 32
     };
 
-
-
-    private static final Integer[] ALLOWED_2G_CHANNELS = {1, 2, 3, 4};
-    private static final int[] ALLOWED_5G_FREQS = {5180, 5190, 5200};
+    private static final int[] EMPTY_CHANNEL_LIST = {};
+    private static final int[] ALLOWED_2G_FREQS = {2462}; //ch# 11
+    private static final int[] ALLOWED_5G_FREQS = {5745, 5765}; //ch# 149, 153
     private static final int[] ALLOWED_6G_FREQS = {5945, 5965};
-    private static final int[] ALLOWED_5G_CHANNELS = {36, 38, 40};
 
     @Mock Context mContext;
     @Mock Resources mResources;
     @Mock WifiNative mWifiNative;
 
-    private final ArrayList<Integer> mAllowed2GChannels =
-            new ArrayList<Integer>(Arrays.asList(ALLOWED_2G_CHANNELS));
-
     /**
      * Setup test.
      */
@@ -268,13 +261,37 @@
     }
 
     /**
+     * Test convert string to channel list
+     */
+    @Test
+    public void testConvertStringToChannelList() throws Exception {
+        assertEquals(Arrays.asList(1, 6, 11), ApConfigUtil.convertStringToChannelList("1, 6, 11"));
+        assertEquals(Arrays.asList(1, 6, 11), ApConfigUtil.convertStringToChannelList("1,6,11"));
+        assertEquals(Arrays.asList(1, 9, 10, 11),
+                ApConfigUtil.convertStringToChannelList("1, 9-11"));
+        assertEquals(Arrays.asList(1, 6, 7, 10, 11),
+                ApConfigUtil.convertStringToChannelList("1,6-7, 10-11"));
+        assertEquals(Arrays.asList(1, 11),
+                ApConfigUtil.convertStringToChannelList("1,6a,11"));
+        assertEquals(Arrays.asList(1, 11), ApConfigUtil.convertStringToChannelList("1,6-3,11"));
+        assertEquals(Arrays.asList(1),
+                ApConfigUtil.convertStringToChannelList("1, abc , def - rsv"));
+    }
+
+    /**
+     * Test get available channel freq for band
+     */
+    /**
      * Verify default channel is used when picking a 2G channel without
      * any allowed 2G channels.
      */
     @Test
     public void chooseApChannel2GBandWithNoAllowedChannel() throws Exception {
-        int freq = ApConfigUtil.chooseApChannel(SoftApConfiguration.BAND_2GHZ,
-                null, ALLOWED_5G_FREQS, ALLOWED_6G_FREQS);
+        int[] allowed2gChannels = {};
+        when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ))
+                .thenReturn(allowed2gChannels);
+        int freq = ApConfigUtil.chooseApChannel(SoftApConfiguration.BAND_2GHZ, mWifiNative,
+                mResources);
         assertEquals(ApConfigUtil.DEFAULT_AP_CHANNEL, ApConfigUtil.convertFrequencyToChannel(freq));
     }
 
@@ -283,10 +300,14 @@
      */
     @Test
     public void chooseApChannel2GBandWithAllowedChannels() throws Exception {
-        int freq = ApConfigUtil.chooseApChannel(
-                SoftApConfiguration.BAND_2GHZ, mAllowed2GChannels, ALLOWED_5G_FREQS,
-                ALLOWED_6G_FREQS);
-        assertTrue(mAllowed2GChannels.contains(ApConfigUtil.convertFrequencyToChannel(freq)));
+        when(mResources.getString(R.string.config_wifiSoftap2gChannelList))
+                .thenReturn("1, 6, 11");
+        when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ))
+                .thenReturn(ALLOWED_2G_FREQS); // ch#11
+
+        int freq = ApConfigUtil.chooseApChannel(SoftApConfiguration.BAND_2GHZ, mWifiNative,
+                mResources);
+        assertEquals(2462, freq);
     }
 
     /**
@@ -294,11 +315,14 @@
      */
     @Test
     public void chooseApChannel5GBandWithAllowedChannels() throws Exception {
+        when(mResources.getString(R.string.config_wifiSoftap5gChannelList))
+                .thenReturn("149, 36-100");
+        when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ))
+                .thenReturn(ALLOWED_5G_FREQS); //ch# 149, 153
+
         int freq = ApConfigUtil.chooseApChannel(
-                SoftApConfiguration.BAND_5GHZ, mAllowed2GChannels, ALLOWED_5G_FREQS,
-                ALLOWED_6G_FREQS);
-        assertTrue(ArrayUtils.contains(ALLOWED_5G_CHANNELS,
-                ApConfigUtil.convertFrequencyToChannel(freq)));
+                SoftApConfiguration.BAND_5GHZ, mWifiNative, mResources);
+        assertTrue(ArrayUtils.contains(ALLOWED_5G_FREQS, freq));
     }
 
     /**
@@ -307,8 +331,10 @@
      */
     @Test
     public void chooseApChannel5GBandWithNoAllowedChannels() throws Exception {
-        assertEquals(-1, ApConfigUtil.chooseApChannel(
-                SoftApConfiguration.BAND_5GHZ, mAllowed2GChannels, null, null));
+        when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ))
+                .thenReturn(EMPTY_CHANNEL_LIST);
+        assertEquals(-1, ApConfigUtil.chooseApChannel(SoftApConfiguration.BAND_5GHZ, mWifiNative,
+                mResources));
     }
 
     /**
@@ -322,8 +348,8 @@
 
         when(mWifiNative.isHalStarted()).thenReturn(false);
         assertEquals(ApConfigUtil.SUCCESS,
-                ApConfigUtil.updateApChannelConfig(mWifiNative, TEST_COUNTRY_CODE,
-                mAllowed2GChannels, configBuilder, configBuilder.build(), false));
+                ApConfigUtil.updateApChannelConfig(mWifiNative, mResources, TEST_COUNTRY_CODE,
+                configBuilder, configBuilder.build(), false));
         /* Verify default band and channel is used. */
         assertEquals(ApConfigUtil.DEFAULT_AP_BAND, configBuilder.build().getBand());
         assertEquals(ApConfigUtil.DEFAULT_AP_CHANNEL, configBuilder.build().getChannel());
@@ -339,7 +365,7 @@
         configBuilder.setBand(SoftApConfiguration.BAND_5GHZ);
         when(mWifiNative.isHalStarted()).thenReturn(true);
         assertEquals(ApConfigUtil.ERROR_GENERIC,
-                ApConfigUtil.updateApChannelConfig(mWifiNative, null, mAllowed2GChannels,
+                ApConfigUtil.updateApChannelConfig(mWifiNative, mResources, null,
                 configBuilder, configBuilder.build(), false));
     }
 
@@ -352,8 +378,8 @@
         configBuilder.setChannel(36, SoftApConfiguration.BAND_5GHZ);
         when(mWifiNative.isHalStarted()).thenReturn(true);
         assertEquals(ApConfigUtil.SUCCESS,
-                ApConfigUtil.updateApChannelConfig(mWifiNative, TEST_COUNTRY_CODE,
-                mAllowed2GChannels, configBuilder, configBuilder.build(), false));
+                ApConfigUtil.updateApChannelConfig(mWifiNative, mResources, TEST_COUNTRY_CODE,
+                configBuilder, configBuilder.build(), false));
         assertEquals(SoftApConfiguration.BAND_5GHZ, configBuilder.build().getBand());
         assertEquals(36, configBuilder.build().getChannel());
     }
@@ -368,26 +394,35 @@
         configBuilder.setBand(SoftApConfiguration.BAND_5GHZ);
         when(mWifiNative.isHalStarted()).thenReturn(true);
         when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ))
-                .thenReturn(null);
+                .thenReturn(EMPTY_CHANNEL_LIST);
         assertEquals(ApConfigUtil.ERROR_NO_CHANNEL,
-                ApConfigUtil.updateApChannelConfig(mWifiNative, TEST_COUNTRY_CODE,
-                mAllowed2GChannels, configBuilder, configBuilder.build(), false));
+                ApConfigUtil.updateApChannelConfig(mWifiNative, mResources, TEST_COUNTRY_CODE,
+                configBuilder, configBuilder.build(), false));
     }
 
     /**
-     * Verify updateApChannelConfig will select a channel number and band when acs is
-     * disabled.
+     * Verify updateApChannelConfig will select a channel number that meets OEM restriction
+     * when acs is disabled.
      */
     @Test
-    public void updateApChannelConfigWithAcsDisabled() throws Exception {
+    public void updateApChannelConfigWithAcsDisabledOemConfigured() throws Exception {
         Builder configBuilder = new SoftApConfiguration.Builder();
         configBuilder.setBand(SoftApConfiguration.BAND_5GHZ | SoftApConfiguration.BAND_2GHZ);
+        when(mResources.getString(R.string.config_wifiSoftap2gChannelList))
+                .thenReturn("6");
+        when(mResources.getString(R.string.config_wifiSoftap5gChannelList))
+                .thenReturn("149, 36-100");
+        when(mWifiNative.isHalStarted()).thenReturn(true);
+        when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ))
+                .thenReturn(ALLOWED_2G_FREQS); // ch# 11
+        when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ))
+                .thenReturn(ALLOWED_5G_FREQS); // ch# 149, 153
         when(mWifiNative.isHalStarted()).thenReturn(true);
         assertEquals(ApConfigUtil.SUCCESS,
-                ApConfigUtil.updateApChannelConfig(mWifiNative, TEST_COUNTRY_CODE,
-                mAllowed2GChannels, configBuilder, configBuilder.build(), false));
-        assertFalse(ApConfigUtil.isMultiband(configBuilder.build().getBand()));
-        assertNotEquals(0, configBuilder.build().getChannel());
+                ApConfigUtil.updateApChannelConfig(mWifiNative, mResources, TEST_COUNTRY_CODE,
+                configBuilder, configBuilder.build(), false));
+        assertEquals(SoftApConfiguration.BAND_5GHZ, configBuilder.build().getBand());
+        assertEquals(149, configBuilder.build().getChannel());
     }
 
     /**
@@ -400,8 +435,8 @@
         configBuilder.setBand(SoftApConfiguration.BAND_5GHZ | SoftApConfiguration.BAND_2GHZ);
         when(mWifiNative.isHalStarted()).thenReturn(true);
         assertEquals(ApConfigUtil.SUCCESS,
-                ApConfigUtil.updateApChannelConfig(mWifiNative, TEST_COUNTRY_CODE,
-                mAllowed2GChannels, configBuilder, configBuilder.build(), true));
+                ApConfigUtil.updateApChannelConfig(mWifiNative, mResources, TEST_COUNTRY_CODE,
+                configBuilder, configBuilder.build(), true));
         assertEquals(SoftApConfiguration.BAND_5GHZ | SoftApConfiguration.BAND_2GHZ,
                 configBuilder.build().getBand());
         assertEquals(0, configBuilder.build().getChannel());