diff options
23 files changed, 1002 insertions, 444 deletions
diff --git a/framework/java/android/net/wifi/SoftApCapability.java b/framework/java/android/net/wifi/SoftApCapability.java index 4af9929291..b841ef2b48 100644 --- a/framework/java/android/net/wifi/SoftApCapability.java +++ b/framework/java/android/net/wifi/SoftApCapability.java @@ -366,12 +366,12 @@ public final class SoftApCapability implements Parcelable { public String toString() { StringBuilder sbuf = new StringBuilder(); sbuf.append("SupportedFeatures=").append(mSupportedFeatures); - sbuf.append("MaximumSupportedClientNumber=").append(mMaximumSupportedClientNumber); - sbuf.append("SupportedChannelListIn24g") + sbuf.append(" MaximumSupportedClientNumber=").append(mMaximumSupportedClientNumber); + sbuf.append(" SupportedChannelListIn24g") .append(Arrays.toString(mSupportedChannelListIn24g)); - sbuf.append("SupportedChannelListIn5g").append(Arrays.toString(mSupportedChannelListIn5g)); - sbuf.append("SupportedChannelListIn6g").append(Arrays.toString(mSupportedChannelListIn6g)); - sbuf.append("SupportedChannelListIn60g") + sbuf.append(" SupportedChannelListIn5g").append(Arrays.toString(mSupportedChannelListIn5g)); + sbuf.append(" SupportedChannelListIn6g").append(Arrays.toString(mSupportedChannelListIn6g)); + sbuf.append(" SupportedChannelListIn60g") .append(Arrays.toString(mSupportedChannelListIn60g)); return sbuf.toString(); } diff --git a/service/ServiceWifiResources/res/values/strings.xml b/service/ServiceWifiResources/res/values/strings.xml index 299b5c40a0..cdd47eed3c 100644 --- a/service/ServiceWifiResources/res/values/strings.xml +++ b/service/ServiceWifiResources/res/values/strings.xml @@ -123,6 +123,10 @@ <!-- A notification is shown when eap failure happens. It should be overridden by carrier-specific overlays. An empty string will result in no notification shown.--> <!-- Note: the :::integer::: is a carrier identifier - it is not to be translated! --> + <string name="wifi_eap_error_message_code_32756"><xliff:g id="ssid">%1$s</xliff:g> : EAP authentication error 32756</string> + <string-array name="wifi_eap_error_message_code_32756_carrier_overrides"> + <item><xliff:g id="carrier_id_prefix">:::1839:::</xliff:g></item> + </string-array> <string name="wifi_eap_error_message_code_32760"><xliff:g id="ssid">%1$s</xliff:g> : EAP authentication error 32760</string> <string-array name="wifi_eap_error_message_code_32760_carrier_overrides"> <item><xliff:g id="carrier_id_prefix">:::1839:::</xliff:g><xliff:g id="ssid">%1$s</xliff:g> : You can\u2019t connect to Verizon Wi-Fi Access from outside the Verizon coverage area. (Error = 32760)</item> @@ -155,14 +159,6 @@ <string-array name="wifi_eap_error_message_code_32767_carrier_overrides"> <item><xliff:g id="carrier_id_prefix">:::1839:::</xliff:g><xliff:g id="ssid">%1$s</xliff:g> : There is a problem connecting you to Verizon Wi-Fi Access. Try again later or try from a different location.</item> </string-array> - <string name="wifi_eap_error_message_code_32768"><xliff:g id="ssid">%1$s</xliff:g> : EAP authentication error 32768</string> - <string-array name="wifi_eap_error_message_code_32768_carrier_overrides"> - <item><xliff:g id="carrier_id_prefix">:::1839:::</xliff:g></item> - </string-array> - <string name="wifi_eap_error_message_code_32769"><xliff:g id="ssid">%1$s</xliff:g> : EAP authentication error 32769</string> - <string-array name="wifi_eap_error_message_code_32769_carrier_overrides"> - <item><xliff:g id="carrier_id_prefix">:::1839:::</xliff:g></item> - </string-array> <string name="wifi_eap_error_message_code_16384"><xliff:g id="ssid">%1$s</xliff:g> : EAP authentication error 16384</string> <string-array name="wifi_eap_error_message_code_16384_carrier_overrides"> <item><xliff:g id="carrier_id_prefix">:::1839:::</xliff:g><xliff:g id="ssid">%1$s</xliff:g> : There is a problem connecting you to Verizon Wi-Fi Access due to error 16384.</item> @@ -186,10 +182,14 @@ <string name="wifi_sim_required_message">To connect to <xliff:g id="ssid">%1$s</xliff:g>, insert a <xliff:g id="carrier_name">%2$s</xliff:g> SIM</string> <!-- External approver for interface priority calls. --> - <string name="wifi_interface_priority_title">App conflict</string> - <string name="wifi_interface_priority_message">Application <xliff:g id="app">%1$s</xliff:g> needs to bring up a <xliff:g id="interface">%2$s</xliff:g> interface. This will result in other interfaces being torn down which may impact <xliff:g id="apps">%3$s</xliff:g>.</string> - <string name="wifi_interface_priority_approve">Yes, approve</string> - <string name="wifi_interface_priority_reject">No, reject</string> + <string name="wifi_interface_priority_title"><xliff:g id="app">%1$s</xliff:g> wants to use a networking resource</string> + <!-- Note: additional available arguments for customized strings (not used in default string): + %1$s: application name + %2$s: interface name + --> + <string name="wifi_interface_priority_message">This may cause problems for <xliff:g id="apps">%3$s</xliff:g>.</string> + <string name="wifi_interface_priority_approve">Allow</string> + <string name="wifi_interface_priority_reject">Don\'t allow</string> <!-- Trust On First Use dialog and notification text. --> <string name="wifi_ca_cert_dialog_title">Is this network trusted?</string> diff --git a/service/java/com/android/server/wifi/FrameworkFacade.java b/service/java/com/android/server/wifi/FrameworkFacade.java index cad8f144f8..4bf64f0474 100644 --- a/service/java/com/android/server/wifi/FrameworkFacade.java +++ b/service/java/com/android/server/wifi/FrameworkFacade.java @@ -185,10 +185,11 @@ public class FrameworkFacade { } /** - * Wrapper for {@link PendingIntent#getActivity}. + * Wrapper for {@link PendingIntent#getActivity} using the current foreground user. */ public PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags) { - return PendingIntent.getActivity(context, requestCode, intent, flags); + return PendingIntent.getActivity(context.createContextAsUser(UserHandle.CURRENT, 0), + requestCode, intent, flags); } public boolean getConfigWiFiDisableInECBM(Context context) { diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java index e1563c87de..abeeffbf90 100644 --- a/service/java/com/android/server/wifi/HalDeviceManager.java +++ b/service/java/com/android/server/wifi/HalDeviceManager.java @@ -34,9 +34,13 @@ import android.hardware.wifi.V1_0.IfaceType; import android.hardware.wifi.V1_0.WifiDebugRingBufferStatus; import android.hardware.wifi.V1_0.WifiStatus; import android.hardware.wifi.V1_0.WifiStatusCode; +import android.hardware.wifi.V1_5.WifiBand; import android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination; import android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit; import android.hardware.wifi.V1_6.IfaceConcurrencyType; +import android.hardware.wifi.V1_6.WifiRadioCombination; +import android.hardware.wifi.V1_6.WifiRadioCombinationMatrix; +import android.hardware.wifi.V1_6.WifiRadioConfiguration; import android.hidl.manager.V1_0.IServiceNotification; import android.hidl.manager.V1_2.IServiceManager; import android.net.wifi.WifiContext; @@ -48,6 +52,7 @@ import android.util.ArraySet; import android.util.Log; import android.util.Pair; import android.util.SparseArray; +import android.util.SparseBooleanArray; import android.util.SparseIntArray; import com.android.internal.annotations.VisibleForTesting; @@ -81,6 +86,11 @@ public class HalDeviceManager { public static final long CHIP_CAPABILITY_ANY = 0L; private static final long CHIP_CAPABILITY_UNINITIALIZED = -1L; + private static final int DBS_24G_5G_MASK = + (1 << WifiBand.BAND_24GHZ) | (1 << WifiBand.BAND_5GHZ); + private static final int DBS_5G_6G_MASK = + (1 << WifiBand.BAND_5GHZ) | (1 << WifiBand.BAND_6GHZ); + private static final int START_HAL_RETRY_INTERVAL_MS = 20; // Number of attempts a start() is re-tried. A value of 0 means no retries after a single // attempt. @@ -390,6 +400,22 @@ public class HalDeviceManager { return success; } + private InterfaceCacheEntry getInterfaceCacheEntry(IWifiIface iface) { + String name = getName(iface); + int type = getType(iface); + if (VDBG) Log.d(TAG, "getInterfaceCacheEntry: iface(name)=" + name); + + synchronized (mLock) { + InterfaceCacheEntry cacheEntry = mInterfaceInfoCache.get(Pair.create(name, type)); + if (cacheEntry == null) { + Log.e(TAG, "getInterfaceCacheEntry: no entry for iface(name)=" + name); + return null; + } + + return cacheEntry; + } + } + /** * Returns the IWifiChip corresponding to the specified interface (or null on error). * @@ -398,22 +424,71 @@ public class HalDeviceManager { * other functions - e.g. calling the debug/trace methods. */ public IWifiChip getChip(IWifiIface iface) { - String name = getName(iface); - int type = getType(iface); - if (VDBG) Log.d(TAG, "getChip: iface(name)=" + name); + synchronized (mLock) { + InterfaceCacheEntry cacheEntry = getInterfaceCacheEntry(iface); + return (cacheEntry == null) ? null : cacheEntry.chip; + } + } + private WifiChipInfo getChipInfo(IWifiIface iface) { synchronized (mLock) { - InterfaceCacheEntry cacheEntry = mInterfaceInfoCache.get(Pair.create(name, type)); - if (cacheEntry == null) { - Log.e(TAG, "getChip: no entry for iface(name)=" + name); - return null; + InterfaceCacheEntry cacheEntry = getInterfaceCacheEntry(iface); + if (null == cacheEntry) return null; + + WifiChipInfo[] chipInfos = getAllChipInfoCached(); + if (null == chipInfos) return null; + + for (WifiChipInfo info: chipInfos) { + if (info.chipId == cacheEntry.chipId) { + return info; + } } + return null; + } + } - return cacheEntry.chip; + private boolean isDbsSupported(IWifiIface iface, int dbsMask) { + synchronized (mLock) { + WifiChipInfo info = getChipInfo(iface); + if (null == info) return false; + // If there is no radio combination information, cache it. + if (null == info.radioCombinationMatrix) { + IWifiChip chip = getChip(iface); + if (null == chip) return false; + + info.radioCombinationMatrix = getChipSupportedRadioCombinationsMatrix(chip); + info.radioCombinationLookupTable = convertRadioCombinationMatrixToLookupTable( + info.radioCombinationMatrix); + if (mDbg) { + Log.d(TAG, "radioCombinationMatrix=" + info.radioCombinationMatrix + + "radioCombinationLookupTable=" + info.radioCombinationLookupTable); + } + } + return info.radioCombinationLookupTable.get(dbsMask); } } /** + * Indicate whether or not 2.4GHz/5GHz DBS is supported. + * + * @param iface The interface on the chip. + * @return true if supported; false, otherwise; + */ + public boolean is24g5gDbsSupported(IWifiIface iface) { + return isDbsSupported(iface, DBS_24G_5G_MASK); + } + + /** + * Indicate whether or not 5GHz/6GHz DBS is supported. + * + * @param iface The interface on the chip. + * @return true if supported; false, otherwise; + */ + public boolean is5g6gDbsSupported(IWifiIface iface) { + return isDbsSupported(iface, DBS_5G_6G_MASK); + } + + /** * Replace the requestorWs info for the associated info. * * When a new iface is requested via @@ -856,6 +931,8 @@ public class HalDeviceManager { public int currentModeId; public WifiIfaceInfo[][] ifaces = new WifiIfaceInfo[IFACE_TYPES_BY_PRIORITY.length][]; public long chipCapabilities; + public WifiRadioCombinationMatrix radioCombinationMatrix = null; + public SparseBooleanArray radioCombinationLookupTable = new SparseBooleanArray(); @Override public String toString() { @@ -3031,6 +3108,25 @@ public class HalDeviceManager { return false; } + private static SparseBooleanArray convertRadioCombinationMatrixToLookupTable( + WifiRadioCombinationMatrix matrix) { + SparseBooleanArray lookupTable = new SparseBooleanArray(); + if (null == matrix) return lookupTable; + + for (WifiRadioCombination combination: matrix.radioCombinations) { + int bandMask = 0; + for (WifiRadioConfiguration config: combination.radioConfigurations) { + bandMask |= 1 << config.bandInfo; + } + if ((bandMask & DBS_24G_5G_MASK) == DBS_24G_5G_MASK) { + lookupTable.put(DBS_24G_5G_MASK, true); + } else if ((bandMask & DBS_5G_6G_MASK) == DBS_5G_6G_MASK) { + lookupTable.put(DBS_5G_6G_MASK, true); + } + } + return lookupTable; + } + /** * Get the chip capabilities * @@ -3065,6 +3161,46 @@ public class HalDeviceManager { } /** + * Get the supported radio combination matrix. + * + * This is called after creating an interface and need at least v1.6 HAL. + * + * @param wifiChip WifiChip + * @return Wifi radio combinmation matrix + */ + private WifiRadioCombinationMatrix getChipSupportedRadioCombinationsMatrix( + @NonNull IWifiChip wifiChip) { + synchronized (mLock) { + if (null == wifiChip) return null; + android.hardware.wifi.V1_6.IWifiChip chipV16 = + getWifiChipForV1_6Mockable(wifiChip); + if (null == chipV16) return null; + + Mutable<WifiRadioCombinationMatrix> radioCombinationMatrixResp = + new Mutable<>(); + radioCombinationMatrixResp.value = null; + try { + chipV16.getSupportedRadioCombinationsMatrix((WifiStatus status, + WifiRadioCombinationMatrix matrix) -> { + if (status.code == WifiStatusCode.SUCCESS) { + radioCombinationMatrixResp.value = matrix; + if (mDbg) { + Log.d(TAG, "radioCombinationMatrix=" + matrix); + } + } else { + Log.e(TAG, "getSupportedRadioCombinationsMatrix failed: " + + statusString(status)); + } + }); + } catch (RemoteException e) { + Log.e(TAG, "Exception on getSupportedRadioCombinationsMatrix: " + e); + radioCombinationMatrixResp.value = null; + } + return radioCombinationMatrixResp.value; + } + } + + /** * Dump the internal state of the class. */ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { diff --git a/service/java/com/android/server/wifi/InterfaceConflictManager.java b/service/java/com/android/server/wifi/InterfaceConflictManager.java index aa2e5fc419..4930719141 100644 --- a/service/java/com/android/server/wifi/InterfaceConflictManager.java +++ b/service/java/com/android/server/wifi/InterfaceConflictManager.java @@ -308,7 +308,7 @@ public class InterfaceConflictManager { String impactedPackages = TextUtils.join(",", impactedPackagesSet); mWifiDialogManager.createSimpleDialog( - mResources.getString(R.string.wifi_interface_priority_title), + mResources.getString(R.string.wifi_interface_priority_title, requestorAppName), mResources.getString(R.string.wifi_interface_priority_message, requestorAppName, requestedInterface, impactedPackages), mResources.getString(R.string.wifi_interface_priority_approve), diff --git a/service/java/com/android/server/wifi/NetworkSuggestionNominator.java b/service/java/com/android/server/wifi/NetworkSuggestionNominator.java index 5b00498982..fd882eda4b 100644 --- a/service/java/com/android/server/wifi/NetworkSuggestionNominator.java +++ b/service/java/com/android/server/wifi/NetworkSuggestionNominator.java @@ -122,6 +122,15 @@ public class NetworkSuggestionNominator implements WifiNetworkSelector.NetworkNo WifiConfiguration config = ewns.createInternalWifiConfiguration(mWifiCarrierInfoManager); WifiConfiguration wCmConfiguredNetwork = mWifiConfigManager.getConfiguredNetwork(config.getProfileKey()); + if (wCmConfiguredNetwork != null) { + mLocalLog.log(config.getProfileKey() + "is already in the WifiConfigManager"); + if (!wCmConfiguredNetwork.getNetworkSelectionStatus().isNetworkEnabled() + && !mWifiConfigManager.tryEnableNetwork(wCmConfiguredNetwork.networkId)) { + mLocalLog.log("Ignoring blocked network: " + + toNetworkString(wCmConfiguredNetwork)); + } + return; + } NetworkUpdateResult result = mWifiConfigManager.addOrUpdateNetwork( config, ewns.perAppInfo.uid, ewns.perAppInfo.packageName); if (!result.isSuccess()) { @@ -129,22 +138,13 @@ public class NetworkSuggestionNominator implements WifiNetworkSelector.NetworkNo return; } mLocalLog.log(config.getProfileKey() - + " is added/updated in the WifiConfigManager"); - mWifiConfigManager.allowAutojoin(result.getNetworkId(), config.allowAutojoin); + + " is added in the WifiConfigManager"); WifiConfiguration currentWCmConfiguredNetwork = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId()); // Try to enable network selection - if (wCmConfiguredNetwork == null) { - if (!mWifiConfigManager.updateNetworkSelectionStatus(result.getNetworkId(), - WifiConfiguration.NetworkSelectionStatus.DISABLED_NONE)) { - mLocalLog.log("Failed to make network suggestion selectable"); - } - } else { - if (!currentWCmConfiguredNetwork.getNetworkSelectionStatus().isNetworkEnabled() - && !mWifiConfigManager.tryEnableNetwork(wCmConfiguredNetwork.networkId)) { - mLocalLog.log("Ignoring blocked network: " - + toNetworkString(wCmConfiguredNetwork)); - } + if (!mWifiConfigManager.updateNetworkSelectionStatus(result.getNetworkId(), + WifiConfiguration.NetworkSelectionStatus.DISABLED_NONE)) { + mLocalLog.log("Failed to make network suggestion selectable"); } } diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java index cd167b84c0..685e298fad 100644 --- a/service/java/com/android/server/wifi/SoftApManager.java +++ b/service/java/com/android/server/wifi/SoftApManager.java @@ -77,6 +77,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; /** * Manage WiFi in AP mode. @@ -531,17 +532,17 @@ public class SoftApManager implements ActiveModeManager { pw.println("mSoftApCountryCode: " + mCountryCode); pw.println("mOriginalModeConfiguration.targetMode: " + mOriginalModeConfiguration.getTargetMode()); - pw.println("mCurrentSoftApConfiguration.mWifiSsid: " - + mCurrentSoftApConfiguration.getWifiSsid()); - pw.println("mCurrentSoftApConfiguration.mBand: " + mCurrentSoftApConfiguration.getBand()); - pw.println("mCurrentSoftApConfiguration.hiddenSSID: " - + mCurrentSoftApConfiguration.isHiddenSsid()); + pw.println("mCurrentSoftApConfiguration: " + mCurrentSoftApConfiguration); + pw.println("mCurrentSoftApCapability: " + mCurrentSoftApCapability); pw.println("getConnectedClientList().size(): " + getConnectedClientList().size()); pw.println("mTimeoutEnabled: " + mTimeoutEnabled); pw.println("mBridgedModeOpportunisticsShutdownTimeoutEnabled: " + mBridgedModeOpportunisticsShutdownTimeoutEnabled); pw.println("mCurrentSoftApInfoMap " + mCurrentSoftApInfoMap); pw.println("mStartTimestamp: " + mStartTimestamp); + pw.println("mSafeChannelFrequencyList: " + mSafeChannelFrequencyList.stream() + .map(Object::toString) + .collect(Collectors.joining(","))); mStateMachine.dump(fd, pw, args); } @@ -681,8 +682,8 @@ public class SoftApManager implements ActiveModeManager { * @return integer result code */ private int startSoftAp() { - Log.d(getTag(), "band " + mCurrentSoftApConfiguration.getBand() + " iface " - + mApInterfaceName + " country " + mCountryCode); + Log.d(getTag(), "startSoftAp: band " + mCurrentSoftApConfiguration.getBand() + + " iface " + mApInterfaceName + " country " + mCountryCode); int result = setMacAddress(); if (result != SUCCESS) { @@ -698,12 +699,9 @@ public class SoftApManager implements ActiveModeManager { SoftApConfiguration.Builder localConfigBuilder = new SoftApConfiguration.Builder(mCurrentSoftApConfiguration); - boolean acsEnabled = mCurrentSoftApCapability.areFeaturesSupported( - SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD); - result = ApConfigUtil.updateApChannelConfig( mWifiNative, mCoexManager, mContext.getResources(), mCountryCode, - localConfigBuilder, mCurrentSoftApConfiguration, acsEnabled); + localConfigBuilder, mCurrentSoftApConfiguration, mCurrentSoftApCapability); if (result != SUCCESS) { Log.e(getTag(), "Failed to update AP band and channel"); return result; diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index e7f4023f19..2ed7203f46 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -684,10 +684,15 @@ public class WifiConfigManager { * @param maskPasswords Mask passwords or not. * @param targetUid Target UID for MAC address reading: -1 = mask all, 0 = mask none, >0 = * mask all but the targetUid (carrier app). - * @return Copy of the WifiConfiguration object. + * @return Copy of the WifiConfiguration object, or a default WifiConfiguration if the input + * is null. */ - private WifiConfiguration createExternalWifiConfiguration( - WifiConfiguration configuration, boolean maskPasswords, int targetUid) { + private @NonNull WifiConfiguration createExternalWifiConfiguration( + @NonNull WifiConfiguration configuration, boolean maskPasswords, int targetUid) { + if (configuration == null) { + Log.wtf(TAG, "Unexpected null configuration in createExternalWifiConfiguration"); + return new WifiConfiguration(); + } WifiConfiguration network = new WifiConfiguration(configuration); if (maskPasswords) { maskPasswordsInWifiConfiguration(network); @@ -775,7 +780,7 @@ public class WifiConfigManager { * @param networkId networkId of the requested network. * @return WifiConfiguration object if found, null otherwise. */ - public WifiConfiguration getConfiguredNetwork(int networkId) { + public @Nullable WifiConfiguration getConfiguredNetwork(int networkId) { WifiConfiguration config = getInternalConfiguredNetwork(networkId); if (config == null) { return null; @@ -792,7 +797,7 @@ public class WifiConfigManager { * @param configKey configKey of the requested network. * @return WifiConfiguration object if found, null otherwise. */ - public WifiConfiguration getConfiguredNetwork(String configKey) { + public @Nullable WifiConfiguration getConfiguredNetwork(String configKey) { WifiConfiguration config = getInternalConfiguredNetwork(configKey); if (config == null) { return null; @@ -812,7 +817,7 @@ public class WifiConfigManager { * @param networkId networkId of the requested network. * @return WifiConfiguration object if found, null otherwise. */ - public WifiConfiguration getConfiguredNetworkWithPassword(int networkId) { + public @Nullable WifiConfiguration getConfiguredNetworkWithPassword(int networkId) { WifiConfiguration config = getInternalConfiguredNetwork(networkId); if (config == null) { return null; @@ -832,7 +837,7 @@ public class WifiConfigManager { * @param networkId networkId of the requested network. * @return Copy of WifiConfiguration object if found, null otherwise. */ - public WifiConfiguration getConfiguredNetworkWithoutMasking(int networkId) { + public @Nullable WifiConfiguration getConfiguredNetworkWithoutMasking(int networkId) { WifiConfiguration config = getInternalConfiguredNetwork(networkId); if (config == null) { return null; @@ -848,8 +853,8 @@ public class WifiConfigManager { return mConfiguredNetworks.valuesForCurrentUser(); } - private WifiConfiguration getInternalConfiguredNetworkByUpgradableType( - WifiConfiguration config) { + private @Nullable WifiConfiguration getInternalConfiguredNetworkByUpgradableType( + @NonNull WifiConfiguration config) { WifiConfiguration internalConfig = null; int securityType = config.getDefaultSecurityParams().getSecurityType(); WifiConfiguration possibleExistingConfig = new WifiConfiguration(config); @@ -888,7 +893,8 @@ public class WifiConfigManager { * This first attempts to find the network using the provided network ID in configuration, * else it attempts to find a matching configuration using the configKey. */ - private WifiConfiguration getInternalConfiguredNetwork(WifiConfiguration config) { + private @Nullable WifiConfiguration getInternalConfiguredNetwork( + @NonNull WifiConfiguration config) { WifiConfiguration internalConfig = mConfiguredNetworks.getForCurrentUser(config.networkId); if (internalConfig != null) { return internalConfig; @@ -911,7 +917,7 @@ public class WifiConfigManager { * Helper method to retrieve the internal WifiConfiguration object corresponding to the * provided network ID in our database. */ - private WifiConfiguration getInternalConfiguredNetwork(int networkId) { + private @Nullable WifiConfiguration getInternalConfiguredNetwork(int networkId) { if (networkId == WifiConfiguration.INVALID_NETWORK_ID) { return null; } @@ -926,7 +932,7 @@ public class WifiConfigManager { * Helper method to retrieve the internal WifiConfiguration object corresponding to the * provided configKey in our database. */ - private WifiConfiguration getInternalConfiguredNetwork(String configKey) { + private @Nullable WifiConfiguration getInternalConfiguredNetwork(String configKey) { WifiConfiguration internalConfig = mConfiguredNetworks.getByConfigKeyForCurrentUser(configKey); if (internalConfig == null) { @@ -1243,9 +1249,9 @@ public class WifiConfigManager { * @return Copy of existing WifiConfiguration object with parameters merged from the provided * configuration. */ - private WifiConfiguration updateExistingInternalWifiConfigurationFromExternal( - WifiConfiguration internalConfig, WifiConfiguration externalConfig, int uid, - @Nullable String packageName) { + private @NonNull WifiConfiguration updateExistingInternalWifiConfigurationFromExternal( + @NonNull WifiConfiguration internalConfig, @NonNull WifiConfiguration externalConfig, + int uid, @Nullable String packageName) { WifiConfiguration newInternalConfig = new WifiConfiguration(internalConfig); // Copy over all the public elements from the provided configuration. @@ -1288,9 +1294,11 @@ public class WifiConfigManager { * @param uid UID of the app requesting the network addition/modification. * @param packageName Package name of the app requesting the network addition/modification. * @return NetworkUpdateResult object representing status of the update. + * WifiConfiguration object representing the existing configuration matching + * the new config, or null if none matches. */ - private NetworkUpdateResult addOrUpdateNetworkInternal(WifiConfiguration config, int uid, - @Nullable String packageName) { + private @NonNull Pair<NetworkUpdateResult, WifiConfiguration> addOrUpdateNetworkInternal( + @NonNull WifiConfiguration config, int uid, @Nullable String packageName) { if (mVerboseLoggingEnabled) { Log.v(TAG, "Adding/Updating network " + config.getPrintableSsid()); } @@ -1306,7 +1314,9 @@ public class WifiConfigManager { if (!WifiConfigurationUtil.validate(config, supportedFeatures, WifiConfigurationUtil.VALIDATE_FOR_ADD)) { Log.e(TAG, "Cannot add network with invalid config"); - return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + return new Pair<>( + new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID), + existingInternalConfig); } newInternalConfig = createNewInternalWifiConfigurationFromExternal(config, uid, packageName); @@ -1321,13 +1331,17 @@ public class WifiConfigManager { if (!WifiConfigurationUtil.validate( config, supportedFeatures, WifiConfigurationUtil.VALIDATE_FOR_UPDATE)) { Log.e(TAG, "Cannot update network with invalid config"); - return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + return new Pair<>( + new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID), + existingInternalConfig); } // Check for the app's permission before we let it update this network. if (!canModifyNetwork(existingInternalConfig, uid, packageName)) { Log.e(TAG, "UID " + uid + " does not have permission to update configuration " + config.getProfileKey()); - return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + return new Pair<>( + new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID), + existingInternalConfig); } if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid) && !config.isPasspoint()) { @@ -1339,7 +1353,9 @@ public class WifiConfigManager { } if (!WifiConfigurationUtil.addUpgradableSecurityTypeIfNecessary(newInternalConfig)) { - return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + return new Pair<>( + new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID), + existingInternalConfig); } // Only add networks with proxy settings if the user has permission to @@ -1348,7 +1364,9 @@ public class WifiConfigManager { Log.e(TAG, "UID " + uid + " does not have permission to modify proxy Settings " + config.getProfileKey() + ". Must have NETWORK_SETTINGS," + " or be device or profile owner."); - return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + return new Pair<>( + new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID), + existingInternalConfig); } // Only allow changes in Repeater Enabled flag if the user has permission to @@ -1359,7 +1377,9 @@ public class WifiConfigManager { + " does not have permission to modify Repeater Enabled Settings " + " , or add a network with Repeater Enabled set to true " + config.getProfileKey() + ". Must have NETWORK_SETTINGS."); - return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + return new Pair<>( + new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID), + existingInternalConfig); } if (WifiConfigurationUtil.hasMacRandomizationSettingsChanged(existingInternalConfig, @@ -1374,7 +1394,9 @@ public class WifiConfigManager { + "NETWORK_SETTINGS or NETWORK_SETUP_WIZARD or be in Demo Mode " + "or be the creator adding or updating a passpoint network" + "or be an admin updating their own network."); - return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + return new Pair<>( + new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID), + existingInternalConfig); } // Update the keys for saved enterprise networks. For Passpoint, the certificates @@ -1382,7 +1404,9 @@ public class WifiConfigManager { // network the certificates and keys are installed at the time the suggestion is added if (!config.isPasspoint() && !config.fromWifiNetworkSuggestion && config.isEnterprise()) { if (!(mWifiKeyStore.updateNetworkKeys(newInternalConfig, existingInternalConfig))) { - return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + return new Pair<>( + new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID), + existingInternalConfig); } } @@ -1391,16 +1415,22 @@ public class WifiConfigManager { if ((supportedFeatures & WIFI_FEATURE_TRUST_ON_FIRST_USE) == 0) { Log.e(TAG, "Trust On First Use could not be set " + "when Trust On First Use is not supported."); - return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + return new Pair<>( + new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID), + existingInternalConfig); } if (!config.enterpriseConfig.isEapMethodServerCertUsed()) { Log.e(TAG, "Trust On First Use could not be set " + "when the server certificate is not used."); - return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + return new Pair<>( + new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID), + existingInternalConfig); } else if (config.enterpriseConfig.hasCaCertificate()) { Log.e(TAG, "Trust On First Use could not be set " + "when Root CA certificate is set."); - return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + return new Pair<>( + new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID), + existingInternalConfig); } } @@ -1434,12 +1464,16 @@ public class WifiConfigManager { mConfiguredNetworks.put(newInternalConfig); } catch (IllegalArgumentException e) { Log.e(TAG, "Failed to add network to config map", e); - return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + return new Pair<>( + new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID), + existingInternalConfig); } if (removeExcessNetworks()) { if (mConfiguredNetworks.getForAllUsers(newInternalConfig.networkId) == null) { Log.e(TAG, "Cannot add network because number of configured networks is maxed."); - return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); + return new Pair<>( + new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID), + existingInternalConfig); } } @@ -1465,7 +1499,7 @@ public class WifiConfigManager { + " configKey=" + newInternalConfig.getProfileKey() + " uid=" + Integer.toString(newInternalConfig.creatorUid) + " name=" + newInternalConfig.creatorName); - return result; + return new Pair<>(result, existingInternalConfig); } /** @@ -1505,7 +1539,10 @@ public class WifiConfigManager { } } - NetworkUpdateResult result = addOrUpdateNetworkInternal(config, uid, packageName); + Pair<NetworkUpdateResult, WifiConfiguration> resultPair = addOrUpdateNetworkInternal( + config, uid, packageName); + NetworkUpdateResult result = resultPair.first; + existingConfig = resultPair.second; if (!result.isSuccess()) { Log.e(TAG, "Failed to add/update network " + config.getPrintableSsid()); return result; @@ -1887,7 +1924,7 @@ public class WifiConfigManager { return updateNetworkSelectionStatus(config, reason); } - private boolean updateNetworkSelectionStatus(WifiConfiguration config, int reason) { + private boolean updateNetworkSelectionStatus(@NonNull WifiConfiguration config, int reason) { int prevNetworkSelectionStatus = config.getNetworkSelectionStatus() .getNetworkSelectionStatus(); if (!mWifiBlocklistMonitor.updateNetworkSelectionStatus(config, reason)) { @@ -1903,7 +1940,7 @@ public class WifiConfigManager { return true; } - private void sendNetworkSelectionStatusChangedUpdate(WifiConfiguration config, + private void sendNetworkSelectionStatusChangedUpdate(@NonNull WifiConfiguration config, int newNetworkSelectionStatus, int disableReason) { switch (newNetworkSelectionStatus) { case NetworkSelectionStatus.NETWORK_SELECTION_ENABLED: @@ -3550,14 +3587,22 @@ public class WifiConfigManager { /** * Add the network update event listener */ - public void addOnNetworkUpdateListener(OnNetworkUpdateListener listener) { + public void addOnNetworkUpdateListener(@NonNull OnNetworkUpdateListener listener) { + if (listener == null) { + Log.wtf(TAG, "addOnNetworkUpdateListener: listener must not be null"); + return; + } mListeners.add(listener); } /** * Remove the network update event listener */ - public void removeOnNetworkUpdateListener(OnNetworkUpdateListener listener) { + public void removeOnNetworkUpdateListener(@NonNull OnNetworkUpdateListener listener) { + if (listener == null) { + Log.wtf(TAG, "removeOnNetworkUpdateListener: listener must not be null"); + return; + } mListeners.remove(listener); } diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index 24ac310742..9bfd7ef3db 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -3016,6 +3016,13 @@ public class WifiNative { return mWifiVendorHal.isHalStarted(); } + /** + * Tests whether the HAL is supported or not + */ + public boolean isHalSupported() { + return mWifiVendorHal.isVendorHalSupported(); + } + // TODO: Change variable names to camel style. public static class ScanCapabilities { public int max_scan_cache_size; diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java index d78bb86d8c..f53d287ed6 100644 --- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java +++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java @@ -867,7 +867,6 @@ public class WifiNetworkSuggestionsManager { if (mVerboseLoggingEnabled) { Log.v(TAG, "Updated config in WifiConfigManager"); } - mWifiConfigManager.allowAutojoin(result.getNetworkId(), newConfig.allowAutojoin); } /** diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index 3db8052d63..8a485593ad 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -4895,6 +4895,7 @@ public class WifiServiceImpl extends BaseWifiService { mWifiMulticastLockManager.enableVerboseLogging(verboseEnabled); mWifiInjector.enableVerboseLogging(verboseEnabled, halVerboseEnabled); mWifiInjector.getSarManager().enableVerboseLogging(verboseEnabled); + ApConfigUtil.enableVerboseLogging(verboseEnabled); } @Override diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java index a321266849..c90b20a9ab 100644 --- a/service/java/com/android/server/wifi/WifiShellCommand.java +++ b/service/java/com/android/server/wifi/WifiShellCommand.java @@ -2096,7 +2096,7 @@ public class WifiShellCommand extends BasicShellCommandHandler { pw.println(" Turns on the default connected scorer."); pw.println(" Note: Will clear any external scorer set."); pw.println(" start-softap <ssid> (open|wpa2|wpa3|wpa3_transition|owe|owe_transition) " - + "<passphrase> [-b 2|5|6|any]"); + + "<passphrase> [-b 2|5|6|any|bridged]"); pw.println(" Start softap with provided params"); pw.println(" Note that the shell command doesn't activate internet tethering. In some " + "devices, internet sharing is possible when Wi-Fi STA is also enabled and is" diff --git a/service/java/com/android/server/wifi/WrongPasswordNotifier.java b/service/java/com/android/server/wifi/WrongPasswordNotifier.java index 637246e208..3ecff59a0b 100644 --- a/service/java/com/android/server/wifi/WrongPasswordNotifier.java +++ b/service/java/com/android/server/wifi/WrongPasswordNotifier.java @@ -18,18 +18,13 @@ package com.android.server.wifi; import android.app.Notification; import android.app.PendingIntent; -import android.content.Context; import android.content.Intent; import android.graphics.drawable.Icon; import android.net.wifi.WifiContext; -import android.os.UserHandle; -import android.os.UserManager; import android.provider.Settings; -import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; -import com.android.modules.utils.build.SdkLevel; import com.android.server.wifi.util.NativeUtil; /** @@ -91,16 +86,6 @@ public class WrongPasswordNotifier { .putExtra("wifi_start_connect_ssid", NativeUtil.removeEnclosingQuotes(ssid)); CharSequence title = mContext.getString( com.android.wifi.resources.R.string.wifi_available_title_failed_to_connect); - - Context userContext = mContext; - if (SdkLevel.isAtLeastS() && UserManager.isHeadlessSystemUserMode()) { - // Need to pass the context of the current user to the activity that's launched when - // the notification is tapped - userContext = mContext.createContextAsUser(UserHandle.CURRENT, /* flags= */ 0); - } - - Log.i(TAG, "Showing '" + title + "' notification for user " + userContext.getUser() - + " and package " + settingsPackage); Notification.Builder builder = mFrameworkFacade.makeNotificationBuilder(mContext, WifiService.NOTIFICATION_NETWORK_ALERTS) .setAutoCancel(true) @@ -111,7 +96,7 @@ public class WrongPasswordNotifier { .setContentTitle(title) .setContentText(ssid) .setContentIntent(mFrameworkFacade.getActivity( - userContext, 0, intent, + mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE)) .setColor(mContext.getResources().getColor( android.R.color.system_notification_accent_color)); diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java index 192989b0dc..b3793864ba 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java @@ -227,7 +227,6 @@ public class PasspointNetworkNominateHelper { mLocalLog.log("Failed to add passpoint network"); return existingNetwork; } - mWifiConfigManager.allowAutojoin(result.getNetworkId(), config.allowAutojoin); mWifiConfigManager.enableNetwork(result.getNetworkId(), false, config.creatorUid, null); mWifiConfigManager.setNetworkCandidateScanResult(result.getNetworkId(), candidate.mScanDetail.getScanResult(), 0, null); diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java index 7ac7607792..c840bf143a 100644 --- a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java +++ b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java @@ -935,4 +935,18 @@ public class WifiP2pNative { return mSupplicantP2pIfaceHal.setVendorElements( new HashSet<ScanResult.InformationElement>()); } + + /** Indicate whether or not 2.4GHz/5GHz DBS is supported. */ + public boolean is24g5gDbsSupported() { + if (null == mIWifiP2pIface) return false; + if (!mHalDeviceManager.isSupported()) return false; + return mHalDeviceManager.is24g5gDbsSupported(mIWifiP2pIface); + } + + /** Indicate whether or not 5GHz/6GHz DBS is supported. */ + public boolean is5g6gDbsSupported() { + if (null == mIWifiP2pIface) return false; + if (!mHalDeviceManager.isSupported()) return false; + return mHalDeviceManager.is5g6gDbsSupported(mIWifiP2pIface); + } } diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java index badbd78b40..a2d5d3f65e 100644 --- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java +++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java @@ -5972,13 +5972,40 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub { WifiInfo wifiInfo = wifiManager.getConnectionInfo(); Log.d(TAG, "WifiInfo: " + wifiInfo); int freq = wifiInfo.getFrequency(); + /* + * GO intent table + * STA Freq 2.4GHz/5GHz DBS 5GHz/6GHz DBS GO intent + * 2.4 GHz No X 5 + * N/A X X 6 (default) + * 2.4 GHz Yes X 7 + * 5 GHz Yes No 8 + * 5 GHz Yes Yes 9 + * 5 GHz No X 10 + * 6 GHz X No 11 + * 6 Ghz X Yes 12 + */ if (wifiInfo.getNetworkId() == WifiConfiguration.INVALID_NETWORK_ID) { - intent = DEFAULT_GROUP_OWNER_INTENT + 1; + intent = DEFAULT_GROUP_OWNER_INTENT; } else if (ScanResult.is24GHz(freq)) { - intent = WifiP2pConfig.GROUP_OWNER_INTENT_MIN; + if (mWifiNative.is24g5gDbsSupported()) { + intent = 7; + } else { + intent = 5; + } } else if (ScanResult.is5GHz(freq)) { - // If both sides use the maximum, the negotiation would fail. - intent = WifiP2pConfig.GROUP_OWNER_INTENT_MAX - 1; + if (!mWifiNative.is24g5gDbsSupported()) { + intent = 10; + } else if (mWifiNative.is5g6gDbsSupported()) { + intent = 9; + } else { + intent = 8; + } + } else if (ScanResult.is6GHz(freq)) { + if (mWifiNative.is5g6gDbsSupported()) { + intent = 12; + } else { + intent = 11; + } } else { intent = DEFAULT_GROUP_OWNER_INTENT; } diff --git a/service/java/com/android/server/wifi/util/ApConfigUtil.java b/service/java/com/android/server/wifi/util/ApConfigUtil.java index 7c548b8c8d..f94eb51b4a 100644 --- a/service/java/com/android/server/wifi/util/ApConfigUtil.java +++ b/service/java/com/android/server/wifi/util/ApConfigUtil.java @@ -26,6 +26,7 @@ import android.net.wifi.SoftApCapability; import android.net.wifi.SoftApConfiguration; import android.net.wifi.SoftApConfiguration.BandType; import android.net.wifi.SoftApInfo; +import android.net.wifi.WifiAvailableChannel; import android.net.wifi.WifiClient; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; @@ -41,6 +42,7 @@ import com.android.server.wifi.coex.CoexManager; import com.android.wifi.resources.R; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -49,6 +51,7 @@ import java.util.Map; import java.util.Objects; import java.util.Random; import java.util.Set; +import java.util.StringJoiner; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -71,6 +74,15 @@ public class ApConfigUtil { /* Random number generator used for AP channel selection. */ private static final Random sRandom = new Random(); + private static boolean sVerboseLoggingEnabled = false; + + /** + * Enable or disable verbose logging + * @param verboseEnabled true if verbose logging is enabled + */ + public static void enableVerboseLogging(boolean verboseEnabled) { + sVerboseLoggingEnabled = verboseEnabled; + } /** * Valid Global Operating classes in each wifi band @@ -86,6 +98,37 @@ public class ApConfigUtil { } /** + * Converts a SoftApConfiguration.BAND_* constant to a meaningful String + */ + public static String bandToString(int band) { + StringJoiner sj = new StringJoiner(" & "); + sj.setEmptyValue("unspecified"); + if ((band & SoftApConfiguration.BAND_2GHZ) != 0) { + sj.add("2Ghz"); + } + band &= ~SoftApConfiguration.BAND_2GHZ; + + if ((band & SoftApConfiguration.BAND_5GHZ) != 0) { + sj.add("5Ghz"); + } + band &= ~SoftApConfiguration.BAND_5GHZ; + + if ((band & SoftApConfiguration.BAND_6GHZ) != 0) { + sj.add("6Ghz"); + } + band &= ~SoftApConfiguration.BAND_6GHZ; + + if ((band & SoftApConfiguration.BAND_60GHZ) != 0) { + sj.add("60Ghz"); + } + band &= ~SoftApConfiguration.BAND_60GHZ; + if (band != 0) { + return "Invalid band"; + } + return sj.toString(); + } + + /** * Helper function to get the band corresponding to the operating class. * * @param operatingClass Global operating class. @@ -243,32 +286,16 @@ public class ApConfigUtil { */ public static boolean isBandSupported(@BandType int apBand, Context context) { if (!isBandValid(apBand)) { - Log.e(TAG, "Invalid SoftAp band. "); - return false; - } - - if (containsBand(apBand, SoftApConfiguration.BAND_2GHZ) - && !isSoftAp24GhzSupported(context)) { - Log.e(TAG, "Can not start softAp with 2GHz band, not supported."); - return false; - } - - if (containsBand(apBand, SoftApConfiguration.BAND_5GHZ) - && !isSoftAp5GhzSupported(context)) { - Log.e(TAG, "Can not start softAp with 5GHz band, not supported."); + Log.e(TAG, "Invalid SoftAp band " + apBand); return false; } - if (containsBand(apBand, SoftApConfiguration.BAND_6GHZ) - && !isSoftAp6GhzSupported(context)) { - Log.e(TAG, "Can not start softAp with 6GHz band, not supported."); - return false; - } - - if (containsBand(apBand, SoftApConfiguration.BAND_60GHZ) - && !isSoftAp60GhzSupported(context)) { - Log.e(TAG, "Can not start softAp with 6GHz band, not supported."); - return false; + for (int b : SoftApConfiguration.BAND_TYPES) { + if (containsBand(apBand, b) && !isSoftApBandSupported(context, b)) { + Log.e(TAG, "Can not start softAp with band " + bandToString(b) + + " not supported."); + return false; + } } return true; @@ -336,70 +363,124 @@ public class ApConfigUtil { return unsafeFreqs; } - /** - * Get channels or 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 restrictions. - * @param resources used to get OEM restrictions - * @param inFrequencyMHz true to convert channel to frequency. - * @return A list of frequencies that are allowed, null on error. - */ - public static List<Integer> getAvailableChannelFreqsForBand( - @BandType int band, WifiNative wifiNative, Resources resources, - boolean inFrequencyMHz) { - if (!isBandValid(band) || isMultiband(band)) { - return null; - } - - List<Integer> configuredList; - int scannerBand; + private static List<Integer> getConfiguredChannelList(Resources resources, @BandType int band) { switch (band) { case SoftApConfiguration.BAND_2GHZ: - configuredList = convertStringToChannelList(resources.getString( + return convertStringToChannelList(resources.getString( R.string.config_wifiSoftap2gChannelList)); - scannerBand = WifiScanner.WIFI_BAND_24_GHZ; - break; case SoftApConfiguration.BAND_5GHZ: - configuredList = convertStringToChannelList(resources.getString( + return convertStringToChannelList(resources.getString( R.string.config_wifiSoftap5gChannelList)); - scannerBand = WifiScanner.WIFI_BAND_5_GHZ; - break; case SoftApConfiguration.BAND_6GHZ: - configuredList = convertStringToChannelList(resources.getString( + return convertStringToChannelList(resources.getString( R.string.config_wifiSoftap6gChannelList)); - scannerBand = WifiScanner.WIFI_BAND_6_GHZ; - break; case SoftApConfiguration.BAND_60GHZ: - configuredList = convertStringToChannelList(resources.getString( + return convertStringToChannelList(resources.getString( R.string.config_wifiSoftap60gChannelList)); - scannerBand = WifiScanner.WIFI_BAND_60_GHZ; - break; default: return null; } + } - // Get the allowed list of channel frequencies in MHz - int[] regulatoryArray = wifiNative.getChannelsForBand(scannerBand); + private static List<Integer> addDfsChannelsIfNeeded(List<Integer> regulatoryList, + @WifiScanner.WifiBand int scannerBand, WifiNative wifiNative, Resources resources, + boolean inFrequencyMHz) { + // Add DFS channels to the supported channel list if the device supports SoftAp + // operation in the DFS channel. + if (resources.getBoolean(R.bool.config_wifiSoftapAcsIncludeDfs) + && scannerBand == WifiScanner.WIFI_BAND_5_GHZ) { + int[] dfs5gBand = wifiNative.getChannelsForBand( + WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY); + for (int freq : dfs5gBand) { + final int freqOrChan = inFrequencyMHz + ? freq : ScanResult.convertFrequencyMhzToChannelIfSupported(freq); + if (!regulatoryList.contains(freqOrChan)) { + regulatoryList.add(freqOrChan); + } + } + } + return regulatoryList; + } + + private static List<Integer> getWifiCondAvailableChannelsForBand( + @WifiScanner.WifiBand int scannerBand, WifiNative wifiNative, Resources resources, + boolean inFrequencyMHz) { List<Integer> regulatoryList = new ArrayList<Integer>(); + // Get the allowed list of channel frequencies in MHz from wificond + int[] regulatoryArray = wifiNative.getChannelsForBand(scannerBand); for (int freq : regulatoryArray) { regulatoryList.add(inFrequencyMHz ? freq : ScanResult.convertFrequencyMhzToChannelIfSupported(freq)); } + return addDfsChannelsIfNeeded(regulatoryList, scannerBand, wifiNative, resources, + inFrequencyMHz); + } - // Add DFS channels to the supported channel list if the device supports SoftAp operation - // in the DFS channel. - if (resources.getBoolean(R.bool.config_wifiSoftapAcsIncludeDfs) - && scannerBand == WifiScanner.WIFI_BAND_5_GHZ) { - regulatoryArray = wifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY); - for (int freq : regulatoryArray) { - regulatoryList.add(inFrequencyMHz - ? freq : ScanResult.convertFrequencyMhzToChannelIfSupported(freq)); - } + private static List<Integer> getHalAvailableChannelsForBand( + @WifiScanner.WifiBand int scannerBand, WifiNative wifiNative, Resources resources, + boolean inFrequencyMHz) { + // Try vendor HAL API to get the usable channel list. + List<WifiAvailableChannel> usableChannelList = wifiNative.getUsableChannels( + scannerBand, + WifiAvailableChannel.OP_MODE_SAP, + WifiAvailableChannel.FILTER_REGULATORY); + if (usableChannelList == null) { + // If HAL doesn't support getUsableChannels then return null + return null; + } + List<Integer> regulatoryList = usableChannelList.stream() + .map(ch -> inFrequencyMHz + ? ch.getFrequencyMhz() + : ScanResult.convertFrequencyMhzToChannelIfSupported( + ch.getFrequencyMhz())) + .collect(Collectors.toList()); + return addDfsChannelsIfNeeded(regulatoryList, scannerBand, wifiNative, resources, + inFrequencyMHz); + } + + /** + * Get channels or 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 restrictions. + * @param resources used to get OEM restrictions + * @param inFrequencyMHz true to convert channel to frequency. + * @return A list of frequencies that are allowed, null on error. + */ + public static List<Integer> getAvailableChannelFreqsForBand( + @BandType int band, WifiNative wifiNative, Resources resources, + boolean inFrequencyMHz) { + if (!isBandValid(band) || isMultiband(band)) { + return null; } - if (configuredList == null || configuredList.isEmpty()) { + int scannerBand = apConfig2wifiScannerBand(band); + List<Integer> regulatoryList = null; + boolean useWifiCond = false; + // Check if vendor HAL API for getting usable channels is available. If HAL doesn't support + // the API it returns null list, in that case we retrieve the list from wificond. + if (!wifiNative.isHalSupported()) { + // HAL is not supported, fallback to wificond + useWifiCond = true; + } else { + if (!wifiNative.isHalStarted()) { + // HAL is not started, return null + return null; + } + regulatoryList = getHalAvailableChannelsForBand(scannerBand, wifiNative, resources, + inFrequencyMHz); + if (regulatoryList == null) { + // HAL API not supported by HAL, fallback to wificond + useWifiCond = true; + } + } + if (useWifiCond) { + regulatoryList = getWifiCondAvailableChannelsForBand(scannerBand, wifiNative, resources, + inFrequencyMHz); + } + List<Integer> configuredList = getConfiguredChannelList(resources, band); + if (configuredList == null || configuredList.isEmpty() || regulatoryList == null) { return regulatoryList; } List<Integer> filteredList = new ArrayList<Integer>(); @@ -414,19 +495,23 @@ public class ApConfigUtil { filteredList.add(channel); } } + if (sVerboseLoggingEnabled) { + Log.d(TAG, "Filtered channel list for band " + bandToString(band) + " : " + + filteredList.stream().map(Object::toString).collect(Collectors.joining(","))); + } return filteredList; } /** * Return a channel frequency for AP setup based on the frequency band. * @param apBand one or combination of the values of SoftApConfiguration.BAND_*. - * @param wifiNative reference used to collect regulatory restrictions. * @param coexManager reference used to get unsafe channels to avoid for coex. * @param resources the resources to use to get configured allowed channels. + * @param capability soft AP capability * @return a valid channel frequency on success, -1 on failure. */ - public static int chooseApChannel(int apBand, @NonNull WifiNative wifiNative, - @NonNull CoexManager coexManager, @NonNull Resources resources) { + public static int chooseApChannel(int apBand, @NonNull CoexManager coexManager, + @NonNull Resources resources, SoftApCapability capability) { if (!isBandValid(apBand)) { Log.e(TAG, "Invalid band: " + apBand); return -1; @@ -446,11 +531,14 @@ public class ApConfigUtil { if ((apBand & band) == 0) { continue; } - final List<Integer> availableFreqs = - getAvailableChannelFreqsForBand(band, wifiNative, resources, true); - if (availableFreqs == null || availableFreqs.isEmpty()) { + int[] availableChannels = capability.getSupportedChannelList(band); + if (availableChannels == null || availableChannels.length == 0) { continue; } + final List<Integer> availableFreqs = + Arrays.stream(availableChannels).boxed() + .map(ch -> convertChannelToFrequency(ch, band)) + .collect(Collectors.toList()); // Separate the available freqs by safe and unsafe. List<Integer> availableSafeFreqs = new ArrayList<>(); List<Integer> availableUnsafeFreqs = new ArrayList<>(); @@ -498,7 +586,7 @@ public class ApConfigUtil { * Remove unavailable bands from the input band and return the resulting * (remaining) available bands. Unavailable bands are those which don't have channels available. * - * @param capability SoftApCapability which inidcates supported channel list. + * @param capability SoftApCapability which indicates supported channel list. * @param targetBand The target band which plan to enable * @param coexManager reference to CoexManager * @@ -541,17 +629,10 @@ public class ApConfigUtil { public static @BandType int removeUnsupportedBands(Context context, @NonNull int band) { int availableBand = band; - if (((band & SoftApConfiguration.BAND_2GHZ) != 0) && !isSoftAp24GhzSupported(context)) { - availableBand &= ~SoftApConfiguration.BAND_2GHZ; - } - if (((band & SoftApConfiguration.BAND_5GHZ) != 0) && !isSoftAp5GhzSupported(context)) { - availableBand &= ~SoftApConfiguration.BAND_5GHZ; - } - if (((band & SoftApConfiguration.BAND_6GHZ) != 0) && !isSoftAp6GhzSupported(context)) { - availableBand &= ~SoftApConfiguration.BAND_6GHZ; - } - if (((band & SoftApConfiguration.BAND_60GHZ) != 0) && !isSoftAp60GhzSupported(context)) { - availableBand &= ~SoftApConfiguration.BAND_60GHZ; + for (int b : SoftApConfiguration.BAND_TYPES) { + if (((band & b) != 0) && !isSoftApBandSupported(context, b)) { + availableBand &= ~b; + } } return availableBand; } @@ -629,6 +710,7 @@ public class ApConfigUtil { * @param resources the resources to use to get configured allowed channels. * @param countryCode country code * @param config configuration to update + * @param capability soft ap capability * @return an integer result code */ public static int updateApChannelConfig(WifiNative wifiNative, @@ -637,7 +719,7 @@ public class ApConfigUtil { String countryCode, SoftApConfiguration.Builder configBuilder, SoftApConfiguration config, - boolean acsEnabled) { + SoftApCapability capability) { /* Use default band and channel for device without HAL. */ if (!wifiNative.isHalStarted()) { configBuilder.setChannel(DEFAULT_AP_CHANNEL, DEFAULT_AP_BAND); @@ -650,11 +732,11 @@ public class ApConfigUtil { Log.e(TAG, "5GHz band is not allowed without country code"); return ERROR_GENERIC; } - - if (!acsEnabled) { + if (!capability.areFeaturesSupported(SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD)) { /* Select a channel if it is not specified and ACS is not enabled */ if (config.getChannel() == 0) { - int freq = chooseApChannel(config.getBand(), wifiNative, coexManager, resources); + int freq = chooseApChannel(config.getBand(), coexManager, resources, + capability); if (freq == -1) { /* We're not able to get channel from wificond. */ Log.e(TAG, "Failed to get available channel."); @@ -667,7 +749,9 @@ public class ApConfigUtil { if (SdkLevel.isAtLeastT()) { /* remove list of allowed channels since they only apply to ACS */ - Log.i(TAG, "Ignoring Allowed ACS channels since ACS is not supported."); + if (sVerboseLoggingEnabled) { + Log.i(TAG, "Ignoring Allowed ACS channels since ACS is not supported."); + } configBuilder.setAllowedAcsChannels(SoftApConfiguration.BAND_2GHZ, new int[] {}); configBuilder.setAllowedAcsChannels(SoftApConfiguration.BAND_5GHZ, @@ -765,22 +849,22 @@ public class ApConfigUtil { features |= SoftApCapability.SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION; } - if (isSoftAp24GhzSupported(context)) { + if (isSoftApBandSupported(context, SoftApConfiguration.BAND_2GHZ)) { Log.d(TAG, "Update Softap capability, add 2.4G support"); features |= SoftApCapability.SOFTAP_FEATURE_BAND_24G_SUPPORTED; } - if (isSoftAp5GhzSupported(context)) { + if (isSoftApBandSupported(context, SoftApConfiguration.BAND_5GHZ)) { Log.d(TAG, "Update Softap capability, add 5G support"); features |= SoftApCapability.SOFTAP_FEATURE_BAND_5G_SUPPORTED; } - if (isSoftAp6GhzSupported(context)) { + if (isSoftApBandSupported(context, SoftApConfiguration.BAND_6GHZ)) { Log.d(TAG, "Update Softap capability, add 6G support"); features |= SoftApCapability.SOFTAP_FEATURE_BAND_6G_SUPPORTED; } - if (isSoftAp60GhzSupported(context)) { + if (isSoftApBandSupported(context, SoftApConfiguration.BAND_60GHZ)) { Log.d(TAG, "Update Softap capability, add 60G support"); features |= SoftApCapability.SOFTAP_FEATURE_BAND_60G_SUPPORTED; } @@ -916,51 +1000,33 @@ public class ApConfigUtil { } /** - * Helper function to get whether or not 2.4G Soft AP support. + * Helper function to get whether or not Soft AP support on particular band. * * @param context the caller context used to get value from resource file. + * @param band the band soft AP to operate on. * @return true if supported, false otherwise. */ - public static boolean isSoftAp24GhzSupported(@NonNull Context context) { - return context.getResources().getBoolean(R.bool.config_wifi24ghzSupport) - && context.getResources().getBoolean( - R.bool.config_wifiSoftap24ghzSupported); - } - - /** - * Helper function to get whether or not 5G Soft AP support. - * - * @param context the caller context used to get value from resource file. - * @return true if supported, false otherwise. - */ - public static boolean isSoftAp5GhzSupported(@NonNull Context context) { - return context.getResources().getBoolean(R.bool.config_wifi5ghzSupport) - && context.getResources().getBoolean( - R.bool.config_wifiSoftap5ghzSupported); - } - - /** - * Helper function to get whether or not 6G Soft AP support - * - * @param context the caller context used to get value from resource file. - * @return true if supported, false otherwise. - */ - public static boolean isSoftAp6GhzSupported(@NonNull Context context) { - return context.getResources().getBoolean(R.bool.config_wifi6ghzSupport) - && context.getResources().getBoolean( - R.bool.config_wifiSoftap6ghzSupported); - } - - /** - * Helper function to get whether or not 60G Soft AP support. - * - * @param context the caller context used to get value from resource file. - * @return true if supported, false otherwise. - */ - public static boolean isSoftAp60GhzSupported(@NonNull Context context) { - return context.getResources().getBoolean(R.bool.config_wifi60ghzSupport) - && context.getResources().getBoolean( - R.bool.config_wifiSoftap60ghzSupported); + public static boolean isSoftApBandSupported(@NonNull Context context, @BandType int band) { + switch (band) { + case SoftApConfiguration.BAND_2GHZ: + return context.getResources().getBoolean(R.bool.config_wifi24ghzSupport) + && context.getResources().getBoolean( + R.bool.config_wifiSoftap24ghzSupported); + case SoftApConfiguration.BAND_5GHZ: + return context.getResources().getBoolean(R.bool.config_wifi5ghzSupport) + && context.getResources().getBoolean( + R.bool.config_wifiSoftap5ghzSupported); + case SoftApConfiguration.BAND_6GHZ: + return context.getResources().getBoolean(R.bool.config_wifi6ghzSupport) + && context.getResources().getBoolean( + R.bool.config_wifiSoftap6ghzSupported); + case SoftApConfiguration.BAND_60GHZ: + return context.getResources().getBoolean(R.bool.config_wifi60ghzSupport) + && context.getResources().getBoolean( + R.bool.config_wifiSoftap60ghzSupported); + default: + return false; + } } /** @@ -1091,40 +1157,16 @@ public class ApConfigUtil { // Note, // - We store the config string here for future use, hence we need to check all bands. // - If there is no restrictions on channels, we store the full band - String channelList = ""; - if ((band & SoftApConfiguration.BAND_2GHZ) != 0) { - channelList = - context.getResources().getString(R.string.config_wifiSoftap2gChannelList); - if (!TextUtils.isEmpty(channelList)) { - return true; - } - if (SdkLevel.isAtLeastT() - && config.getAllowedAcsChannels(SoftApConfiguration.BAND_2GHZ).length != 0) { - return true; - } - } - - if ((band & SoftApConfiguration.BAND_5GHZ) != 0) { - channelList = - context.getResources().getString(R.string.config_wifiSoftap5gChannelList); - if (!TextUtils.isEmpty(channelList)) { - return true; - } - if (SdkLevel.isAtLeastT() - && config.getAllowedAcsChannels(SoftApConfiguration.BAND_5GHZ).length != 0) { - return true; - } - } - - if ((band & SoftApConfiguration.BAND_6GHZ) != 0) { - channelList = - context.getResources().getString(R.string.config_wifiSoftap6gChannelList); - if (!TextUtils.isEmpty(channelList)) { - return true; - } - if (SdkLevel.isAtLeastT() - && config.getAllowedAcsChannels(SoftApConfiguration.BAND_6GHZ).length != 0) { - return true; + for (int b : SoftApConfiguration.BAND_TYPES) { + if ((band & b) != 0) { + List<Integer> configuredList = getConfiguredChannelList(context.getResources(), b); + if (configuredList != null && !configuredList.isEmpty()) { + // If any of the selected band has restriction in the overlay file return true. + return true; + } + if (SdkLevel.isAtLeastT() && config.getAllowedAcsChannels(b).length != 0) { + return true; + } } } @@ -1188,7 +1230,7 @@ public class ApConfigUtil { .boxed() .collect(Collectors.toSet()); default: - Log.e(TAG, "Invalid band: " + band); + Log.e(TAG, "Invalid band: " + bandToString(band)); return Collections.emptySet(); } } @@ -1281,54 +1323,29 @@ public class ApConfigUtil { /** - * Observer the available channel from native layer (wificond) and update the SoftApCapability + * Observer the available channel from native layer (vendor HAL if getUsableChannels is + * supported, or wificond if not supported) and update the SoftApCapability * * @param softApCapability the current softap capability * @param context the caller context used to get value from resource file - * @param wifiNative reference used to collect regulatory restrictions. - * + * @param wifiNative reference used to collect regulatory restrictions. * * @return updated soft AP capability */ public static SoftApCapability updateSoftApCapabilityWithAvailableChannelList( - @NonNull SoftApCapability softApCapability, @NonNull Context context, - @NonNull WifiNative wifiNative) { + @NonNull SoftApCapability softApCapability, @NonNull Context context, + @NonNull WifiNative wifiNative) { SoftApCapability newSoftApCapability = new SoftApCapability(softApCapability); List<Integer> supportedChannelList = null; - if (isSoftAp24GhzSupported(context)) { - supportedChannelList = getAvailableChannelFreqsForBand( - SoftApConfiguration.BAND_2GHZ, wifiNative, context.getResources(), false); - if (supportedChannelList != null) { - newSoftApCapability.setSupportedChannelList( - SoftApConfiguration.BAND_2GHZ, - supportedChannelList.stream().mapToInt(Integer::intValue).toArray()); - } - } - if (isSoftAp5GhzSupported(context)) { - supportedChannelList = getAvailableChannelFreqsForBand( - SoftApConfiguration.BAND_5GHZ, wifiNative, context.getResources(), false); - if (supportedChannelList != null) { - newSoftApCapability.setSupportedChannelList( - SoftApConfiguration.BAND_5GHZ, - supportedChannelList.stream().mapToInt(Integer::intValue).toArray()); - } - } - if (isSoftAp6GhzSupported(context)) { - supportedChannelList = getAvailableChannelFreqsForBand( - SoftApConfiguration.BAND_6GHZ, wifiNative, context.getResources(), false); - if (supportedChannelList != null) { - newSoftApCapability.setSupportedChannelList( - SoftApConfiguration.BAND_6GHZ, - supportedChannelList.stream().mapToInt(Integer::intValue).toArray()); - } - } - if (isSoftAp60GhzSupported(context)) { - supportedChannelList = getAvailableChannelFreqsForBand( - SoftApConfiguration.BAND_60GHZ, wifiNative, context.getResources(), - false); - if (supportedChannelList != null) { - newSoftApCapability.setSupportedChannelList( - SoftApConfiguration.BAND_60GHZ, - supportedChannelList.stream().mapToInt(Integer::intValue).toArray()); + + for (int band : SoftApConfiguration.BAND_TYPES) { + if (isSoftApBandSupported(context, band)) { + supportedChannelList = getAvailableChannelFreqsForBand( + band, wifiNative, context.getResources(), false); + if (supportedChannelList != null) { + newSoftApCapability.setSupportedChannelList( + band, + supportedChannelList.stream().mapToInt(Integer::intValue).toArray()); + } } } return newSoftApCapability; diff --git a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java index 7bfd3139a4..78faf9fcf3 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java @@ -65,7 +65,11 @@ import android.hardware.wifi.V1_0.IWifiStaIface; import android.hardware.wifi.V1_0.IfaceType; import android.hardware.wifi.V1_0.WifiStatus; import android.hardware.wifi.V1_0.WifiStatusCode; +import android.hardware.wifi.V1_5.WifiBand; import android.hardware.wifi.V1_6.IfaceConcurrencyType; +import android.hardware.wifi.V1_6.WifiRadioCombination; +import android.hardware.wifi.V1_6.WifiRadioCombinationMatrix; +import android.hardware.wifi.V1_6.WifiRadioConfiguration; import android.hidl.manager.V1_0.IServiceNotification; import android.hidl.manager.V1_2.IServiceManager; import android.net.wifi.WifiContext; @@ -85,6 +89,8 @@ import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener; import com.android.server.wifi.util.WorkSourceHelper; import com.android.wifi.resources.R; +import com.google.common.collect.ImmutableList; + import org.hamcrest.core.IsNull; import org.junit.After; import org.junit.Before; @@ -3157,6 +3163,109 @@ public class HalDeviceManagerTest extends WifiBaseTest { TestChipV6.CHIP_MODE_ID); } + private IWifiIface setupDbsSupportTest(ChipMockBase testChip, int onlyChipMode, + ImmutableList<ArrayList<Integer>> radioCombinationMatrix) throws Exception { + WifiRadioCombinationMatrix matrix = new WifiRadioCombinationMatrix(); + for (ArrayList<Integer> comb: radioCombinationMatrix) { + WifiRadioCombination combination = new WifiRadioCombination(); + for (Integer b: comb) { + WifiRadioConfiguration config = new WifiRadioConfiguration(); + config.bandInfo = b; + combination.radioConfigurations.add(config); + } + matrix.radioCombinations.add(combination); + } + + testChip.chipSupportedRadioCombinationsMatrix = matrix; + + testChip.initialize(); + mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, testChip.chip, + mManagerStatusListenerMock); + executeAndValidateInitializationSequence(); + executeAndValidateStartupSequence(); + + InterfaceDestroyedListener staDestroyedListener = mock( + InterfaceDestroyedListener.class); + + InterfaceDestroyedListener p2pDestroyedListener = mock( + InterfaceDestroyedListener.class); + + // Request STA + IWifiIface staIface = validateInterfaceSequence(testChip, + false, // chipModeValid + -1000, // chipModeId (only used if chipModeValid is true) + HDM_CREATE_IFACE_STA, // createIfaceType + "wlan0", // ifaceName + onlyChipMode, // finalChipMode + null, // tearDownList + staDestroyedListener, // destroyedListener + TEST_WORKSOURCE_0 // requestorWs + ); + collector.checkThat("STA can't be created", staIface, IsNull.notNullValue()); + + // Request P2P + IWifiIface p2pIface = validateInterfaceSequence(testChip, + true, // chipModeValid + onlyChipMode, // chipModeId + HDM_CREATE_IFACE_P2P, // ifaceTypeToCreate + "p2p0", // ifaceName + onlyChipMode, // finalChipMode + null, // tearDownList + p2pDestroyedListener, // destroyedListener + TEST_WORKSOURCE_0 // requestorWs + ); + collector.checkThat("P2P can't be created", p2pIface, IsNull.notNullValue()); + mTestLooper.dispatchAll(); + + return staIface; + } + + /** + * Validate 24GHz/5GHz DBS support. + */ + @Test + public void test24g5gDbsSupport() throws Exception { + TestChipV6 testChip = new TestChipV6(); + ImmutableList<ArrayList<Integer>> radioCombinationMatrix = ImmutableList.of( + new ArrayList(Arrays.asList(WifiBand.BAND_24GHZ, WifiBand.BAND_5GHZ))); + IWifiIface iface = setupDbsSupportTest(testChip, TestChipV6.CHIP_MODE_ID, + radioCombinationMatrix); + + assertTrue(mDut.is24g5gDbsSupported(iface)); + assertFalse(mDut.is5g6gDbsSupported(iface)); + } + + /** + * Validate 5GHz/6GHz DBS support. + */ + @Test + public void test5g6gDbsSupport() throws Exception { + TestChipV6 testChip = new TestChipV6(); + ImmutableList<ArrayList<Integer>> radioCombinationMatrix = ImmutableList.of( + new ArrayList(Arrays.asList(WifiBand.BAND_5GHZ, WifiBand.BAND_6GHZ))); + IWifiIface iface = setupDbsSupportTest(testChip, TestChipV6.CHIP_MODE_ID, + radioCombinationMatrix); + + assertFalse(mDut.is24g5gDbsSupported(iface)); + assertTrue(mDut.is5g6gDbsSupported(iface)); + } + + /** + * Validate 2.4GHz/5GHz DBS and 5GHz/6GHz DBS support. + */ + @Test + public void test24g5gAnd5g6gDbsSupport() throws Exception { + TestChipV6 testChip = new TestChipV6(); + ImmutableList<ArrayList<Integer>> radioCombinationMatrix = ImmutableList.of( + new ArrayList(Arrays.asList(WifiBand.BAND_24GHZ, WifiBand.BAND_5GHZ)), + new ArrayList(Arrays.asList(WifiBand.BAND_5GHZ, WifiBand.BAND_6GHZ))); + IWifiIface iface = setupDbsSupportTest(testChip, TestChipV6.CHIP_MODE_ID, + radioCombinationMatrix); + + assertTrue(mDut.is24g5gDbsSupported(iface)); + assertTrue(mDut.is5g6gDbsSupported(iface)); + } + /////////////////////////////////////////////////////////////////////////////////////// // utilities /////////////////////////////////////////////////////////////////////////////////////// @@ -3912,6 +4021,21 @@ public class HalDeviceManagerTest extends WifiBaseTest { } } + private class GetSupportedRadioCombinationsMatrixAnswer + extends MockAnswerUtil.AnswerWithArguments { + private ChipMockBase mChipMockBase; + + GetSupportedRadioCombinationsMatrixAnswer(ChipMockBase chipMockBase) { + mChipMockBase = chipMockBase; + } + + public void answer( + android.hardware.wifi.V1_6.IWifiChip.getSupportedRadioCombinationsMatrixCallback + cb) { + cb.onValues(mStatusOk, mChipMockBase.chipSupportedRadioCombinationsMatrix); + } + } + // chip configuration private static final int CHIP_MOCK_V1 = 0; @@ -3930,6 +4054,7 @@ public class HalDeviceManagerTest extends WifiBaseTest { public int chipModeId = -1000; public int chipModeIdValidForRtt = -1; // single chip mode ID where RTT can be created public int chipCapabilities = 0; + public WifiRadioCombinationMatrix chipSupportedRadioCombinationsMatrix = null; public Map<Integer, ArrayList<String>> interfaceNames = new HashMap<>(); public Map<Integer, Map<String, IWifiIface>> interfacesByName = new HashMap<>(); @@ -3988,6 +4113,10 @@ public class HalDeviceManagerTest extends WifiBaseTest { chip).createRttController(any(), any()); doAnswer(new GetBoundIfaceAnswer(true)).when(mRttControllerMock).getBoundIface(any()); + doAnswer(new GetSupportedRadioCombinationsMatrixAnswer(this)) + .when(chip).getSupportedRadioCombinationsMatrix( + any(android.hardware.wifi.V1_6.IWifiChip + .getSupportedRadioCombinationsMatrixCallback.class)); } } @@ -4336,6 +4465,7 @@ public class HalDeviceManagerTest extends WifiBaseTest { // test chip configuration V6 for Bridged AP: // mode: // STA + (AP || AP_BRIDGED) + // STA + (NAN || P2P) private class TestChipV6 extends ChipMockBase { // only mode (different number from any in other TestChips so can catch test errors) static final int CHIP_MODE_ID = 60; @@ -4361,7 +4491,7 @@ public class HalDeviceManagerTest extends WifiBaseTest { android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination ccc; android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit cccl; - // Mode 60 (only one): 1xSTA + 1x{AP,AP_BRIDGED} + // Mode 60 (only one): 1xSTA + 1x{AP,AP_BRIDGED}, 1xSTA + 1x{P2P,NAN} availableModes_1_6 = new ArrayList<>(); cm = new android.hardware.wifi.V1_6.IWifiChip.ChipMode(); cm.id = CHIP_MODE_ID; @@ -4380,6 +4510,22 @@ public class HalDeviceManagerTest extends WifiBaseTest { ccc.limits.add(cccl); cm.availableCombinations.add(ccc); + + ccc = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombination(); + + cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit(); + cccl.maxIfaces = 1; + cccl.types.add(IfaceType.STA); + ccc.limits.add(cccl); + + cccl = new android.hardware.wifi.V1_6.IWifiChip.ChipConcurrencyCombinationLimit(); + cccl.maxIfaces = 1; + cccl.types.add(IfaceType.P2P); + cccl.types.add(IfaceType.NAN); + ccc.limits.add(cccl); + + cm.availableCombinations.add(ccc); + availableModes_1_6.add(cm); chipModeIdValidForRtt = CHIP_MODE_ID; diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java index 6e1191961f..2082e03fcc 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java @@ -24,6 +24,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; +import static org.mockito.ArgumentMatchers.anyObject; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; @@ -7346,4 +7347,31 @@ public class WifiConfigManagerTest extends WifiBaseTest { assertTrue(option23.containsAll(actual23)); assertTrue(actual23.containsAll(option23)); } + + @Test + public void testAddOnNetworkUpdateListenerNull() throws Exception { + ArgumentCaptor<WifiConfiguration> wifiConfigCaptor = + ArgumentCaptor.forClass(WifiConfiguration.class); + mWifiConfigManager.addOnNetworkUpdateListener(mListener); + mWifiConfigManager.addOnNetworkUpdateListener(null); + WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork(); + verifyAddNetworkToWifiConfigManager(openNetwork); + NetworkUpdateResult result = + mWifiConfigManager.addOrUpdateNetwork(openNetwork, TEST_CREATOR_UID); + verify(mListener).onNetworkAdded(wifiConfigCaptor.capture()); + assertEquals(openNetwork.networkId, wifiConfigCaptor.getValue().networkId); + } + + @Test + public void testRemoveOnNetworkUpdateListenerNull() throws Exception { + mWifiConfigManager.addOnNetworkUpdateListener(mListener); + mWifiConfigManager.addOnNetworkUpdateListener(null); + mWifiConfigManager.removeOnNetworkUpdateListener(null); + mWifiConfigManager.removeOnNetworkUpdateListener(mListener); + WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork(); + verifyAddNetworkToWifiConfigManager(openNetwork); + NetworkUpdateResult result = + mWifiConfigManager.addOrUpdateNetwork(openNetwork, TEST_CREATOR_UID); + verify(mListener, never()).onNetworkAdded(anyObject()); + } } diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java index dcfdb86a68..837613632e 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java @@ -4129,7 +4129,6 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { .thenReturn(true); verify(mPasspointManager).enableAutojoin(anyString(), any(), eq(true)); verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt(), anyString()); - verify(mWifiConfigManager).allowAutojoin(anyInt(), eq(true)); matchedSuggestions = mWifiNetworkSuggestionsManager .getNetworkSuggestionsForScanDetail(createScanDetailForNetwork(eapSimConfig)); diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java index 984a2c342d..da81260f2f 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pNativeTest.java @@ -25,10 +25,13 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.withSettings; import android.app.test.MockAnswerUtil.AnswerWithArguments; +import android.hardware.wifi.V1_0.IWifiP2pIface; import android.net.wifi.WifiManager; import android.net.wifi.nl80211.WifiNl80211Manager; import android.net.wifi.p2p.WifiP2pConfig; @@ -39,20 +42,25 @@ import android.net.wifi.p2p.WifiP2pManager; import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo; import android.net.wifi.p2p.nsd.WifiP2pServiceInfo; import android.os.Handler; +import android.os.WorkSource; import androidx.test.filters.SmallTest; +import com.android.dx.mockito.inline.extended.ExtendedMockito; import com.android.server.wifi.HalDeviceManager; import com.android.server.wifi.PropertyService; import com.android.server.wifi.WifiBaseTest; import com.android.server.wifi.WifiNative; import com.android.server.wifi.WifiVendorHal; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.MockitoSession; +import org.mockito.quality.Strictness; import java.util.Collections; import java.util.HashSet; @@ -91,6 +99,7 @@ public class WifiP2pNativeTest extends WifiBaseTest { @Mock private PropertyService mPropertyServiceMock; @Mock private Handler mHandler; + private MockitoSession mSession; private WifiP2pNative mWifiP2pNative; private WifiP2pGroupList mWifiP2pGroupList = new WifiP2pGroupList(); private Set<String> mWifiClientInterfaceNames = new HashSet<String>(); @@ -110,6 +119,13 @@ public class WifiP2pNativeTest extends WifiBaseTest { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); + mSession = ExtendedMockito.mockitoSession() + .mockStatic(HalDeviceManager.class, withSettings().lenient()) + .strictness(Strictness.LENIENT) + .startMocking(); + + when(HalDeviceManager.getName(any())).thenReturn(TEST_IFACE); + mWifiClientInterfaceNames.add("wlan0"); mWifiClientInterfaceNames.add("wlan1"); @@ -146,6 +162,11 @@ public class WifiP2pNativeTest extends WifiBaseTest { } + @After + public void tearDown() { + mSession.finishMocking(); + } + /** * Verifies that isHalInterfaceSupported returns correct values. */ @@ -736,4 +757,51 @@ public class WifiP2pNativeTest extends WifiBaseTest { assertTrue(mWifiP2pNative.removeClient(TEST_BSSID)); verify(mSupplicantP2pIfaceHalMock).removeClient(eq(TEST_BSSID), anyBoolean()); } + + void prepareDbsMock(boolean isHalDeviceManagerSupported) throws Exception { + when(mHalDeviceManagerMock.isSupported()).thenReturn(isHalDeviceManagerSupported); + when(mHalDeviceManagerMock.createP2pIface(any(), any(), any())) + .thenReturn(mock(IWifiP2pIface.class)); + when(mSupplicantP2pIfaceHalMock.isInitializationStarted()).thenReturn(true); + when(mSupplicantP2pIfaceHalMock.initialize()).thenReturn(true); + when(mSupplicantP2pIfaceHalMock.isInitializationComplete()).thenReturn(true); + when(mSupplicantP2pIfaceHalMock.setupIface(any())).thenReturn(true); + mWifiP2pNative.setupInterface(null, mHandler, mock(WorkSource.class)); + } + + /** + * Verify DBS support inquiry. + */ + @Test + public void testDbsSupport() throws Exception { + prepareDbsMock(true); + + when(mHalDeviceManagerMock.is24g5gDbsSupported(any())).thenReturn(true); + assertTrue(mWifiP2pNative.is24g5gDbsSupported()); + when(mHalDeviceManagerMock.is24g5gDbsSupported(any())).thenReturn(false); + assertFalse(mWifiP2pNative.is24g5gDbsSupported()); + + when(mHalDeviceManagerMock.is5g6gDbsSupported(any())).thenReturn(true); + assertTrue(mWifiP2pNative.is5g6gDbsSupported()); + when(mHalDeviceManagerMock.is5g6gDbsSupported(any())).thenReturn(false); + assertFalse(mWifiP2pNative.is5g6gDbsSupported()); + } + + /** + * Verify DBS support inquiry when HalDeviceManager is not supported. + */ + @Test + public void testDbsSupportWhenHalDeviceManagerNotSupported() throws Exception { + prepareDbsMock(false); + + when(mHalDeviceManagerMock.is24g5gDbsSupported(any())).thenReturn(true); + assertFalse(mWifiP2pNative.is24g5gDbsSupported()); + when(mHalDeviceManagerMock.is24g5gDbsSupported(any())).thenReturn(false); + assertFalse(mWifiP2pNative.is24g5gDbsSupported()); + + when(mHalDeviceManagerMock.is5g6gDbsSupported(any())).thenReturn(true); + assertFalse(mWifiP2pNative.is5g6gDbsSupported()); + when(mHalDeviceManagerMock.is5g6gDbsSupported(any())).thenReturn(false); + assertFalse(mWifiP2pNative.is5g6gDbsSupported()); + } } diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java index 9cd56e1200..370180bc6a 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java @@ -5285,13 +5285,10 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { } } - /** - * Verify the group owner intent value is selected correctly when no STA connection. - */ - @Test - public void testGroupOwnerIntentSelectionWithoutStaConnection() throws Exception { - when(mWifiInfo.getNetworkId()).thenReturn(WifiConfiguration.INVALID_NETWORK_ID); - when(mWifiInfo.getFrequency()).thenReturn(2412); + private void verifyGroupOwnerIntentSelection(int netId, int freq, int expectedGoIntent) + throws Exception { + when(mWifiInfo.getNetworkId()).thenReturn(netId); + when(mWifiInfo.getFrequency()).thenReturn(freq); forceP2pEnabled(mClient1); sendChannelInfoUpdateMsg("testPkg1", "testFeature", mClient1, mClientMessenger); @@ -5307,8 +5304,89 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { ArgumentCaptor.forClass(WifiP2pConfig.class); verify(mWifiNative).p2pConnect(configCaptor.capture(), anyBoolean()); WifiP2pConfig config = configCaptor.getValue(); - assertEquals(WifiP2pServiceImpl.DEFAULT_GROUP_OWNER_INTENT + 1, - config.groupOwnerIntent); + assertEquals(expectedGoIntent, config.groupOwnerIntent); + } + + /** + * Verify the group owner intent value is selected correctly when no STA connection. + */ + @Test + public void testGroupOwnerIntentSelectionWithoutStaConnection() throws Exception { + verifyGroupOwnerIntentSelection(WifiConfiguration.INVALID_NETWORK_ID, 2412, + WifiP2pServiceImpl.DEFAULT_GROUP_OWNER_INTENT); + } + + /** + * Verify the group owner intent value is selected correctly when 2.4GHz STA connection + * without 2.4GHz/5GHz DBS support. + */ + @Test + public void testGroupOwnerIntentSelectionWith24GStaConnectionWithout24g5gDbs() + throws Exception { + verifyGroupOwnerIntentSelection(1, 2412, 5); + } + + /** + * Verify the group owner intent value is selected correctly when 2.4GHz STA connection + * with 2.4GHz/5GHz DBS support. + */ + @Test + public void testGroupOwnerIntentSelectionWith24GStaConnectionWith24g5gDbs() throws Exception { + when(mWifiNative.is24g5gDbsSupported()).thenReturn(true); + verifyGroupOwnerIntentSelection(1, 2412, 7); + } + + /** + * Verify the group owner intent value is selected correctly when 5GHz STA connection + * without 2.4GHz/5GHz DBS and 5GHz/6GHz DBS support. + */ + @Test + public void testGroupOwnerIntentSelectionWith5GHzStaConnectionWithout24g5gDbs5g6gDbs() + throws Exception { + verifyGroupOwnerIntentSelection(1, 5200, 10); + } + + /** + * Verify the group owner intent value is selected correctly when 5GHz STA connection + * with 2.4GHz/5GHz DBS and without 5GHz/6GHz DBS support. + */ + @Test + public void testGroupOwnerIntentSelectionWith5GHzStaConnectionWith24g5gDbsWithout5g6gDbs() + throws Exception { + when(mWifiNative.is24g5gDbsSupported()).thenReturn(true); + verifyGroupOwnerIntentSelection(1, 5200, 8); + } + + /** + * Verify the group owner intent value is selected correctly when 5GHz STA connection + * with 2.4GHz/5GHz DBS and 5GHz/6GHz DBS support. + */ + @Test + public void testGroupOwnerIntentSelectionWith5GHzStaConnectionWith24g5gDbs5g6gDbs() + throws Exception { + when(mWifiNative.is24g5gDbsSupported()).thenReturn(true); + when(mWifiNative.is5g6gDbsSupported()).thenReturn(true); + verifyGroupOwnerIntentSelection(1, 5200, 9); + } + + /** + * Verify the group owner intent value is selected correctly when 6GHz STA connection + * without 5GHz/6GHz DBS support. + */ + @Test + public void testGroupOwnerIntentSelectionWith6GHzStaConnectionWithout5g6gDbs() + throws Exception { + verifyGroupOwnerIntentSelection(1, 6000, 11); + } + + /** + * Verify the group owner intent value is selected correctly when 6GHz STA connection + * with 5GHz/6GHz DBS support. + */ + @Test + public void testGroupOwnerIntentSelectionWith6GHzStaConnectionWith5g6gDbs() throws Exception { + when(mWifiNative.is5g6gDbsSupported()).thenReturn(true); + verifyGroupOwnerIntentSelection(1, 6000, 12); } /** @@ -5373,84 +5451,6 @@ public class WifiP2pServiceImplTest extends WifiBaseTest { } } - /** - * Verify the group owner intent value is selected correctly when 2.4GHz STA connection. - */ - @Test - public void testGroupOwnerIntentSelectionWith24GStaConnection() throws Exception { - when(mWifiInfo.getNetworkId()).thenReturn(1); - when(mWifiInfo.getFrequency()).thenReturn(2412); - forceP2pEnabled(mClient1); - sendChannelInfoUpdateMsg("testPkg1", "testFeature", mClient1, mClientMessenger); - - mockEnterProvisionDiscoveryState(); - - WifiP2pProvDiscEvent pdEvent = new WifiP2pProvDiscEvent(); - pdEvent.device = mTestWifiP2pDevice; - sendSimpleMsg(null, - WifiP2pMonitor.P2P_PROV_DISC_PBC_RSP_EVENT, - pdEvent); - - ArgumentCaptor<WifiP2pConfig> configCaptor = - ArgumentCaptor.forClass(WifiP2pConfig.class); - verify(mWifiNative).p2pConnect(configCaptor.capture(), anyBoolean()); - WifiP2pConfig config = configCaptor.getValue(); - assertEquals(WifiP2pConfig.GROUP_OWNER_INTENT_MIN, - config.groupOwnerIntent); - } - - /** - * Verify the group owner intent value is selected correctly when 5GHz STA connection. - */ - @Test - public void testGroupOwnerIntentSelectionWith5GHzStaConnection() throws Exception { - when(mWifiInfo.getNetworkId()).thenReturn(1); - when(mWifiInfo.getFrequency()).thenReturn(5200); - forceP2pEnabled(mClient1); - sendChannelInfoUpdateMsg("testPkg1", "testFeature", mClient1, mClientMessenger); - - mockEnterProvisionDiscoveryState(); - - WifiP2pProvDiscEvent pdEvent = new WifiP2pProvDiscEvent(); - pdEvent.device = mTestWifiP2pDevice; - sendSimpleMsg(null, - WifiP2pMonitor.P2P_PROV_DISC_PBC_RSP_EVENT, - pdEvent); - - ArgumentCaptor<WifiP2pConfig> configCaptor = - ArgumentCaptor.forClass(WifiP2pConfig.class); - verify(mWifiNative).p2pConnect(configCaptor.capture(), anyBoolean()); - WifiP2pConfig config = configCaptor.getValue(); - assertEquals(WifiP2pConfig.GROUP_OWNER_INTENT_MAX - 1, - config.groupOwnerIntent); - } - - /** - * Verify the group owner intent value is selected correctly when 6GHz STA connection. - */ - @Test - public void testGroupOwnerIntentSelectionWith6GHzStaConnection() throws Exception { - when(mWifiInfo.getNetworkId()).thenReturn(1); - when(mWifiInfo.getFrequency()).thenReturn(6000); - forceP2pEnabled(mClient1); - sendChannelInfoUpdateMsg("testPkg1", "testFeature", mClient1, mClientMessenger); - - mockEnterProvisionDiscoveryState(); - - WifiP2pProvDiscEvent pdEvent = new WifiP2pProvDiscEvent(); - pdEvent.device = mTestWifiP2pDevice; - sendSimpleMsg(null, - WifiP2pMonitor.P2P_PROV_DISC_PBC_RSP_EVENT, - pdEvent); - - ArgumentCaptor<WifiP2pConfig> configCaptor = - ArgumentCaptor.forClass(WifiP2pConfig.class); - verify(mWifiNative).p2pConnect(configCaptor.capture(), anyBoolean()); - WifiP2pConfig config = configCaptor.getValue(); - assertEquals(WifiP2pServiceImpl.DEFAULT_GROUP_OWNER_INTENT, - config.groupOwnerIntent); - } - private List<CoexUnsafeChannel> setupCoexMock(int restrictionBits) { assumeTrue(SdkLevel.isAtLeastS()); List<CoexUnsafeChannel> unsafeChannels = new ArrayList<>(); 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 33f59a55c2..3f9cb51010 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 @@ -19,11 +19,14 @@ package com.android.server.wifi.util; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -138,21 +141,38 @@ public class ApConfigUtilTest extends WifiBaseTest { 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_2G5G_FREQS = {2462, 5745, 5765}; + private static final int[] ALLOWED_2G_CHANS = {11}; //ch# 11 + private static final int[] ALLOWED_5G_CHANS = {149, 153}; //ch# 149, 153 + private static final int[] ALLOWED_2G5G_CHANS = {11, 149, 153}; private static final int[] ALLOWED_6G_FREQS = {5945, 5965}; private static final int[] ALLOWED_60G_FREQS = {58320, 60480}; // ch# 1, 2 + private static final int[] ALLOWED_60G_CHANS = {1, 2}; // ch# 1, 2 private static final int[] TEST_5G_DFS_FREQS = {5280, 5520}; // ch#56, 104 @Mock Context mContext; @Mock Resources mResources; @Mock WifiNative mWifiNative; @Mock CoexManager mCoexManager; - + private SoftApCapability mCapability; /** * Setup test. */ @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); + final long testFeatures = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT + | SoftApCapability.SOFTAP_FEATURE_BAND_6G_SUPPORTED + | SoftApCapability.SOFTAP_FEATURE_BAND_60G_SUPPORTED; + mCapability = new SoftApCapability(testFeatures); + mCapability.setSupportedChannelList(SoftApConfiguration.BAND_2GHZ, ALLOWED_2G_CHANS); + mCapability.setSupportedChannelList(SoftApConfiguration.BAND_5GHZ, ALLOWED_5G_CHANS); + mCapability.setSupportedChannelList(SoftApConfiguration.BAND_60GHZ, ALLOWED_60G_CHANS); + when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(true); + when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(true); + when(mResources.getBoolean(R.bool.config_wifiSoftap24ghzSupported)).thenReturn(true); + when(mResources.getBoolean(R.bool.config_wifiSoftap5ghzSupported)).thenReturn(true); + when(mWifiNative.getUsableChannels(anyInt(), anyInt(), anyInt())).thenReturn(null); } /** @@ -282,6 +302,8 @@ public class ApConfigUtilTest extends WifiBaseTest { assertEquals(Arrays.asList(1, 11), ApConfigUtil.convertStringToChannelList("1,6-3,11")); assertEquals(Arrays.asList(1), ApConfigUtil.convertStringToChannelList("1, abc , def - rsv")); + assertNotNull(ApConfigUtil.convertStringToChannelList("")); + assertTrue(ApConfigUtil.convertStringToChannelList("").isEmpty()); } /** @@ -296,8 +318,9 @@ public class ApConfigUtilTest extends WifiBaseTest { int[] allowed2gChannels = {}; when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ)) .thenReturn(allowed2gChannels); - int freq = ApConfigUtil.chooseApChannel(SoftApConfiguration.BAND_2GHZ, mWifiNative, - mCoexManager, mResources); + mCapability.setSupportedChannelList(SoftApConfiguration.BAND_2GHZ, allowed2gChannels); + int freq = ApConfigUtil.chooseApChannel(SoftApConfiguration.BAND_2GHZ, + mCoexManager, mResources, new SoftApCapability(0)); assertEquals(ApConfigUtil.DEFAULT_AP_CHANNEL, ScanResult.convertFrequencyMhzToChannelIfSupported(freq)); } @@ -307,13 +330,14 @@ public class ApConfigUtilTest extends WifiBaseTest { */ @Test public void chooseApChannel2GBandWithAllowedChannels() throws Exception { + when(mWifiNative.isHalStarted()).thenReturn(true); + when(mWifiNative.getUsableChannels(anyInt(), anyInt(), anyInt())).thenReturn(null); 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, - mCoexManager, mResources); + int freq = ApConfigUtil.chooseApChannel(SoftApConfiguration.BAND_2GHZ, + mCoexManager, mResources, mCapability); assertEquals(2462, freq); } @@ -324,11 +348,10 @@ public class ApConfigUtilTest extends WifiBaseTest { 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, mWifiNative, mCoexManager, mResources); + when(mWifiNative.isHalStarted()).thenReturn(true); + when(mWifiNative.getUsableChannels(anyInt(), anyInt(), anyInt())).thenReturn(null); + int freq = ApConfigUtil.chooseApChannel(SoftApConfiguration.BAND_5GHZ, + mCoexManager, mResources, mCapability); assertTrue(ArrayUtils.contains(ALLOWED_5G_FREQS, freq)); } @@ -337,14 +360,13 @@ public class ApConfigUtilTest extends WifiBaseTest { */ @Test public void chooseApChannel60GBandWithAllowedChannels() throws Exception { + when(mWifiNative.isHalStarted()).thenReturn(true); + when(mWifiNative.getUsableChannels(anyInt(), anyInt(), anyInt())).thenReturn(null); when(mResources.getString(R.string.config_wifiSoftap60gChannelList)) .thenReturn("1-2"); - when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_60_GHZ)) - .thenReturn(ALLOWED_60G_FREQS); //ch# 1, 2 - - int freq = ApConfigUtil.chooseApChannel( - SoftApConfiguration.BAND_60GHZ, mWifiNative, mCoexManager, mResources); - assertTrue(ArrayUtils.contains(ALLOWED_60G_FREQS, freq)); + int freq = ApConfigUtil.chooseApChannel(SoftApConfiguration.BAND_60GHZ, + mCoexManager, mResources, mCapability); + assertTrue("freq " + freq, ArrayUtils.contains(ALLOWED_60G_FREQS, freq)); } /** @@ -355,8 +377,9 @@ public class ApConfigUtilTest extends WifiBaseTest { public void chooseApChannel5GBandWithNoAllowedChannels() throws Exception { when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ)) .thenReturn(EMPTY_CHANNEL_LIST); - assertEquals(-1, ApConfigUtil.chooseApChannel(SoftApConfiguration.BAND_5GHZ, mWifiNative, - mCoexManager, mResources)); + mCapability.setSupportedChannelList(SoftApConfiguration.BAND_5GHZ, new int[0]); + assertEquals(-1, ApConfigUtil.chooseApChannel(SoftApConfiguration.BAND_5GHZ, + mCoexManager, mResources, mCapability)); } /** @@ -364,8 +387,8 @@ public class ApConfigUtilTest extends WifiBaseTest { */ @Test public void chooseApChannelWillHighBandPrefer() throws Exception { - when(mResources.getString(R.string.config_wifiSoftap2gChannelList)) - .thenReturn("1, 6, 11"); + when(mWifiNative.isHalStarted()).thenReturn(true); + when(mWifiNative.getUsableChannels(anyInt(), anyInt(), anyInt())).thenReturn(null); when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ)) .thenReturn(ALLOWED_2G_FREQS); // ch#11 when(mResources.getString(R.string.config_wifiSoftap5gChannelList)) @@ -375,8 +398,8 @@ public class ApConfigUtilTest extends WifiBaseTest { int freq = ApConfigUtil.chooseApChannel( SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ, - mWifiNative, mCoexManager, mResources); - assertTrue(ArrayUtils.contains(ALLOWED_5G_FREQS, freq)); + mCoexManager, mResources, mCapability); + assertTrue("freq " + freq, ArrayUtils.contains(ALLOWED_5G_FREQS, freq)); } /** @@ -385,6 +408,8 @@ public class ApConfigUtilTest extends WifiBaseTest { @Test public void chooseApChannelWithUnsafeChannelsPreferSafe() throws Exception { assumeTrue(SdkLevel.isAtLeastS()); + when(mWifiNative.isHalStarted()).thenReturn(true); + when(mWifiNative.getUsableChannels(anyInt(), anyInt(), anyInt())).thenReturn(null); when(mResources.getString(R.string.config_wifiSoftap2gChannelList)) .thenReturn("1, 6, 11"); when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ)) @@ -402,7 +427,7 @@ public class ApConfigUtilTest extends WifiBaseTest { int freq = ApConfigUtil.chooseApChannel( SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ, - mWifiNative, mCoexManager, mResources); + mCoexManager, mResources, mCapability); assertTrue(ArrayUtils.contains(ALLOWED_2G_FREQS, freq)); @@ -411,7 +436,7 @@ public class ApConfigUtilTest extends WifiBaseTest { freq = ApConfigUtil.chooseApChannel( SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ, - mWifiNative, mCoexManager, mResources); + mCoexManager, mResources, mCapability); assertTrue(ArrayUtils.contains(ALLOWED_2G_FREQS, freq)); } @@ -422,6 +447,8 @@ public class ApConfigUtilTest extends WifiBaseTest { @Test public void chooseApChannelWithAllSoftUnsafePreferHighBand() throws Exception { assumeTrue(SdkLevel.isAtLeastS()); + when(mWifiNative.isHalStarted()).thenReturn(true); + when(mWifiNative.getUsableChannels(anyInt(), anyInt(), anyInt())).thenReturn(null); when(mResources.getString(R.string.config_wifiSoftap2gChannelList)) .thenReturn("1, 6, 11"); when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ)) @@ -441,7 +468,7 @@ public class ApConfigUtilTest extends WifiBaseTest { int freq = ApConfigUtil.chooseApChannel( SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ, - mWifiNative, mCoexManager, mResources); + mCoexManager, mResources, mCapability); assertTrue(ArrayUtils.contains(ALLOWED_5G_FREQS, freq)); } @@ -471,7 +498,7 @@ public class ApConfigUtilTest extends WifiBaseTest { int freq = ApConfigUtil.chooseApChannel( SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ, - mWifiNative, mCoexManager, mResources); + mCoexManager, mResources, mCapability); assertEquals(freq, ApConfigUtil.convertChannelToFrequency( ApConfigUtil.DEFAULT_AP_CHANNEL, ApConfigUtil.DEFAULT_AP_BAND)); @@ -587,7 +614,7 @@ public class ApConfigUtilTest extends WifiBaseTest { when(mWifiNative.isHalStarted()).thenReturn(false); assertEquals(ApConfigUtil.SUCCESS, ApConfigUtil.updateApChannelConfig(mWifiNative, mCoexManager, mResources, - TEST_COUNTRY_CODE, configBuilder, configBuilder.build(), false)); + TEST_COUNTRY_CODE, configBuilder, configBuilder.build(), mCapability)); /* Verify default band and channel is used. */ assertEquals(ApConfigUtil.DEFAULT_AP_BAND, configBuilder.build().getBand()); assertEquals(ApConfigUtil.DEFAULT_AP_CHANNEL, configBuilder.build().getChannel()); @@ -604,7 +631,7 @@ public class ApConfigUtilTest extends WifiBaseTest { when(mWifiNative.isHalStarted()).thenReturn(true); assertEquals(ApConfigUtil.ERROR_GENERIC, ApConfigUtil.updateApChannelConfig(mWifiNative, mCoexManager, mResources, null, - configBuilder, configBuilder.build(), false)); + configBuilder, configBuilder.build(), mCapability)); } /** @@ -617,7 +644,7 @@ public class ApConfigUtilTest extends WifiBaseTest { when(mWifiNative.isHalStarted()).thenReturn(true); assertEquals(ApConfigUtil.SUCCESS, ApConfigUtil.updateApChannelConfig(mWifiNative, mCoexManager, mResources, - TEST_COUNTRY_CODE, configBuilder, configBuilder.build(), false)); + TEST_COUNTRY_CODE, configBuilder, configBuilder.build(), mCapability)); assertEquals(SoftApConfiguration.BAND_5GHZ, configBuilder.build().getBand()); assertEquals(36, configBuilder.build().getChannel()); } @@ -633,9 +660,10 @@ public class ApConfigUtilTest extends WifiBaseTest { when(mWifiNative.isHalStarted()).thenReturn(true); when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ)) .thenReturn(EMPTY_CHANNEL_LIST); + mCapability.setSupportedChannelList(SoftApConfiguration.BAND_5GHZ, new int[0]); assertEquals(ApConfigUtil.ERROR_NO_CHANNEL, ApConfigUtil.updateApChannelConfig(mWifiNative, mCoexManager, mResources, - TEST_COUNTRY_CODE, configBuilder, configBuilder.build(), false)); + TEST_COUNTRY_CODE, configBuilder, configBuilder.build(), mCapability)); } /** @@ -646,19 +674,27 @@ public class ApConfigUtilTest extends WifiBaseTest { public void updateApChannelConfigWithAcsDisabledOemConfigured() throws Exception { Builder configBuilder = new SoftApConfiguration.Builder(); configBuilder.setBand(SoftApConfiguration.BAND_5GHZ | SoftApConfiguration.BAND_2GHZ); + when(mContext.getResources()).thenReturn(mResources); when(mResources.getString(R.string.config_wifiSoftap2gChannelList)) .thenReturn("6"); when(mResources.getString(R.string.config_wifiSoftap5gChannelList)) .thenReturn("149, 36-100"); + when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(true); + when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(true); + when(mResources.getBoolean(R.bool.config_wifiSoftap24ghzSupported)).thenReturn(true); + when(mResources.getBoolean(R.bool.config_wifiSoftap5ghzSupported)).thenReturn(true); when(mWifiNative.isHalStarted()).thenReturn(true); + when(mWifiNative.getUsableChannels(anyInt(), anyInt(), anyInt())).thenReturn(null); 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); + mCapability = ApConfigUtil.updateSoftApCapabilityWithAvailableChannelList(mCapability, + mContext, mWifiNative); assertEquals(ApConfigUtil.SUCCESS, ApConfigUtil.updateApChannelConfig(mWifiNative, mCoexManager, mResources, - TEST_COUNTRY_CODE, configBuilder, configBuilder.build(), false)); + TEST_COUNTRY_CODE, configBuilder, configBuilder.build(), + mCapability)); assertEquals(SoftApConfiguration.BAND_5GHZ, configBuilder.build().getBand()); assertEquals(149, configBuilder.build().getChannel()); } @@ -669,13 +705,20 @@ public class ApConfigUtilTest extends WifiBaseTest { */ @Test public void updateApChannelConfigWithAcsEnabled() throws Exception { + final long testFeatures = SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT + | SoftApCapability.SOFTAP_FEATURE_BAND_6G_SUPPORTED + | SoftApCapability.SOFTAP_FEATURE_BAND_60G_SUPPORTED + | SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD; + mCapability = new SoftApCapability(testFeatures); Builder configBuilder = new SoftApConfiguration.Builder(); configBuilder.setBand(SoftApConfiguration.BAND_5GHZ | SoftApConfiguration.BAND_2GHZ); when(mWifiNative.isHalStarted()).thenReturn(true); - when(mWifiNative.getChannelsForBand(anyInt())).thenReturn(new int[0]); + when(mWifiNative.getUsableChannels(anyInt(), anyInt(), anyInt())) + .thenReturn(new ArrayList<>()); assertEquals(ApConfigUtil.SUCCESS, ApConfigUtil.updateApChannelConfig(mWifiNative, mCoexManager, mResources, - TEST_COUNTRY_CODE, configBuilder, configBuilder.build(), true)); + TEST_COUNTRY_CODE, configBuilder, configBuilder.build(), + mCapability)); assertEquals(SoftApConfiguration.BAND_5GHZ | SoftApConfiguration.BAND_2GHZ, configBuilder.build().getBand()); assertEquals(0, configBuilder.build().getChannel()); @@ -698,6 +741,10 @@ public class ApConfigUtilTest extends WifiBaseTest { .thenReturn(false); when(mResources.getBoolean(R.bool.config_wifiSofapClientForceDisconnectSupported)) .thenReturn(true); + when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(false); + when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(false); + when(mResources.getBoolean(R.bool.config_wifiSoftap24ghzSupported)).thenReturn(false); + when(mResources.getBoolean(R.bool.config_wifiSoftap5ghzSupported)).thenReturn(false); when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(true); when(mResources.getBoolean(R.bool.config_wifi60ghzSupport)).thenReturn(true); when(mResources.getBoolean(R.bool.config_wifiSoftap6ghzSupported)).thenReturn(true); @@ -948,6 +995,8 @@ public class ApConfigUtilTest extends WifiBaseTest { @Test public void testGetAvailableChannelFreqsForBandWithDfsChannelWhenDeviceSupported() throws Exception { + when(mWifiNative.isHalStarted()).thenReturn(true); + when(mWifiNative.getUsableChannels(anyInt(), anyInt(), anyInt())).thenReturn(null); when(mResources.getBoolean(R.bool.config_wifiSoftapAcsIncludeDfs)) .thenReturn(true); when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY)) @@ -978,4 +1027,43 @@ public class ApConfigUtilTest extends WifiBaseTest { assertArrayEquals(new int[]{1, 5, 9}, resultList.stream().mapToInt(x->x).toArray()); } + + @Test + public void testGetAvailableChannelFreqsForBandWithHalNotSupported() + throws Exception { + when(mWifiNative.isHalStarted()).thenReturn(true); + when(mWifiNative.isHalSupported()).thenReturn(false); + when(mResources.getBoolean(R.bool.config_wifiSoftapAcsIncludeDfs)) + .thenReturn(false); + when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ)) + .thenReturn(ALLOWED_5G_FREQS); + List<Integer> result = ApConfigUtil.getAvailableChannelFreqsForBand( + SoftApConfiguration.BAND_5GHZ, mWifiNative, mResources, true); + // make sure we try to get available channels from wificond. + verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ); + verify(mWifiNative, never()).getUsableChannels(anyInt(), anyInt(), anyInt()); + for (int freq : result) { + assertTrue(Arrays.stream(ALLOWED_5G_FREQS).anyMatch(n -> n == freq)); + } + } + + @Test + public void testGetAvailableChannelFreqsForBandWithHalgetUsableChannelsNotSupported() + throws Exception { + when(mWifiNative.isHalStarted()).thenReturn(true); + when(mWifiNative.isHalSupported()).thenReturn(true); + when(mResources.getBoolean(R.bool.config_wifiSoftapAcsIncludeDfs)) + .thenReturn(false); + when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ)) + .thenReturn(ALLOWED_5G_FREQS); + when(mWifiNative.getUsableChannels(anyInt(), anyInt(), anyInt())).thenReturn(null); + List<Integer> result = ApConfigUtil.getAvailableChannelFreqsForBand( + SoftApConfiguration.BAND_5GHZ, mWifiNative, mResources, true); + // make sure we try to get available channels from HAL and fallback to wificond. + verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ); + verify(mWifiNative).getUsableChannels(eq(WifiScanner.WIFI_BAND_5_GHZ), anyInt(), anyInt()); + for (int freq : result) { + assertTrue(Arrays.stream(ALLOWED_5G_FREQS).anyMatch(n -> n == freq)); + } + } } |