diff options
8 files changed, 113 insertions, 22 deletions
diff --git a/flags/wifi_flags.aconfig b/flags/wifi_flags.aconfig index b198e9b06b..c7ee13a665 100644 --- a/flags/wifi_flags.aconfig +++ b/flags/wifi_flags.aconfig @@ -263,3 +263,13 @@ flag { bug: "349253691" is_fixed_read_only: true } + + +flag { + name: "multiple_mld_on_sap_supported" + is_exported: false + namespace: "wifi" + description: "Check driver capability when determining the number of supported MLD" + bug: "382023801" + is_fixed_read_only: true +} diff --git a/framework/java/android/net/wifi/WifiManager.java b/framework/java/android/net/wifi/WifiManager.java index 52836c2940..912fe66124 100644 --- a/framework/java/android/net/wifi/WifiManager.java +++ b/framework/java/android/net/wifi/WifiManager.java @@ -4062,6 +4062,12 @@ public class WifiManager { public static final int WIFI_FEATURE_SOFTAP_MLO = 63; /** + * Supports multiple Wi-Fi 7 multi-link devices (MLD) on SoftAp. + * @hide + */ + public static final int WIFI_FEATURE_MULTIPLE_MLD_ON_SAP = 64; + + /** * NOTE: When adding a new WIFI_FEATURE_ value, also be sure to update * {@link com.android.server.wifi.util.FeatureBitsetUtils} */ diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java index 74c216cf35..a3fe7aa516 100644 --- a/service/java/com/android/server/wifi/SoftApManager.java +++ b/service/java/com/android/server/wifi/SoftApManager.java @@ -226,6 +226,9 @@ public class SoftApManager implements ActiveModeManager { // Whether this SoftApManager (i.e. this AP interface) is using multiple link operation. private boolean mIsUsingMlo = false; + private int mMaximumNumberOfMLDSupported; + private int mCurrentExistingMLD; + /** * The specified configuration passed in during initialization or during a configuration update * that doesn't require a restart. @@ -533,6 +536,9 @@ public class SoftApManager implements ActiveModeManager { mRole = role; // chip support it && overlay configuration is set. mIsMLDApSupportMLO = mWifiNative.isMLDApSupportMLO(); + mMaximumNumberOfMLDSupported = ApConfigUtil.getMaximumSupportedMLD( + mContext, mWifiNative.isMultipleMLDSupportedOnSap()); + mCurrentExistingMLD = mActiveModeWarden.getCurrentMLDAp(); mIsUsingMlo = useMultilinkMloSoftAp(); enableVerboseLogging(verboseLoggingEnabled); mStateMachine.sendMessage(SoftApStateMachine.CMD_START, requestorWs); @@ -568,12 +574,10 @@ public class SoftApManager implements ActiveModeManager { && mCurrentSoftApConfiguration.isIeee80211beEnabled() && isBridgedMode() && mIsMLDApSupportMLO) { - int currentExistingMLD = - mActiveModeWarden.getCurrentMLDAp(); if (ApConfigUtil.is11beAllowedForThisConfiguration( null /* Wiphy capability can be ignored for MLO case*/, mContext, mCurrentSoftApConfiguration, true /* isBridgedMode */, - currentExistingMLD, + mMaximumNumberOfMLDSupported, mCurrentExistingMLD, true /* isMLDApSupportMLO */)) { return true; } @@ -1350,11 +1354,9 @@ public class SoftApManager implements ActiveModeManager { DeviceWiphyCapabilities capabilities = mWifiNative.getDeviceWiphyCapabilities( mApInterfaceName, isBridgeRequired()); - int currentExistingMLD = - mActiveModeWarden.getCurrentMLDAp(); if (!ApConfigUtil.is11beAllowedForThisConfiguration(capabilities, mContext, mCurrentSoftApConfiguration, isBridgedMode(), - currentExistingMLD, + mMaximumNumberOfMLDSupported, mCurrentExistingMLD, mIsMLDApSupportMLO)) { Log.d(getTag(), "11BE is not allowed," + " removing from configuration"); diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index 25e5a764c8..3bef19e367 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -1688,6 +1688,17 @@ public class WifiNative { } /** + * Return true when the device supports multiple Wi-Fi 7 multi-link devices (MLD) on SoftAp. + */ + public boolean isMultipleMLDSupportedOnSap() { + if (!Flags.multipleMldOnSapSupported()) { + return false; + } + BitSet cachedFeatureSet = getCompleteFeatureSetFromConfigStore(); + return cachedFeatureSet.get(WifiManager.WIFI_FEATURE_MULTIPLE_MLD_ON_SAP); + } + + /** * Setup an interface for Soft AP mode operations. * * This method configures an interface in AP mode in all the native daemons diff --git a/service/java/com/android/server/wifi/hal/WifiChipAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiChipAidlImpl.java index d63d1e1187..1fe36ded44 100644 --- a/service/java/com/android/server/wifi/hal/WifiChipAidlImpl.java +++ b/service/java/com/android/server/wifi/hal/WifiChipAidlImpl.java @@ -1638,6 +1638,9 @@ public class WifiChipAidlImpl implements IWifiChip { if (bitmapContains(halFeatureSet, FeatureSetMask.MLO_SAP)) { features.set(WifiManager.WIFI_FEATURE_SOFTAP_MLO); } + if (bitmapContains(halFeatureSet, FeatureSetMask.MULTIPLE_MLD_ON_SAP)) { + features.set(WifiManager.WIFI_FEATURE_MULTIPLE_MLD_ON_SAP); + } return features; } diff --git a/service/java/com/android/server/wifi/util/ApConfigUtil.java b/service/java/com/android/server/wifi/util/ApConfigUtil.java index b2bb51007e..c60a9f4f35 100644 --- a/service/java/com/android/server/wifi/util/ApConfigUtil.java +++ b/service/java/com/android/server/wifi/util/ApConfigUtil.java @@ -904,6 +904,7 @@ public class ApConfigUtil { * IEEE80211BE & single link MLO in bridged mode from the resource file. * @param config The current {@link SoftApConfiguration}. * @param isBridgedMode true if bridged mode is enabled, false otherwise. + * @param maximumSupportedMLD maximum number of supported MLD on SoftAp. * @param currentExistingMLD number of existing 11BE SoftApManager. * @param isMLDApSupportMLO true if the chip reports the support multiple links * on a single MLD AP. @@ -913,7 +914,7 @@ public class ApConfigUtil { public static boolean is11beAllowedForThisConfiguration(DeviceWiphyCapabilities capabilities, @NonNull WifiContext context, SoftApConfiguration config, - boolean isBridgedMode, int currentExistingMLD, + boolean isBridgedMode, int maximumSupportedMLD, int currentExistingMLD, boolean isMLDApSupportMLO) { if (!ApConfigUtil.isIeee80211beSupported(context)) { return false; @@ -926,7 +927,7 @@ public class ApConfigUtil { } } if (Flags.mloSap()) { - if (!hasAvailableMLD(context, isBridgedMode, + if (!hasAvailableMLD(context, isBridgedMode, maximumSupportedMLD, currentExistingMLD, isMLDApSupportMLO)) { Log.i(TAG, "No available MLD, hence downgrading from 11be. currentExistingMLD = " + currentExistingMLD + ", isMLDApSupportMLO = " + isMLDApSupportMLO); @@ -946,10 +947,10 @@ public class ApConfigUtil { } private static boolean hasAvailableMLD(@NonNull WifiContext context, - boolean isBridgedMode, int currentExistingMLD, + boolean isBridgedMode, int maximumSupportedMLD, int currentExistingMLD, boolean isMLDApSupportMLO) { int numberOfMLDStillAllowed = - maximumNumberOfMLDForMLOAp(context) - currentExistingMLD; + maximumSupportedMLD - currentExistingMLD; if (numberOfMLDStillAllowed < 1) { return false; } @@ -960,10 +961,21 @@ public class ApConfigUtil { return true; } - private static int maximumNumberOfMLDForMLOAp(@NonNull WifiContext context) { + /** + * Returns maximum number of supported MLD on SoftAp. + * + * @param context The caller context used to get the OEM configuration from resource file. + * @param chipSupportsMultipleMld whether Chip supports multiple mld on SoftAp. + */ + public static int getMaximumSupportedMLD(@NonNull WifiContext context, + boolean chipSupportsMultipleMld) { int numberOfMLDSupported = context.getResourceCache() .getInteger(R.integer.config_wifiSoftApMaxNumberMLDSupported); - if (numberOfMLDSupported != 0) { + if (numberOfMLDSupported > 0) { + if (Flags.multipleMldOnSapSupported() && !chipSupportsMultipleMld) { + // Chip doesn't support multiple mld on SoftAp + return 1; + } return numberOfMLDSupported; } if (context.getResourceCache().getBoolean( diff --git a/service/java/com/android/server/wifi/util/FeatureBitsetUtils.java b/service/java/com/android/server/wifi/util/FeatureBitsetUtils.java index 6c6f2bb4e1..73ad5c867a 100644 --- a/service/java/com/android/server/wifi/util/FeatureBitsetUtils.java +++ b/service/java/com/android/server/wifi/util/FeatureBitsetUtils.java @@ -96,6 +96,8 @@ public class FeatureBitsetUtils { append(WifiManager.WIFI_FEATURE_D2D_WHEN_INFRA_STA_DISABLED, "WIFI_FEATURE_D2D_WHEN_INFRA_STA_DISABLED"); append(WifiManager.WIFI_FEATURE_SOFTAP_MLO, "WIFI_FEATURE_SOFTAP_MLO"); + append(WifiManager.WIFI_FEATURE_MULTIPLE_MLD_ON_SAP, + "WIFI_FEATURE_MULTIPLE_MLD_ON_SAP"); } }; diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java index aabfb3883c..39eca8f05c 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java @@ -1483,7 +1483,8 @@ public class ApConfigUtilTest extends WifiBaseTest { .thenReturn(false); /* 11be is disallowed when IEEE80211_BE feature is not supported */ assertFalse(ApConfigUtil.is11beAllowedForThisConfiguration(mDeviceWiphyCapabilities, - mContext, config, true, 0, false)); + mContext, config, true, 2 /* maximumSupportedMLD */, 0 /* currentExistingMLD */, + false)); when(mResources.getBoolean(R.bool.config_wifiSoftapIeee80211beSupported)) .thenReturn(true); @@ -1493,35 +1494,42 @@ public class ApConfigUtilTest extends WifiBaseTest { .thenReturn(true); /* 11be is allowed if chip supports single link MLO in bridged mode */ assertTrue(ApConfigUtil.is11beAllowedForThisConfiguration(mDeviceWiphyCapabilities, - mContext, config, true, 0, false)); + mContext, config, true, 2 /* maximumSupportedMLD */, 0 /* currentExistingMLD */, + false)); /* 11be is not allowed if chip doesn't support single link MLO in bridged mode */ when(mResources.getBoolean(R.bool.config_wifiSoftApSingleLinkMloInBridgedModeSupported)) .thenReturn(false); assertFalse(ApConfigUtil.is11beAllowedForThisConfiguration(mDeviceWiphyCapabilities, - mContext, config, true, 0, false)); + mContext, config, true, 1 /* maximumSupportedMLD */, 0 /* currentExistingMLD */, + false)); when(Flags.mloSap()).thenReturn(true); // two MLDs supported, allow 11be on bridged mode. when(mResources.getInteger(R.integer.config_wifiSoftApMaxNumberMLDSupported)) .thenReturn(2); assertTrue(ApConfigUtil.is11beAllowedForThisConfiguration(mDeviceWiphyCapabilities, - mContext, config, true, 0, false)); + mContext, config, true, 2 /* maximumSupportedMLD */, 0 /* currentExistingMLD */, + false)); - // One MLD only, disallow 11be on bridged AP. + // One MLD supported only, disallow 11be on bridged AP. when(mResources.getInteger(R.integer.config_wifiSoftApMaxNumberMLDSupported)) .thenReturn(1); assertFalse(ApConfigUtil.is11beAllowedForThisConfiguration(mDeviceWiphyCapabilities, - mContext, config, true, 0, false)); + mContext, config, true, 1 /* maximumSupportedMLD */, 0 /* currentExistingMLD */, + false)); - // One MLD only, disallow 11be when there is existing 11be AP. + // One MLD supported only, disallow 11be when there is existing 11be AP. assertFalse(ApConfigUtil.is11beAllowedForThisConfiguration(mDeviceWiphyCapabilities, - mContext, config, false, 1, false)); + mContext, config, false, 1 /* maximumSupportedMLD */, 1 /* currentExistingMLD */, + false)); - // One MLD only but chip support MultilinksOnMLD, allow 11be on bridged AP. + // One MLD supported only but chip support MultilinksOnMLD, allow 11be on bridged AP. assertTrue(ApConfigUtil.is11beAllowedForThisConfiguration(mDeviceWiphyCapabilities, - mContext, config, true, 0, true)); + mContext, config, true, 1 /* maximumSupportedMLD */, 0 /* currentExistingMLD */, + true)); } + @Test public void testIs11beDisabledForSecurityType() throws Exception { assertTrue(ApConfigUtil.is11beDisabledForSecurityType(SECURITY_TYPE_OPEN)); @@ -1531,4 +1539,41 @@ public class ApConfigUtilTest extends WifiBaseTest { assertFalse(ApConfigUtil.is11beDisabledForSecurityType(SECURITY_TYPE_WPA3_OWE)); assertTrue(ApConfigUtil.is11beDisabledForSecurityType(SECURITY_TYPE_WPA3_OWE_TRANSITION)); } + + @Test + public void testGetMaximumSupportedMLD() throws Exception { + // Old overlay, no MLD number is configured + when(mResources.getInteger(R.integer.config_wifiSoftApMaxNumberMLDSupported)) + .thenReturn(0); + // 1 MLD supported only no matter whether multiple MLD supported. + when(mResources.getBoolean(R.bool.config_wifiSoftApSingleLinkMloInBridgedModeSupported)) + .thenReturn(false); + assertEquals(1, ApConfigUtil.getMaximumSupportedMLD(mContext, + false /* isMultipleMLMDSupportedOnSap */)); + assertEquals(1, ApConfigUtil.getMaximumSupportedMLD(mContext, + true /* isMultipleMLMDSupportedOnSap */)); + + // 2 MLDs supported when overlay is true and no matter whether multiple MLD supported. + when(mResources.getBoolean(R.bool.config_wifiSoftApSingleLinkMloInBridgedModeSupported)) + .thenReturn(true); + assertEquals(2, ApConfigUtil.getMaximumSupportedMLD(mContext, + false /* isMultipleMLMDSupportedOnSap */)); + assertEquals(2, ApConfigUtil.getMaximumSupportedMLD(mContext, + true /* isMultipleMLMDSupportedOnSap */)); + + // New overlay, MLD number is configured. It will check multiple MLD supported value. + when(Flags.multipleMldOnSapSupported()).thenReturn(true); + when(mResources.getInteger(R.integer.config_wifiSoftApMaxNumberMLDSupported)) + .thenReturn(2); + assertEquals(1, ApConfigUtil.getMaximumSupportedMLD(mContext, + false /* isMultipleMLMDSupportedOnSap */)); + assertEquals(2, ApConfigUtil.getMaximumSupportedMLD(mContext, + true /* isMultipleMLMDSupportedOnSap */)); + + // Make sure it uses overlay value even though chip supports multiple MLD. + when(mResources.getInteger(R.integer.config_wifiSoftApMaxNumberMLDSupported)) + .thenReturn(1); + assertEquals(1, ApConfigUtil.getMaximumSupportedMLD(mContext, + true /* isMultipleMLMDSupportedOnSap */)); + } } |