Snap for 11296156 from d53919e1e4057be97c2702e1b9a4cc79ce97357e to mainline-tzdata5-release
Change-Id: I596d1e0afbfec61ad4bfb7c472ad039aecffeb05
diff --git a/framework/java/android/net/wifi/SoftApCapability.java b/framework/java/android/net/wifi/SoftApCapability.java
index 58a760c..64d7d41 100644
--- a/framework/java/android/net/wifi/SoftApCapability.java
+++ b/framework/java/android/net/wifi/SoftApCapability.java
@@ -234,6 +234,20 @@
}
/**
+ * Set SoftAp Capabilities
+ * @param value Boolean to set value 0 or 1
+ * @param features @HotspotFeatures represents which feature to access
+ * @hide
+ */
+ public void setSupportedFeatures(boolean value, @HotspotFeatures long features) {
+ if (value) {
+ mSupportedFeatures |= features;
+ } else {
+ mSupportedFeatures &= ~features;
+ }
+ }
+
+ /**
* Set supported channel list in target band type.
*
* @param band One of the following band types:
diff --git a/framework/java/android/net/wifi/SoftApConfiguration.java b/framework/java/android/net/wifi/SoftApConfiguration.java
index 3de0735..e52a2d2 100644
--- a/framework/java/android/net/wifi/SoftApConfiguration.java
+++ b/framework/java/android/net/wifi/SoftApConfiguration.java
@@ -1018,14 +1018,6 @@
}
/**
- * @see #isIeee80211beEnabled()
- * @hide
- */
- public boolean isIeee80211beEnabledInternal() {
- return mIeee80211beEnabled;
- }
-
- /**
* Returns whether or not the Soft AP is configured to enable 802.11be.
* This is an indication that if the device support 802.11be AP then to enable or disable
* that feature. If the device does not support 802.11be AP then this flag is ignored.
@@ -1038,7 +1030,7 @@
if (!SdkLevel.isAtLeastT()) {
throw new UnsupportedOperationException();
}
- return isIeee80211beEnabledInternal();
+ return mIeee80211beEnabled;
}
/**
diff --git a/framework/java/android/net/wifi/WifiConfiguration.java b/framework/java/android/net/wifi/WifiConfiguration.java
index ded4ac5..e0c1128 100644
--- a/framework/java/android/net/wifi/WifiConfiguration.java
+++ b/framework/java/android/net/wifi/WifiConfiguration.java
@@ -1192,9 +1192,8 @@
/**
* Four WEP keys. For each of the four values, provide either an ASCII
- * string enclosed in double quotation marks (e.g., {@code "abcdef"}),
- * a string of hex digits (e.g., {@code 0102030405}), or an empty string
- * (e.g., {@code ""}).
+ * string enclosed in double quotation marks (e.g., {@code "abcdef"})
+ * or a string of hex digits (e.g., {@code 0102030405}).
* <p/>
* When the value of one of these keys is read, the actual key is
* not returned, just a "*" if the key has a value, or the null
@@ -2131,7 +2130,8 @@
DISABLED_AUTHENTICATION_PRIVATE_EAP_ERROR,
DISABLED_NETWORK_NOT_FOUND,
DISABLED_CONSECUTIVE_FAILURES,
- DISABLED_UNWANTED_LOW_RSSI})
+ DISABLED_UNWANTED_LOW_RSSI,
+ DISABLED_REPEATED_NUD_FAILURES})
public @interface NetworkSelectionDisableReason {}
// Quality Network disabled reasons
@@ -2188,10 +2188,15 @@
*/
public static final int DISABLED_UNWANTED_LOW_RSSI = 14;
/**
+ * This network is temporarily disabled due to repeated IP reachability failures.
+ * @hide
+ */
+ public static final int DISABLED_REPEATED_NUD_FAILURES = 15;
+ /**
* All other disable reasons should be strictly less than this value.
* @hide
*/
- public static final int NETWORK_SELECTION_DISABLED_MAX = 15;
+ public static final int NETWORK_SELECTION_DISABLED_MAX = 16;
/**
* Get an integer that is equal to the maximum integer value of all the
@@ -2369,6 +2374,10 @@
new DisableReasonInfo("NETWORK_SELECTION_DISABLED_UNWANTED_LOW_RSSI",
1,
30 * 1000));
+ reasons.append(DISABLED_REPEATED_NUD_FAILURES,
+ new DisableReasonInfo("NETWORK_SELECTION_DISABLED_REPEATED_NUD_FAILURES",
+ 1,
+ 15 * 60 * 1000));
return reasons;
}
diff --git a/service/ServiceWifiResources/res/values-eu/strings.xml b/service/ServiceWifiResources/res/values-eu/strings.xml
index c1463a4..c4f0377 100644
--- a/service/ServiceWifiResources/res/values-eu/strings.xml
+++ b/service/ServiceWifiResources/res/values-eu/strings.xml
@@ -40,10 +40,10 @@
<string name="wifi_suggestion_imsi_privacy_exemption_confirmation_content" msgid="9211241189147807136">"Konektatzen bazara, baliteke <xliff:g id="CARRIERNAME">%s</xliff:g> operadorearen wifi-sareek zure SIM txartelarekin lotutako identifikatzaile esklusiboa atzitzea edo partekatzea. Horrela, baliteke zure gailuaren kokapenaren jarraipena egiteko aukera izatea."</string>
<string name="wifi_suggestion_action_allow_imsi_privacy_exemption_confirmation" msgid="2168947026413431603">"Konektatu"</string>
<string name="wifi_suggestion_action_disallow_imsi_privacy_exemption_confirmation" msgid="5156881939985876066">"Ez konektatu"</string>
- <string name="wifi_wakeup_onboarding_title" msgid="3868826648004934540">"Wi‑Fi konexioa automatikoki aktibatuko da"</string>
+ <string name="wifi_wakeup_onboarding_title" msgid="3868826648004934540">"Wifi-konexioa automatikoki aktibatuko da"</string>
<string name="wifi_wakeup_onboarding_subtext" msgid="5705886295837387430">"Gordeta daukazun kalitate handiko sare batetik gertu zaudenean"</string>
<string name="wifi_wakeup_onboarding_action_disable" msgid="6209706680391785825">"Ez aktibatu berriro"</string>
- <string name="wifi_wakeup_enabled_title" msgid="5043486751612595850">"Automatikoki aktibatu da Wi‑Fi konexioa"</string>
+ <string name="wifi_wakeup_enabled_title" msgid="5043486751612595850">"Automatikoki aktibatu da wifi-konexioa"</string>
<string name="wifi_wakeup_enabled_content" msgid="3911262526267025882">"Gordetako sare honetatik gertu zaude: <xliff:g id="NETWORK_SSID">%1$s</xliff:g>"</string>
<string name="wifi_watchdog_network_disabled" msgid="5769226742956006362">"Ezin izan da wifi-sarera konektatu"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="1725243835135539125">" SSIDak Interneteko konexio txarra du."</string>
diff --git a/service/ServiceWifiResources/res/values/config.xml b/service/ServiceWifiResources/res/values/config.xml
index 55910a6..472c191 100644
--- a/service/ServiceWifiResources/res/values/config.xml
+++ b/service/ServiceWifiResources/res/values/config.xml
@@ -370,10 +370,12 @@
<!-- Indicates that AP mode MAC randomization is supported on this device -->
<bool translatable="false" name="config_wifi_ap_mac_randomization_supported">true</bool>
- <!-- Indicates that bridged AP mode is supported on this device -->
+ <!-- Indicates that bridged AP mode is supported on this device provided that
+ the device interface combination allows for it -->
<bool translatable="false" name="config_wifiBridgedSoftApSupported">false</bool>
- <!-- Indicates that STA + bridged AP concurrency mode is supported on this device -->
+ <!-- Indicates that STA + bridged AP concurrency mode is supported on this device provided
+ that the device interface combination allows for it-->
<bool translatable="false" name="config_wifiStaWithBridgedSoftApConcurrencySupported">false</bool>
<!-- Indicates that dynamic country code update in AP mode is supported on this device -->
@@ -599,6 +601,12 @@
<integer translatable="false" name="config_wifiDisableReasonAuthenticationNoSubscriptionDurationMs"> -1 </integer>
<integer translatable="false" name="config_wifiDisableReasonConsecutiveFailuresDurationMs"> 300000 </integer>
+ <!-- Configuration for disabling a network due to repeated NUD failures -->
+ <!-- The number of NUD failures that need to happen to trigger blocking -->
+ <integer translatable="false" name="config_wifiDisableReasonRepeatedNudFailuresThreshold"> 5 </integer>
+ <!-- The NUD failures need to happen within this time window or else the counter will be reset -->
+ <integer translatable="false" name="config_wifiDisableReasonRepeatedNudFailuresWindowMs"> 60000 </integer>
+
<!-- List of constants that indicate the number of consecutive failures per type needed to block a BSSID.
A blocked BSSID will not be considered in network selection and firmware roaming.-->
<integer translatable="false" name="config_wifiBssidBlocklistMonitorApUnableToHandleNewStaThreshold"> 1 </integer>
diff --git a/service/ServiceWifiResources/res/values/overlayable.xml b/service/ServiceWifiResources/res/values/overlayable.xml
index f4d5d08..337c708 100644
--- a/service/ServiceWifiResources/res/values/overlayable.xml
+++ b/service/ServiceWifiResources/res/values/overlayable.xml
@@ -177,6 +177,8 @@
<item type="integer" name="config_wifiDisableReasonByWrongPasswordDurationMs" />
<item type="integer" name="config_wifiDisableReasonAuthenticationNoSubscriptionDurationMs" />
<item type="integer" name="config_wifiDisableReasonConsecutiveFailuresDurationMs" />
+ <item type="integer" name="config_wifiDisableReasonRepeatedNudFailuresThreshold" />
+ <item type="integer" name="config_wifiDisableReasonRepeatedNudFailuresWindowMs" />
<item type="integer" name="config_wifiBssidBlocklistMonitorApUnableToHandleNewStaThreshold" />
<item type="integer" name="config_wifiBssidBlocklistMonitorNetworkValidationFailureThreshold" />
diff --git a/service/java/com/android/server/wifi/ActiveModeWarden.java b/service/java/com/android/server/wifi/ActiveModeWarden.java
index 22bc460..7abf1a5 100644
--- a/service/java/com/android/server/wifi/ActiveModeWarden.java
+++ b/service/java/com/android/server/wifi/ActiveModeWarden.java
@@ -2714,12 +2714,12 @@
additionalFeatureSet |= WifiManager.WIFI_FEATURE_AP_RAND_MAC;
}
- if (ApConfigUtil.isBridgedModeSupported(mContext)) {
+ if (ApConfigUtil.isBridgedModeSupported(mContext, mWifiNative)) {
// The bridged mode requires the kernel network modules support.
// It doesn't relate the vendor HAL, set if overlay enables it.
additionalFeatureSet |= WifiManager.WIFI_FEATURE_BRIDGED_AP;
}
- if (ApConfigUtil.isStaWithBridgedModeSupported(mContext)) {
+ if (ApConfigUtil.isStaWithBridgedModeSupported(mContext, mWifiNative)) {
// The bridged mode requires the kernel network modules support.
// It doesn't relate the vendor HAL, set if overlay enables it.
additionalFeatureSet |= WifiManager.WIFI_FEATURE_STA_BRIDGED_AP;
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index eb12b2e..43db35c 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -357,6 +357,9 @@
// This is is used to track the number of TDLS peers enabled in driver via enableTdls()
private Set<String> mEnabledTdlsPeers = new ArraySet<>();
+ // Tracks the last NUD failure timestamp, and number of failures.
+ private Pair<Long, Integer> mNudFailureCounter = new Pair<>(0L, 0);
+
/**
* Method to clear {@link #mTargetBssid} and reset the current connected network's
* bssid in wpa_supplicant after a roam/connect attempt.
@@ -1938,7 +1941,7 @@
*/
public boolean enableTdls(String remoteMacAddress, boolean enable) {
boolean ret;
- if (!canEnableTdls()) {
+ if (enable && !canEnableTdls()) {
return false;
}
ret = mWifiNative.startTdls(mInterfaceName, remoteMacAddress, enable);
@@ -3454,6 +3457,7 @@
mLastSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
mCurrentConnectionDetectedCaptivePortal = false;
mLastSimBasedConnectionCarrierName = null;
+ mNudFailureCounter = new Pair<>(0L, 0);
checkAbnormalDisconnectionAndTakeBugReport();
mWifiScoreCard.resetConnectionState(mInterfaceName);
updateLayer2Information();
@@ -3967,6 +3971,21 @@
handleIpReachabilityLost(lossReason);
return;
}
+ final long curTime = mClock.getElapsedSinceBootMillis();
+ if (curTime - mNudFailureCounter.first <= mWifiGlobals.getRepeatedNudFailuresWindowMs()) {
+ mNudFailureCounter = new Pair<>(curTime, mNudFailureCounter.second + 1);
+ } else {
+ mNudFailureCounter = new Pair<>(curTime, 1);
+ }
+ if (mNudFailureCounter.second >= mWifiGlobals.getRepeatedNudFailuresThreshold()) {
+ // Disable and disconnect due to repeated NUD failures within limited time window.
+ mWifiConfigManager.updateNetworkSelectionStatus(config.networkId,
+ WifiConfiguration.NetworkSelectionStatus.DISABLED_REPEATED_NUD_FAILURES);
+ handleIpReachabilityLost(lossReason);
+ mNudFailureCounter = new Pair<>(0L, 0);
+ return;
+ }
+
final NetworkAgentConfig naConfig = getNetworkAgentConfigInternal(config);
final NetworkCapabilities nc = getCapabilities(
getConnectedWifiConfigurationInternal(), getConnectedBssidInternal());
@@ -6567,6 +6586,7 @@
}
else {
mRssiMonitor.setShortPollRssiInterval();
+ removeMessages(CMD_RSSI_POLL);
}
break;
}
@@ -8053,6 +8073,7 @@
.withPreDhcpAction()
.withPreconnection()
.withDisplayName(config.SSID)
+ .withCreatorUid(config.creatorUid)
.withLayer2Information(layer2Info)
.withProvisioningTimeoutMs(PROVISIONING_TIMEOUT_FILS_CONNECTION_MS);
if (mContext.getResources().getBoolean(R.bool.config_wifiEnableApfOnNonPrimarySta)
@@ -8106,6 +8127,7 @@
.withNetwork(network)
.withDisplayName(config.SSID)
.withScanResultInfo(scanResultInfo)
+ .withCreatorUid(config.creatorUid)
.withLayer2Information(layer2Info);
} else {
StaticIpConfiguration staticIpConfig = config.getStaticIpConfiguration();
@@ -8113,6 +8135,7 @@
.withStaticConfiguration(staticIpConfig)
.withNetwork(network)
.withDisplayName(config.SSID)
+ .withCreatorUid(config.creatorUid)
.withLayer2Information(layer2Info);
}
if (mContext.getResources().getBoolean(R.bool.config_wifiEnableApfOnNonPrimarySta)
diff --git a/service/java/com/android/server/wifi/HostapdHalAidlImp.java b/service/java/com/android/server/wifi/HostapdHalAidlImp.java
index 5875c41..c34035f 100644
--- a/service/java/com/android/server/wifi/HostapdHalAidlImp.java
+++ b/service/java/com/android/server/wifi/HostapdHalAidlImp.java
@@ -896,11 +896,9 @@
R.bool.config_wifiSoftapHeMuBeamformerSupported);
hwModeParams.enableHeTargetWakeTime = mContext.getResources().getBoolean(
R.bool.config_wifiSoftapHeTwtSupported);
- hwModeParams.enable80211BE = ApConfigUtil.isIeee80211beSupported(mContext);
- //Update 80211be support with the configuration.
- hwModeParams.enable80211BE &= config.isIeee80211beEnabledInternal();
if (SdkLevel.isAtLeastT()) {
+ hwModeParams.enable80211BE = config.isIeee80211beEnabled();
hwModeParams.maximumChannelBandwidth =
mapSoftApInfoBandwidthToHal(config.getMaxChannelBandwidth());
} else {
diff --git a/service/java/com/android/server/wifi/PmkCacheManager.java b/service/java/com/android/server/wifi/PmkCacheManager.java
index a952870..adcd549 100644
--- a/service/java/com/android/server/wifi/PmkCacheManager.java
+++ b/service/java/com/android/server/wifi/PmkCacheManager.java
@@ -22,6 +22,7 @@
import android.util.Log;
import android.util.SparseArray;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
@@ -39,6 +40,10 @@
private final Handler mEventHandler;
private boolean mVerboseLoggingEnabled = false;
+
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
private SparseArray<List<PmkCacheStoreData>> mPmkCacheEntries = new SparseArray<>();
public PmkCacheManager(Clock clock, Handler eventHandler) {
@@ -58,63 +63,71 @@
*/
public boolean add(MacAddress macAddress, int networkId, MacAddress bssid,
long expirationTimeInSec, ArrayList<Byte> serializedEntry) {
- if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return false;
- if (macAddress == null) {
- Log.w(TAG, "Omit PMK cache due to no valid MAC address");
- return false;
- }
- if (null == serializedEntry) {
- Log.w(TAG, "Omit PMK cache due to null entry.");
- return false;
- }
- final long elapseTimeInSecond = mClock.getElapsedSinceBootMillis() / 1000;
- if (elapseTimeInSecond >= expirationTimeInSec) {
- Log.w(TAG, "Omit expired PMK cache.");
- return false;
- }
+ synchronized (mLock) {
+ if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return false;
+ if (macAddress == null) {
+ Log.w(TAG, "Omit PMK cache due to no valid MAC address");
+ return false;
+ }
+ if (null == serializedEntry) {
+ Log.w(TAG, "Omit PMK cache due to null entry.");
+ return false;
+ }
+ final long elapseTimeInSecond = mClock.getElapsedSinceBootMillis() / 1000;
+ if (elapseTimeInSecond >= expirationTimeInSec) {
+ Log.w(TAG, "Omit expired PMK cache.");
+ return false;
+ }
- PmkCacheStoreData newStoreData =
- new PmkCacheStoreData(macAddress, bssid, serializedEntry, expirationTimeInSec);
- List<PmkCacheStoreData> pmkDataList = mPmkCacheEntries.get(networkId);
- if (pmkDataList == null) {
- pmkDataList = new ArrayList<>();
- mPmkCacheEntries.put(networkId, pmkDataList);
- } else {
- if (bssid != null) {
- // Remove the stored PMK cache if the PMK cache is changed for an existing BSSID.
- PmkCacheStoreData existStoreData = pmkDataList.stream()
- .filter(storeData -> Objects.equals(storeData.bssid, bssid))
- .findAny()
- .orElse(null);
- if (null != existStoreData) {
- if (Objects.equals(existStoreData, newStoreData)) {
+ PmkCacheStoreData newStoreData =
+ new PmkCacheStoreData(macAddress, bssid, serializedEntry, expirationTimeInSec);
+ List<PmkCacheStoreData> pmkDataList = mPmkCacheEntries.get(networkId);
+ if (pmkDataList == null) {
+ pmkDataList = new ArrayList<>();
+ mPmkCacheEntries.put(networkId, pmkDataList);
+ } else {
+ PmkCacheStoreData existStoreData = null;
+ if (bssid != null) {
+ // Remove the stored PMK cache if the PMK cache is changed for an existing
+ // BSSID.
+ for (PmkCacheStoreData storeData : pmkDataList) {
+ if (Objects.equals(storeData.bssid, bssid)) {
+ existStoreData = storeData;
+ break;
+ }
+ }
+ if (null != existStoreData) {
+ if (Objects.equals(existStoreData, newStoreData)) {
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "PMK entry exists for the BSSID, skip it.");
+ }
+ return true;
+ }
+ pmkDataList.remove(existStoreData);
+ }
+ } else {
+ for (PmkCacheStoreData storeData : pmkDataList) {
+ if (Objects.equals(storeData, newStoreData)) {
+ existStoreData = storeData;
+ break;
+ }
+ }
+ if (null != existStoreData) {
if (mVerboseLoggingEnabled) {
- Log.d(TAG, "PMK entry exists for the BSSID, skip it.");
+ Log.d(TAG, "PMK entry exists, skip it.");
}
return true;
}
- pmkDataList.remove(existStoreData);
- }
- } else {
- PmkCacheStoreData existStoreData = pmkDataList.stream()
- .filter(storeData -> Objects.equals(storeData, newStoreData))
- .findAny()
- .orElse(null);
- if (null != existStoreData) {
- if (mVerboseLoggingEnabled) {
- Log.d(TAG, "PMK entry exists, skip it.");
- }
- return true;
}
}
- }
- pmkDataList.add(newStoreData);
- if (mVerboseLoggingEnabled) {
- Log.d(TAG, "Network " + networkId + " PmkCache Count: " + pmkDataList.size());
+ pmkDataList.add(newStoreData);
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "Network " + networkId + " PmkCache Count: " + pmkDataList.size());
+ }
+ updatePmkCacheExpiration();
+ return true;
}
- updatePmkCacheExpiration();
- return true;
}
/**
@@ -124,12 +137,14 @@
* @return true when PMK caches are removed; otherwise, false.
*/
public boolean remove(int networkId) {
- if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return false;
- if (!mPmkCacheEntries.contains(networkId)) return false;
+ synchronized (mLock) {
+ if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return false;
+ if (!mPmkCacheEntries.contains(networkId)) return false;
- mPmkCacheEntries.remove(networkId);
- updatePmkCacheExpiration();
- return true;
+ mPmkCacheEntries.remove(networkId);
+ updatePmkCacheExpiration();
+ return true;
+ }
}
/**
@@ -142,16 +157,18 @@
*/
public boolean remove(int networkId, MacAddress curMacAddress) {
- if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return false;
- List<PmkCacheStoreData> pmkDataList = mPmkCacheEntries.get(networkId);
- if (null == pmkDataList) return false;
+ synchronized (mLock) {
+ if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return false;
+ List<PmkCacheStoreData> pmkDataList = mPmkCacheEntries.get(networkId);
+ if (null == pmkDataList) return false;
- pmkDataList.removeIf(pmkData -> !Objects.equals(curMacAddress, pmkData.macAddress));
+ pmkDataList.removeIf(pmkData -> !Objects.equals(curMacAddress, pmkData.macAddress));
- if (pmkDataList.size() == 0) {
- remove(networkId);
+ if (pmkDataList.size() == 0) {
+ remove(networkId);
+ }
+ return true;
}
- return true;
}
/**
@@ -162,18 +179,20 @@
* If none of PMK cache is associated with the network ID, return null.
*/
public List<ArrayList<Byte>> get(int networkId) {
- List<PmkCacheStoreData> pmkDataList = mPmkCacheEntries.get(networkId);
- if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return null;
- if (null == pmkDataList) return null;
+ synchronized (mLock) {
+ List<PmkCacheStoreData> pmkDataList = mPmkCacheEntries.get(networkId);
+ if (WifiConfiguration.INVALID_NETWORK_ID == networkId) return null;
+ if (null == pmkDataList) return null;
- final long elapseTimeInSecond = mClock.getElapsedSinceBootMillis() / 1000;
- List<ArrayList<Byte>> dataList = new ArrayList<>();
- for (PmkCacheStoreData pmkData: pmkDataList) {
- if (pmkData.isValid(elapseTimeInSecond)) {
- dataList.add(pmkData.data);
+ final long elapseTimeInSecond = mClock.getElapsedSinceBootMillis() / 1000;
+ List<ArrayList<Byte>> dataList = new ArrayList<>();
+ for (PmkCacheStoreData pmkData : pmkDataList) {
+ if (pmkData.isValid(elapseTimeInSecond)) {
+ dataList.add(pmkData.data);
+ }
}
+ return dataList;
}
- return dataList;
}
/**
@@ -185,46 +204,48 @@
@VisibleForTesting
void updatePmkCacheExpiration() {
- mEventHandler.removeCallbacksAndMessages(PMK_CACHE_EXPIRATION_ALARM_TAG);
+ synchronized (mLock) {
+ mEventHandler.removeCallbacksAndMessages(PMK_CACHE_EXPIRATION_ALARM_TAG);
- long elapseTimeInSecond = mClock.getElapsedSinceBootMillis() / 1000;
- long nextUpdateTimeInSecond = Long.MAX_VALUE;
- if (mVerboseLoggingEnabled) {
- Log.d(TAG, "Update PMK cache expiration at " + elapseTimeInSecond);
- }
-
- List<Integer> emptyStoreDataList = new ArrayList<>();
- for (int i = 0; i < mPmkCacheEntries.size(); i++) {
- int networkId = mPmkCacheEntries.keyAt(i);
- List<PmkCacheStoreData> list = mPmkCacheEntries.get(networkId);
- list.removeIf(pmkData -> !pmkData.isValid(elapseTimeInSecond));
- if (list.size() == 0) {
- emptyStoreDataList.add(networkId);
- continue;
+ long elapseTimeInSecond = mClock.getElapsedSinceBootMillis() / 1000;
+ long nextUpdateTimeInSecond = Long.MAX_VALUE;
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "Update PMK cache expiration at " + elapseTimeInSecond);
}
- for (PmkCacheStoreData pmkData: list) {
- if (nextUpdateTimeInSecond > pmkData.expirationTimeInSec) {
- nextUpdateTimeInSecond = pmkData.expirationTimeInSec;
+
+ List<Integer> emptyStoreDataList = new ArrayList<>();
+ for (int i = 0; i < mPmkCacheEntries.size(); i++) {
+ int networkId = mPmkCacheEntries.keyAt(i);
+ List<PmkCacheStoreData> list = mPmkCacheEntries.get(networkId);
+ list.removeIf(pmkData -> !pmkData.isValid(elapseTimeInSecond));
+ if (list.size() == 0) {
+ emptyStoreDataList.add(networkId);
+ continue;
+ }
+ for (PmkCacheStoreData pmkData : list) {
+ if (nextUpdateTimeInSecond > pmkData.expirationTimeInSec) {
+ nextUpdateTimeInSecond = pmkData.expirationTimeInSec;
+ }
}
}
- }
- emptyStoreDataList.forEach(networkId -> mPmkCacheEntries.remove(networkId));
+ emptyStoreDataList.forEach(networkId -> mPmkCacheEntries.remove(networkId));
- // No need to arrange next update since there is no valid PMK in the cache.
- if (nextUpdateTimeInSecond == Long.MAX_VALUE) {
- return;
- }
+ // No need to arrange next update since there is no valid PMK in the cache.
+ if (nextUpdateTimeInSecond == Long.MAX_VALUE) {
+ return;
+ }
- if (mVerboseLoggingEnabled) {
- Log.d(TAG, "PMK cache next expiration time: " + nextUpdateTimeInSecond);
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "PMK cache next expiration time: " + nextUpdateTimeInSecond);
+ }
+ long delayedTimeInMs = (nextUpdateTimeInSecond - elapseTimeInSecond) * 1000;
+ mEventHandler.postDelayed(
+ () -> {
+ updatePmkCacheExpiration();
+ },
+ PMK_CACHE_EXPIRATION_ALARM_TAG,
+ (delayedTimeInMs > 0) ? delayedTimeInMs : 0);
}
- long delayedTimeInMs = (nextUpdateTimeInSecond - elapseTimeInSecond) * 1000;
- mEventHandler.postDelayed(
- () -> {
- updatePmkCacheExpiration();
- },
- PMK_CACHE_EXPIRATION_ALARM_TAG,
- (delayedTimeInMs > 0) ? delayedTimeInMs : 0);
}
private static class PmkCacheStoreData {
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index acaa650..fbe50bc 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -1175,7 +1175,8 @@
// Checking STA status only when device supports STA + AP concurrency
// since STA would be dropped when device doesn't support it.
if (cmms.size() != 0 && mWifiNative.isStaApConcurrencySupported()) {
- if (ApConfigUtil.isStaWithBridgedModeSupported(mContext)) {
+ if (ApConfigUtil.isStaWithBridgedModeSupported(mContext,
+ mWifiNative)) {
for (ClientModeManager cmm
: mActiveModeWarden.getClientModeManagers()) {
WifiInfo wifiConnectedInfo = cmm.getConnectionInfo();
@@ -1284,11 +1285,15 @@
break;
}
- // Only check if it's possible to create single AP, since a DBS request
- // already falls back to single AP if we can't create DBS.
- if (!mWifiNative.isItPossibleToCreateApIface(mRequestorWs)) {
- handleStartSoftApFailure(START_RESULT_FAILURE_INTERFACE_CONFLICT);
- break;
+ if (SdkLevel.isAtLeastT()
+ && mCurrentSoftApConfiguration.isIeee80211beEnabled()
+ && !mCurrentSoftApCapability.areFeaturesSupported(
+ SoftApCapability.SOFTAP_FEATURE_IEEE80211_BE)) {
+ Log.d(getTag(), "11BE is not supported, removing from configuration");
+ mCurrentSoftApConfiguration = new SoftApConfiguration
+ .Builder(mCurrentSoftApConfiguration)
+ .setIeee80211beEnabled(false)
+ .build();
}
mApInterfaceName = mWifiNative.setupInterfaceForSoftApMode(
mWifiNativeInterfaceCallback, mRequestorWs,
@@ -1296,7 +1301,13 @@
SoftApManager.this);
if (TextUtils.isEmpty(mApInterfaceName)) {
Log.e(getTag(), "setup failure when creating ap interface.");
- handleStartSoftApFailure(START_RESULT_FAILURE_CREATE_INTERFACE);
+ // Only check if it's possible to create single AP, since a DBS request
+ // already falls back to single AP if we can't create DBS.
+ if (!mWifiNative.isItPossibleToCreateApIface(mRequestorWs)) {
+ handleStartSoftApFailure(START_RESULT_FAILURE_INTERFACE_CONFLICT);
+ } else {
+ handleStartSoftApFailure(START_RESULT_FAILURE_CREATE_INTERFACE);
+ }
break;
}
mSoftApNotifier.dismissSoftApShutdownTimeoutExpiredNotification();
@@ -2223,9 +2234,9 @@
getRole(),
band1,
band2,
- ApConfigUtil.isBridgedModeSupported(mContext),
+ ApConfigUtil.isBridgedModeSupported(mContext, mWifiNative),
mWifiNative.isStaApConcurrencySupported(),
- ApConfigUtil.isStaWithBridgedModeSupported(mContext),
+ ApConfigUtil.isStaWithBridgedModeSupported(mContext, mWifiNative),
getCurrentStaFreqMhz(),
securityType);
}
@@ -2250,7 +2261,7 @@
band,
isBridgedMode(),
mWifiNative.isStaApConcurrencySupported(),
- ApConfigUtil.isStaWithBridgedModeSupported(mContext),
+ ApConfigUtil.isStaWithBridgedModeSupported(mContext, mWifiNative),
getCurrentStaFreqMhz(),
mDefaultShutdownTimeoutMillis > 0,
-1,
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java
index af82aa0..15cf9a9 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java
@@ -329,11 +329,17 @@
WifiConfiguration curConfiguration =
mStaIfaceHal.getCurrentNetworkLocalConfig(mIfaceName);
if (curConfiguration != null) {
+ // In case of PSK networks the disconnection event in the middle of key exchange
+ // happens due to PSK mismatch. But filter out the de-authentication/disassociation
+ // frame from AP with known reason codes which are not related to PSK mismatch from
+ // reporting wrong password error.
if (mStateBeforeDisconnect == StaIfaceCallbackState.FOURWAY_HANDSHAKE
&& (WifiConfigurationUtil.isConfigForPskNetwork(curConfiguration)
- || WifiConfigurationUtil.isConfigForWapiPskNetwork(curConfiguration))
- && (!locallyGenerated || reasonCode
- != StaIfaceReasonCode.IE_IN_4WAY_DIFFERS)) {
+ || WifiConfigurationUtil.isConfigForWapiPskNetwork(
+ curConfiguration))
+ && (!locallyGenerated
+ || (reasonCode != StaIfaceReasonCode.IE_IN_4WAY_DIFFERS
+ && reasonCode != StaIfaceReasonCode.DISASSOC_AP_BUSY))) {
mWifiMonitor.broadcastAuthenticationFailureEvent(
mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1,
mCurrentSsid, MacAddress.fromBytes(bssid));
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java
index 3673d7b..3a50f66 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java
@@ -287,10 +287,17 @@
WifiConfiguration curConfiguration =
mStaIfaceHal.getCurrentNetworkLocalConfig(mIfaceName);
if (curConfiguration != null) {
+ // In case of PSK networks the disconnection event in the middle of key exchange
+ // happens due to PSK mismatch. But filter out the de-authentication/disassociation
+ // frame from AP with known reason codes which are not related to PSK mismatch from
+ // reporting wrong password error.
if (mStateBeforeDisconnect == State.FOURWAY_HANDSHAKE
&& (WifiConfigurationUtil.isConfigForPskNetwork(curConfiguration)
- || WifiConfigurationUtil.isConfigForWapiPskNetwork(curConfiguration))
- && (!locallyGenerated || reasonCode != ReasonCode.IE_IN_4WAY_DIFFERS)) {
+ || WifiConfigurationUtil.isConfigForWapiPskNetwork(
+ curConfiguration))
+ && (!locallyGenerated
+ || (reasonCode != ReasonCode.IE_IN_4WAY_DIFFERS
+ && reasonCode != ReasonCode.DISASSOC_AP_BUSY))) {
mWifiMonitor.broadcastAuthenticationFailureEvent(
mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1,
mCurrentSsid, MacAddress.fromBytes(bssid));
diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java
index 33d43f0..f17c6db 100644
--- a/service/java/com/android/server/wifi/WifiApConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiApConfigStore.java
@@ -85,6 +85,7 @@
private final MacAddressUtil mMacAddressUtil;
private final WifiConfigManager mWifiConfigManager;
private final ActiveModeWarden mActiveModeWarden;
+ private final WifiNative mWifiNative;
private boolean mHasNewDataToSerialize = false;
private boolean mForceApChannel = false;
private int mForcedApBand;
@@ -135,7 +136,7 @@
mWifiConfigManager = wifiConfigManager;
mActiveModeWarden = activeModeWarden;
mWifiMetrics = wifiMetrics;
-
+ mWifiNative = wifiInjector.getWifiNative();
// Register store data listener
wifiConfigStore.registerStoreData(
wifiInjector.makeSoftApStoreData(new SoftApStoreDataSource()));
@@ -215,7 +216,7 @@
public synchronized SoftApConfiguration upgradeSoftApConfiguration(
@NonNull SoftApConfiguration config) {
SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(config);
- if (SdkLevel.isAtLeastS() && ApConfigUtil.isBridgedModeSupported(mContext)
+ if (SdkLevel.isAtLeastS() && ApConfigUtil.isBridgedModeSupported(mContext, mWifiNative)
&& config.getBands().length == 1 && mContext.getResources().getBoolean(
R.bool.config_wifiSoftapAutoUpgradeToBridgedConfigWhenSupported)) {
int[] dual_bands = new int[] {
@@ -290,7 +291,7 @@
}
if (SdkLevel.isAtLeastS() && config.getBands().length > 1) {
- if (!ApConfigUtil.isBridgedModeSupported(mContext)
+ if (!ApConfigUtil.isBridgedModeSupported(mContext, mWifiNative)
|| !isBandsSupported(config.getBands(), mContext)) {
int newSingleApBand = 0;
for (int targetBand : config.getBands()) {
@@ -418,7 +419,7 @@
// It is new overlay configuration, it should always false in R. Add SdkLevel.isAtLeastS for
// lint check
- if (ApConfigUtil.isBridgedModeSupported(mContext)) {
+ if (ApConfigUtil.isBridgedModeSupported(mContext, mWifiNative)) {
if (SdkLevel.isAtLeastS()) {
int[] dual_bands = new int[] {
SoftApConfiguration.BAND_2GHZ,
@@ -589,11 +590,12 @@
*
* @param apConfig {@link SoftApConfiguration} to use for softap mode
* @param isPrivileged indicate the caller can pass some fields check or not
+ * @param wifiNative to use native API to get iface combinations.
* @return boolean true if the provided config meets the minimum set of details, false
* otherwise.
*/
static boolean validateApWifiConfiguration(@NonNull SoftApConfiguration apConfig,
- boolean isPrivileged, Context context) {
+ boolean isPrivileged, Context context, WifiNative wifiNative) {
// first check the SSID
WifiSsid ssid = apConfig.getWifiSsid();
if (ssid == null || ssid.getBytes().length == 0) {
@@ -670,7 +672,7 @@
if (SdkLevel.isAtLeastT()
&& authType == SECURITY_TYPE_WPA3_OWE_TRANSITION) {
- if (!ApConfigUtil.isBridgedModeSupported(context)) {
+ if (!ApConfigUtil.isBridgedModeSupported(context, wifiNative)) {
Log.d(TAG, "softap owe transition needs bridge mode support");
return false;
} else if (apConfig.getBands().length > 1) {
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index c2c4800..93263ff 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -1106,6 +1106,20 @@
}
}
+ private static @WifiEnterpriseConfig.TofuConnectionState int mergeTofuConnectionState(
+ WifiConfiguration internalConfig, WifiConfiguration externalConfig) {
+ // Prioritize the internal config if it has reached a post-connection state.
+ int internalTofuState = internalConfig.enterpriseConfig.getTofuConnectionState();
+ if (internalTofuState == WifiEnterpriseConfig.TOFU_STATE_CONFIGURE_ROOT_CA
+ || internalTofuState == WifiEnterpriseConfig.TOFU_STATE_CERT_PINNING) {
+ return internalTofuState;
+ }
+ // Else assign a pre-connection state based on the latest external config.
+ return externalConfig.enterpriseConfig.isTrustOnFirstUseEnabled()
+ ? WifiEnterpriseConfig.TOFU_STATE_ENABLED_PRE_CONNECTION
+ : WifiEnterpriseConfig.TOFU_STATE_NOT_ENABLED;
+ }
+
/**
* Copy over public elements from an external WifiConfiguration object to the internal
* configuration object if element has been set in the provided external WifiConfiguration.
@@ -1199,10 +1213,18 @@
}
internalConfig.allowAutojoin = externalConfig.allowAutojoin;
- // Copy over the |WifiEnterpriseConfig| parameters if set.
+ // Copy over the |WifiEnterpriseConfig| parameters if set. For fields which should
+ // only be set by the framework, cache the internal config's value and restore.
if (externalConfig.enterpriseConfig != null) {
+ boolean userApproveNoCaCertInternal =
+ internalConfig.enterpriseConfig.isUserApproveNoCaCert();
+ int tofuDialogStateInternal = internalConfig.enterpriseConfig.getTofuDialogState();
+ int tofuConnectionState = mergeTofuConnectionState(internalConfig, externalConfig);
internalConfig.enterpriseConfig.copyFromExternal(
externalConfig.enterpriseConfig, PASSWORD_MASK);
+ internalConfig.enterpriseConfig.setUserApproveNoCaCert(userApproveNoCaCertInternal);
+ internalConfig.enterpriseConfig.setTofuDialogState(tofuDialogStateInternal);
+ internalConfig.enterpriseConfig.setTofuConnectionState(tofuConnectionState);
}
// Copy over any metered information.
diff --git a/service/java/com/android/server/wifi/WifiDialogManager.java b/service/java/com/android/server/wifi/WifiDialogManager.java
index 6c35e60..db5d93d 100644
--- a/service/java/com/android/server/wifi/WifiDialogManager.java
+++ b/service/java/com/android/server/wifi/WifiDialogManager.java
@@ -89,14 +89,7 @@
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Received action: " + action);
}
- if (Intent.ACTION_SCREEN_OFF.equals(action)) {
- // Change all window types to TYPE_APPLICATION_OVERLAY to prevent the dialogs
- // from appearing over the lock screen when the screen turns on again.
- for (LegacySimpleDialogHandle dialogHandle : mActiveLegacySimpleDialogs) {
- dialogHandle.changeWindowType(
- WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
- }
- } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
+ if (Intent.ACTION_USER_PRESENT.equals(action)) {
// Change all window types to TYPE_KEYGUARD_DIALOG to show the dialogs over the
// QuickSettings after the screen is unlocked.
for (LegacySimpleDialogHandle dialogHandle : mActiveLegacySimpleDialogs) {
@@ -134,12 +127,11 @@
public WifiDialogManager(
@NonNull WifiContext context,
@NonNull WifiThreadRunner wifiThreadRunner,
- @NonNull FrameworkFacade frameworkFacade) {
+ @NonNull FrameworkFacade frameworkFacade, WifiInjector wifiInjector) {
mContext = context;
mWifiThreadRunner = wifiThreadRunner;
mFrameworkFacade = frameworkFacade;
IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_USER_PRESENT);
intentFilter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
int flags = 0;
@@ -147,6 +139,34 @@
flags = Context.RECEIVER_EXPORTED;
}
mContext.registerReceiver(mBroadcastReceiver, intentFilter, flags);
+ wifiInjector.getWifiDeviceStateChangeManager()
+ .registerStateChangeCallback(
+ new WifiDeviceStateChangeManager.StateChangeCallback() {
+ @Override
+ public void onScreenStateChanged(boolean screenOn) {
+ handleScreenStateChanged(screenOn);
+ }
+ });
+ }
+
+ private void handleScreenStateChanged(boolean screenOn) {
+ // Change all window types to TYPE_APPLICATION_OVERLAY to
+ // prevent the dialogs from appearing over the lock screen when
+ // the screen turns on again.
+ if (!screenOn) {
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "onScreenStateChanged: screen off");
+ }
+ // Change all window types to TYPE_APPLICATION_OVERLAY to
+ // prevent the dialogs from appearing over the lock screen when
+ // the screen turns on again.
+ for (LegacySimpleDialogHandle dialogHandle :
+ mActiveLegacySimpleDialogs) {
+ dialogHandle.changeWindowType(
+ WindowManager.LayoutParams
+ .TYPE_APPLICATION_OVERLAY);
+ }
+ }
}
/**
diff --git a/service/java/com/android/server/wifi/WifiGlobals.java b/service/java/com/android/server/wifi/WifiGlobals.java
index 232cf8b..1fa95d0 100644
--- a/service/java/com/android/server/wifi/WifiGlobals.java
+++ b/service/java/com/android/server/wifi/WifiGlobals.java
@@ -69,6 +69,8 @@
private final int mClientRssiMonitorHysteresisDb;
private boolean mDisableFirmwareRoamingInIdleMode = false;
private final boolean mIsSupportMultiInternetDual5G;
+ private final int mRepeatedNudFailuresThreshold;
+ private final int mRepeatedNudFailuresWindowMs;
private final boolean mAdjustPollRssiIntervalEnabled;
private final boolean mWifiInterfaceAddedSelfRecoveryEnabled;
private final int mNetworkNotFoundEventThreshold;
@@ -131,6 +133,10 @@
.getBoolean(R.bool.config_wifiDisableFirmwareRoamingInIdleMode);
mIsSupportMultiInternetDual5G = mContext.getResources().getBoolean(
R.bool.config_wifiAllowMultiInternetConnectDual5GFrequency);
+ mRepeatedNudFailuresThreshold = mContext.getResources()
+ .getInteger(R.integer.config_wifiDisableReasonRepeatedNudFailuresThreshold);
+ mRepeatedNudFailuresWindowMs = mContext.getResources()
+ .getInteger(R.integer.config_wifiDisableReasonRepeatedNudFailuresWindowMs);
mWifiInterfaceAddedSelfRecoveryEnabled = mContext.getResources().getBoolean(
R.bool.config_wifiInterfaceAddedSelfRecoveryEnabled);
mDisableUnwantedNetworkOnLowRssi = mContext.getResources().getBoolean(
@@ -306,6 +312,20 @@
}
/**
+ * Get number of repeated NUD failures needed to disable a network.
+ */
+ public int getRepeatedNudFailuresThreshold() {
+ return mRepeatedNudFailuresThreshold;
+ }
+
+ /**
+ * Get the time window in millis to count for repeated NUD failures.
+ */
+ public int getRepeatedNudFailuresWindowMs() {
+ return mRepeatedNudFailuresWindowMs;
+ }
+
+ /**
* Helper method to check if the device may not connect to the configuration
* due to deprecated security type
*/
@@ -534,6 +554,8 @@
pw.println("mIsWepDeprecated=" + mIsWepDeprecated);
pw.println("mIsWpaPersonalDeprecated=" + mIsWpaPersonalDeprecated);
pw.println("mDisableFirmwareRoamingInIdleMode=" + mDisableFirmwareRoamingInIdleMode);
+ pw.println("mRepeatedNudFailuresThreshold=" + mRepeatedNudFailuresThreshold);
+ pw.println("mRepeatedNudFailuresWindowMs=" + mRepeatedNudFailuresWindowMs);
pw.println("mCarrierSpecificEapFailureConfigMapPerCarrierId mapping below:");
for (int i = 0; i < mCarrierSpecificEapFailureConfigMapPerCarrierId.size(); i++) {
int carrierId = mCarrierSpecificEapFailureConfigMapPerCarrierId.keyAt(i);
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index dc7a639..22f962c 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -309,7 +309,8 @@
mSoftApBackupRestore = new SoftApBackupRestore(mContext, mSettingsMigrationDataHolder);
mWifiStateTracker = new WifiStateTracker(mBatteryStats);
mWifiThreadRunner = new WifiThreadRunner(wifiHandler);
- mWifiDialogManager = new WifiDialogManager(mContext, mWifiThreadRunner, mFrameworkFacade);
+ mWifiDialogManager = new WifiDialogManager(mContext, mWifiThreadRunner, mFrameworkFacade,
+ this);
mSsidTranslator = new SsidTranslator(mContext, wifiHandler);
mWifiP2pServiceHandlerThread = new HandlerThread("WifiP2pService");
mWifiP2pServiceHandlerThread.start();
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index d16f763..0908ff3 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -4557,6 +4557,15 @@
if (iface.phyCapabilities == null) {
iface.phyCapabilities = mWifiCondManager.getDeviceWiphyCapabilities(ifaceName);
}
+ if (iface.phyCapabilities != null
+ && iface.phyCapabilities.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11BE)
+ != mWifiInjector.getSettingsConfigStore()
+ .get(WifiSettingsConfigStore.WIFI_WIPHY_11BE_SUPPORTED)) {
+ mWifiInjector.getSettingsConfigStore().put(
+ WifiSettingsConfigStore.WIFI_WIPHY_11BE_SUPPORTED,
+ iface.phyCapabilities.isWifiStandardSupported(
+ ScanResult.WIFI_STANDARD_11BE));
+ }
return iface.phyCapabilities;
}
}
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 31fb17c..a22a5a8 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -1623,7 +1623,7 @@
int uid = Binder.getCallingUid();
boolean privileged = isSettingsOrSuw(Binder.getCallingPid(), uid);
return WifiApConfigStore.validateApWifiConfiguration(
- config, privileged, mContext);
+ config, privileged, mContext, mWifiNative);
}
/**
@@ -1782,7 +1782,7 @@
SoftApConfiguration softApConfig = apConfig.getSoftApConfiguration();
if (softApConfig != null
&& (!WifiApConfigStore.validateApWifiConfiguration(
- softApConfig, privileged, mContext))) {
+ softApConfig, privileged, mContext, mWifiNative))) {
Log.e(TAG, "Invalid SoftApConfiguration");
return false;
}
@@ -2047,6 +2047,8 @@
synchronized (mLock) {
if (mSoftApCapability == null) {
mSoftApCapability = ApConfigUtil.updateCapabilityFromResource(mContext);
+ mSoftApCapability = ApConfigUtil.updateCapabilityFromConfigStore(
+ mSoftApCapability, mWifiInjector.getSettingsConfigStore());
// Default country code
mSoftApCapability = updateSoftApCapabilityWithAvailableChannelList(
mSoftApCapability, mCountryCode.getCountryCode());
@@ -2900,7 +2902,7 @@
SoftApConfiguration softApConfig = ApConfigUtil.fromWifiConfiguration(wifiConfig);
if (softApConfig == null) return false;
if (!WifiApConfigStore.validateApWifiConfiguration(
- softApConfig, false, mContext)) {
+ softApConfig, false, mContext, mWifiNative)) {
Log.e(TAG, "Invalid WifiConfiguration");
return false;
}
@@ -2928,7 +2930,8 @@
}
mLog.info("setSoftApConfiguration uid=%").c(uid).flush();
if (softApConfig == null) return false;
- if (WifiApConfigStore.validateApWifiConfiguration(softApConfig, privileged, mContext)) {
+ if (WifiApConfigStore.validateApWifiConfiguration(softApConfig, privileged, mContext,
+ mWifiNative)) {
mWifiApConfigStore.setApConfiguration(softApConfig);
// Send the message for AP config update after the save is done.
mActiveModeWarden.updateSoftApConfiguration(softApConfig);
@@ -3079,7 +3082,11 @@
}
@Override
- public void getWifiActivityEnergyInfoAsync(IOnWifiActivityEnergyInfoListener listener) {
+ public void getWifiActivityEnergyInfoAsync(@NonNull IOnWifiActivityEnergyInfoListener
+ listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener should not be null");
+ }
enforceAccessPermission();
if (mVerboseLoggingEnabled) {
mLog.info("getWifiActivityEnergyInfoAsync uid=%")
@@ -5334,6 +5341,8 @@
pw.println();
mWifiConfigManager.dump(fd, pw, args);
pw.println();
+ pw.println("WifiApConfigStore config: " + mWifiApConfigStore.getApConfiguration());
+ pw.println();
mPasspointManager.dump(pw);
pw.println();
mWifiInjector.getWifiDiagnostics().captureBugReportData(
diff --git a/service/java/com/android/server/wifi/WifiSettingsConfigStore.java b/service/java/com/android/server/wifi/WifiSettingsConfigStore.java
index 27ae1f8..73756c9 100644
--- a/service/java/com/android/server/wifi/WifiSettingsConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiSettingsConfigStore.java
@@ -182,6 +182,12 @@
public static final Key<Integer> SUPPLICANT_HAL_AIDL_SERVICE_VERSION =
new Key<>("supplicant_hal_aidl_service_version", -1);
+ /**
+ * Store wiphy capability for 11be support.
+ */
+ public static final Key<Boolean> WIFI_WIPHY_11BE_SUPPORTED =
+ new Key<>("wifi_wiphy_11be_supported", true);
+
/******** Wifi shared pref keys ***************/
private final Context mContext;
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
index 7375927..96ed2d3 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
@@ -2190,6 +2190,123 @@
setInitialState(mWaitState);
}
+ @Override
+ protected String getWhatToString(int what) {
+ return switch (what) {
+ case COMMAND_TYPE_CONNECT -> "COMMAND_TYPE_CONNECT";
+ case COMMAND_TYPE_DISCONNECT -> "COMMAND_TYPE_DISCONNECT";
+ case COMMAND_TYPE_TERMINATE_SESSION -> "COMMAND_TYPE_TERMINATE_SESSION";
+ case COMMAND_TYPE_PUBLISH -> "COMMAND_TYPE_PUBLISH";
+ case COMMAND_TYPE_UPDATE_PUBLISH -> "COMMAND_TYPE_UPDATE_PUBLISH";
+ case COMMAND_TYPE_SUBSCRIBE -> "COMMAND_TYPE_SUBSCRIBE";
+ case COMMAND_TYPE_UPDATE_SUBSCRIBE -> "COMMAND_TYPE_UPDATE_SUBSCRIBE";
+ case COMMAND_TYPE_ENQUEUE_SEND_MESSAGE -> "COMMAND_TYPE_ENQUEUE_SEND_MESSAGE";
+ case COMMAND_TYPE_ENABLE_USAGE -> "COMMAND_TYPE_ENABLE_USAGE";
+ case COMMAND_TYPE_DISABLE_USAGE -> "COMMAND_TYPE_DISABLE_USAGE";
+ case COMMAND_TYPE_GET_CAPABILITIES -> "COMMAND_TYPE_GET_CAPABILITIES";
+ case COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES
+ -> "COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES";
+ case COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE
+ -> "COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE";
+ case COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE
+ -> "COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE";
+ case COMMAND_TYPE_INITIATE_DATA_PATH_SETUP
+ -> "COMMAND_TYPE_INITIATE_DATA_PATH_SETUP";
+ case COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST
+ -> "COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST";
+ case COMMAND_TYPE_END_DATA_PATH -> "COMMAND_TYPE_END_DATA_PATH";
+ case COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE -> "COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE";
+ case COMMAND_TYPE_RECONFIGURE -> "COMMAND_TYPE_RECONFIGURE";
+ case COMMAND_TYPE_DELAYED_INITIALIZATION -> "COMMAND_TYPE_DELAYED_INITIALIZATION";
+ case COMMAND_TYPE_GET_AWARE -> "COMMAND_TYPE_GET_AWARE";
+ case COMMAND_TYPE_RELEASE_AWARE -> "COMMAND_TYPE_RELEASE_AWARE";
+ case COMMAND_TYPE_DISABLE -> "COMMAND_TYPE_DISABLE";
+ case COMMAND_TYPE_INITIATE_PAIRING_REQUEST
+ -> "COMMAND_TYPE_INITIATE_PAIRING_REQUEST";
+ case COMMAND_TYPE_RESPONSE_PAIRING_REQUEST
+ -> "COMMAND_TYPE_RESPONSE_PAIRING_REQUEST";
+ case COMMAND_TYPE_INITIATE_BOOTSTRAPPING_REQUEST
+ -> "COMMAND_TYPE_INITIATE_BOOTSTRAPPING_REQUEST";
+ case COMMAND_TYPE_RESPONSE_BOOTSTRAPPING_REQUEST
+ -> "COMMAND_TYPE_RESPONSE_BOOTSTRAPPING_REQUEST";
+ case COMMAND_TYPE_SUSPEND_SESSION -> "COMMAND_TYPE_SUSPEND_SESSION";
+ case COMMAND_TYPE_RESUME_SESSION -> "COMMAND_TYPE_RESUME_SESSION";
+ case COMMAND_TYPE_END_PAIRING -> "COMMAND_TYPE_END_PAIRING";
+
+ case RESPONSE_TYPE_ON_CONFIG_SUCCESS -> "RESPONSE_TYPE_ON_CONFIG_SUCCESS";
+ case RESPONSE_TYPE_ON_CONFIG_FAIL -> "RESPONSE_TYPE_ON_CONFIG_FAIL";
+ case RESPONSE_TYPE_ON_SESSION_CONFIG_SUCCESS
+ -> "RESPONSE_TYPE_ON_SESSION_CONFIG_SUCCESS";
+ case RESPONSE_TYPE_ON_SESSION_CONFIG_FAIL -> "RESPONSE_TYPE_ON_SESSION_CONFIG_FAIL";
+ case RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_SUCCESS
+ -> "RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_SUCCESS";
+ case RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_FAIL
+ -> "RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_FAIL";
+ case RESPONSE_TYPE_ON_CAPABILITIES_UPDATED
+ -> "RESPONSE_TYPE_ON_CAPABILITIES_UPDATED";
+ case RESPONSE_TYPE_ON_CREATE_INTERFACE -> "RESPONSE_TYPE_ON_CREATE_INTERFACE";
+ case RESPONSE_TYPE_ON_DELETE_INTERFACE -> "RESPONSE_TYPE_ON_DELETE_INTERFACE";
+ case RESPONSE_TYPE_ON_INITIATE_DATA_PATH_SUCCESS
+ -> "RESPONSE_TYPE_ON_INITIATE_DATA_PATH_SUCCESS";
+ case RESPONSE_TYPE_ON_INITIATE_DATA_PATH_FAIL
+ -> "RESPONSE_TYPE_ON_INITIATE_DATA_PATH_FAIL";
+ case RESPONSE_TYPE_ON_RESPOND_TO_DATA_PATH_SETUP_REQUEST
+ -> "RESPONSE_TYPE_ON_RESPOND_TO_DATA_PATH_SETUP_REQUEST";
+ case RESPONSE_TYPE_ON_END_DATA_PATH -> "RESPONSE_TYPE_ON_END_DATA_PATH";
+ case RESPONSE_TYPE_ON_DISABLE -> "RESPONSE_TYPE_ON_DISABLE";
+ case RESPONSE_TYPE_ON_INITIATE_PAIRING_SUCCESS
+ -> "RESPONSE_TYPE_ON_INITIATE_PAIRING_SUCCESS";
+ case RESPONSE_TYPE_ON_INITIATE_PAIRING_FAIL
+ -> "RESPONSE_TYPE_ON_INITIATE_PAIRING_FAIL";
+ case RESPONSE_TYPE_ON_RESPONSE_PAIRING_SUCCESS
+ -> "RESPONSE_TYPE_ON_RESPONSE_PAIRING_SUCCESS";
+ case RESPONSE_TYPE_ON_RESPONSE_PAIRING_FAIL
+ -> "RESPONSE_TYPE_ON_RESPONSE_PAIRING_FAIL";
+ case RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_SUCCESS
+ -> "RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_SUCCESS";
+ case RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_FAIL
+ -> "RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_FAIL";
+ case RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_SUCCESS
+ -> "RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_SUCCESS";
+ case RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_FAIL
+ -> "RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_FAIL";
+ case RESPONSE_TYPE_ON_SUSPEND -> "RESPONSE_TYPE_ON_SUSPEND";
+ case RESPONSE_TYPE_ON_RESUME -> "RESPONSE_TYPE_ON_RESUME";
+ case RESPONSE_TYPE_ON_END_PAIRING -> "RESPONSE_TYPE_ON_END_PAIRING";
+
+ case NOTIFICATION_TYPE_INTERFACE_CHANGE -> "NOTIFICATION_TYPE_INTERFACE_CHANGE";
+ case NOTIFICATION_TYPE_CLUSTER_CHANGE -> "NOTIFICATION_TYPE_CLUSTER_CHANGE";
+ case NOTIFICATION_TYPE_MATCH -> "NOTIFICATION_TYPE_MATCH";
+ case NOTIFICATION_TYPE_SESSION_TERMINATED -> "NOTIFICATION_TYPE_SESSION_TERMINATED";
+ case NOTIFICATION_TYPE_MESSAGE_RECEIVED -> "NOTIFICATION_TYPE_MESSAGE_RECEIVED";
+ case NOTIFICATION_TYPE_AWARE_DOWN -> "NOTIFICATION_TYPE_AWARE_DOWN";
+ case NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS
+ -> "NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS";
+ case NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL
+ -> "NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL";
+ case NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST
+ -> "NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST";
+ case NOTIFICATION_TYPE_ON_DATA_PATH_CONFIRM
+ -> "NOTIFICATION_TYPE_ON_DATA_PATH_CONFIRM";
+ case NOTIFICATION_TYPE_ON_DATA_PATH_END -> "NOTIFICATION_TYPE_ON_DATA_PATH_END";
+ case NOTIFICATION_TYPE_ON_DATA_PATH_SCHED_UPDATE
+ -> "NOTIFICATION_TYPE_ON_DATA_PATH_SCHED_UPDATE";
+ case NOTIFICATION_TYPE_MATCH_EXPIRED -> "NOTIFICATION_TYPE_MATCH_EXPIRED";
+ case NOTIFICATION_TYPE_ON_PAIRING_REQUEST -> "NOTIFICATION_TYPE_ON_PAIRING_REQUEST";
+ case NOTIFICATION_TYPE_ON_PAIRING_CONFIRM -> "NOTIFICATION_TYPE_ON_PAIRING_CONFIRM";
+ case NOTIFICATION_TYPE_ON_BOOTSTRAPPING_REQUEST
+ -> "NOTIFICATION_TYPE_ON_BOOTSTRAPPING_REQUEST";
+ case NOTIFICATION_TYPE_ON_BOOTSTRAPPING_CONFIRM
+ -> "NOTIFICATION_TYPE_ON_BOOTSTRAPPING_CONFIRM";
+ case NOTIFICATION_TYPE_ON_SUSPENSION_MODE_CHANGED
+ -> "NOTIFICATION_TYPE_ON_SUSPENSION_MODE_CHANGED";
+ default -> {
+ Log.wtf(TAG, "unknown message what: " + what);
+ yield "what:" + what;
+ }
+ };
+ }
+
public void onAwareDownCleanupSendQueueState() {
mSendQueueBlocked = false;
mHostQueuedSendMessages.clear();
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pMetrics.java b/service/java/com/android/server/wifi/p2p/WifiP2pMetrics.java
index 0ae1bf7..b2d2ea7 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pMetrics.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pMetrics.java
@@ -190,24 +190,8 @@
} else {
sb.append(StringUtil.calendarToString(c));
}
- sb.append(", connectionType=");
- switch (event.connectionType) {
- case P2pConnectionEvent.CONNECTION_FRESH:
- sb.append("FRESH");
- break;
- case P2pConnectionEvent.CONNECTION_REINVOKE:
- sb.append("REINVOKE");
- break;
- case P2pConnectionEvent.CONNECTION_LOCAL:
- sb.append("LOCAL");
- break;
- case P2pConnectionEvent.CONNECTION_FAST:
- sb.append("FAST");
- break;
- default:
- sb.append("UNKNOWN");
- break;
- }
+ sb.append(", connectionType=").append(
+ getconnectionTypeToString(event.connectionType));
sb.append(", wpsMethod=");
switch (event.wpsMethod) {
case P2pConnectionEvent.WPS_NA:
@@ -231,19 +215,7 @@
}
sb.append(", durationTakenToConnectMillis=");
sb.append(event.durationTakenToConnectMillis);
- sb.append(", groupRole=");
- switch (event.groupRole) {
- case GroupEvent.GROUP_OWNER:
- sb.append("OWNER");
- break;
- case GroupEvent.GROUP_CLIENT:
- sb.append("CLIENT");
- break;
- default:
- sb.append("UNKNOWN DURING CONNECT");
- break;
- }
-
+ sb.append(", groupRole=").append(getGroupRoleToString(event.groupRole));
sb.append(", tryCount=");
sb.append(event.tryCount);
sb.append(", inviteToNeg=");
@@ -258,40 +230,9 @@
sb.append(event.staFrequencyMhz);
sb.append(", uid=");
sb.append(event.uid);
- sb.append(", connectivityLevelFailureCode=");
- switch (event.connectivityLevelFailureCode) {
- case P2pConnectionEvent.CLF_NONE:
- sb.append("NONE");
- break;
- case P2pConnectionEvent.CLF_TIMEOUT:
- sb.append("TIMEOUT");
- break;
- case P2pConnectionEvent.CLF_CANCEL:
- sb.append("CANCEL");
- break;
- case P2pConnectionEvent.CLF_PROV_DISC_FAIL:
- sb.append("PROV_DISC_FAIL");
- break;
- case P2pConnectionEvent.CLF_INVITATION_FAIL:
- sb.append("INVITATION_FAIL");
- break;
- case P2pConnectionEvent.CLF_USER_REJECT:
- sb.append("USER_REJECT");
- break;
- case P2pConnectionEvent.CLF_NEW_CONNECTION_ATTEMPT:
- sb.append("NEW_CONNECTION_ATTEMPT");
- break;
- case P2pConnectionEvent.CLF_GROUP_REMOVED:
- sb.append("GROUP_REMOVED");
- break;
- case P2pConnectionEvent.CLF_CREATE_GROUP_FAILED:
- sb.append("CREATE_GROUP_FAILED");
- break;
- case P2pConnectionEvent.CLF_UNKNOWN:
- default:
- sb.append("UNKNOWN");
- break;
- }
+ sb.append(", connectivityLevelFailureCode=").append(
+ getConnectivityLevelFailureCodeToString(
+ event.connectivityLevelFailureCode));
if (event == mCurrentConnectionEvent) {
sb.append(" CURRENTLY OPEN EVENT");
}
@@ -342,6 +283,58 @@
}
}
+ private String getconnectionTypeToString(int connectionType) {
+ switch (connectionType) {
+ case P2pConnectionEvent.CONNECTION_FRESH:
+ return "FRESH";
+ case P2pConnectionEvent.CONNECTION_REINVOKE:
+ return "REINVOKE";
+ case P2pConnectionEvent.CONNECTION_LOCAL:
+ return "LOCAL";
+ case P2pConnectionEvent.CONNECTION_FAST:
+ return "FAST";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ private String getGroupRoleToString(int groupRole) {
+ switch (groupRole) {
+ case GroupEvent.GROUP_OWNER:
+ return "OWNER";
+ case GroupEvent.GROUP_CLIENT:
+ return "CLIENT";
+ default:
+ return "UNKNOWN DURING CONNECT";
+ }
+ }
+
+ private String getConnectivityLevelFailureCodeToString(int connectivityLevelFailureCode) {
+ switch (connectivityLevelFailureCode) {
+ case P2pConnectionEvent.CLF_NONE:
+ return "NONE";
+ case P2pConnectionEvent.CLF_TIMEOUT:
+ return "TIMEOUT";
+ case P2pConnectionEvent.CLF_CANCEL:
+ return "CANCEL";
+ case P2pConnectionEvent.CLF_PROV_DISC_FAIL:
+ return "PROV_DISC_FAIL";
+ case P2pConnectionEvent.CLF_INVITATION_FAIL:
+ return "INVITATION_FAIL";
+ case P2pConnectionEvent.CLF_USER_REJECT:
+ return "USER_REJECT";
+ case P2pConnectionEvent.CLF_NEW_CONNECTION_ATTEMPT:
+ return "NEW_CONNECTION_ATTEMPT";
+ case P2pConnectionEvent.CLF_GROUP_REMOVED:
+ return "GROUP_REMOVED";
+ case P2pConnectionEvent.CLF_CREATE_GROUP_FAILED:
+ return "CREATE_GROUP_FAILED";
+ case P2pConnectionEvent.CLF_UNKNOWN:
+ default:
+ return "UNKNOWN";
+ }
+ }
+
/** Increment total number of peer scans */
public void incrementPeerScans() {
synchronized (mLock) {
@@ -392,6 +385,24 @@
public void startConnectionEvent(int connectionType, WifiP2pConfig config, int groupRole,
int uid) {
synchronized (mLock) {
+ StringBuilder stringBuilder = new StringBuilder("Start connection event");
+ if (mCurrentConnectionEvent == null) {
+ stringBuilder.append(", mCurrentConnectionEvent:null");
+ } else {
+ stringBuilder.append(", curConnectionType:")
+ .append(getconnectionTypeToString(mCurrentConnectionEvent.connectionType))
+ .append(", curGroupRole:")
+ .append(getGroupRoleToString(mCurrentConnectionEvent.groupRole))
+ .append(", curUid:").append(mCurrentConnectionEvent.uid)
+ .append(", curConnectivityLevelFailureCode:")
+ .append(getConnectivityLevelFailureCodeToString(
+ mCurrentConnectionEvent.connectivityLevelFailureCode));
+ }
+ stringBuilder.append(", startConnectionType:")
+ .append(getconnectionTypeToString(connectionType))
+ .append(", startGroupRole:").append(getGroupRoleToString(groupRole))
+ .append(", startUid:").append(uid);
+ Log.d(TAG, stringBuilder.toString());
// handle overlapping connection event first.
if (mCurrentConnectionEvent != null) {
endConnectionEvent(P2pConnectionEvent.CLF_NEW_CONNECTION_ATTEMPT);
@@ -443,6 +454,23 @@
*/
public void endConnectionEvent(int failure) {
synchronized (mLock) {
+ StringBuilder stringBuilder = new StringBuilder("End connection event");
+ if (mCurrentConnectionEvent == null) {
+ stringBuilder.append(", mCurrentConnectionEvent:null");
+ } else {
+ stringBuilder.append(", curConnectionType:")
+ .append(getconnectionTypeToString(mCurrentConnectionEvent.connectionType))
+ .append(", curGroupRole:")
+ .append(getGroupRoleToString(mCurrentConnectionEvent.groupRole))
+ .append(", curUid:")
+ .append(mCurrentConnectionEvent.uid)
+ .append(", curConnectivityLevelFailureCode:")
+ .append(getConnectivityLevelFailureCodeToString(
+ mCurrentConnectionEvent.connectivityLevelFailureCode));
+ }
+ stringBuilder.append(", endConnectivityLevelFailureCode:")
+ .append(getConnectivityLevelFailureCodeToString(failure));
+ Log.d(TAG, stringBuilder.toString());
if (mCurrentConnectionEvent == null) {
// Reinvoking a group with invitation will be handled in supplicant.
// There won't be a connection starting event in framework.
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index f16e1e2..a1beea4 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -154,6 +154,7 @@
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
@@ -252,7 +253,7 @@
android.Manifest.permission.ACCESS_WIFI_STATE
};
- private static final String[] RECEIVER_PERMISSIONS_FOR_TETHERING = {
+ private static final String[] RECEIVER_PERMISSIONS_MAINLINE_NETWORK_STACK = {
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
};
@@ -3675,7 +3676,7 @@
P2pConnectionEvent.CLF_CANCEL);
// Notify the peer about the rejection.
int delay = 0;
- if (mSavedPeerConfig != null) {
+ if (!TextUtils.isEmpty(mSavedPeerConfig.deviceAddress)) {
mWifiNative.p2pStopFind();
delay = sendP2pRejection();
}
@@ -3685,7 +3686,7 @@
P2P_REJECTION_RESUME_AFTER_DELAY,
++sP2pRejectionResumeAfterDelayIndex,
WifiP2pManager.CANCEL_CONNECT,
- message),
+ Message.obtain(message)),
delay);
break;
case WifiP2pMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
@@ -3729,7 +3730,7 @@
if (mVerboseLoggingEnabled) {
logd("User rejected negotiation " + mSavedPeerConfig);
}
- if (mSavedPeerConfig != null) {
+ if (!TextUtils.isEmpty(mSavedPeerConfig.deviceAddress)) {
WifiP2pDevice dev = fetchCurrentDeviceDetails(mSavedPeerConfig);
boolean join = (dev != null && dev.isGroupOwner())
|| mJoinExistingGroup;
@@ -4041,7 +4042,10 @@
// As a result, P2P sends a unicast intent to tether service to trigger
// the whole flow before entering GroupCreatedState.
setWifiP2pInfoOnGroupFormation(null);
- if (!sendP2pTetherRequestBroadcast()) {
+ boolean isSendSuccessful = SdkLevel.isAtLeastU()
+ ? sendP2pTetherRequestBroadcastPostU()
+ : sendP2pTetherRequestBroadcastPreU();
+ if (!isSendSuccessful) {
loge("Cannot start tethering, remove " + mGroup);
mWifiNative.p2pGroupRemove(mGroup.getInterface());
}
@@ -4798,7 +4802,7 @@
sendP2pConnectionChangedBroadcast();
if (!SdkLevel.isAtLeastU()) {
// Ensure tethering service to stop tethering.
- sendP2pTetherRequestBroadcast();
+ sendP2pTetherRequestBroadcastPreU();
}
}
}
@@ -5040,10 +5044,13 @@
if (mVerboseLoggingEnabled) logd("sending p2p connection changed broadcast");
Intent intent = getP2pConnectionChangedIntent();
if (SdkLevel.isAtLeastU()) {
- // First send direct foreground broadcast to Tethering package
- sendP2pTetherRequestBroadcast();
- // Then send the same broadcast to remaining apps excluding Tethering package
- sendBroadcastWithExcludedPermissions(intent, RECEIVER_PERMISSIONS_FOR_TETHERING);
+ // First send direct foreground broadcast to Tethering package and system service
+ // with same android.permission.MAINLINE_NETWORK_STACK
+ sendBroadcastWithMainlineNetworkStackPermissionPostU();
+ // Then send the same broadcast to remaining apps without
+ // android.permission.MAINLINE_NETWORK_STACK
+ sendBroadcastWithExcludedPermissions(intent,
+ RECEIVER_PERMISSIONS_MAINLINE_NETWORK_STACK);
} else {
sendBroadcastWithExcludedPermissions(intent, null);
}
@@ -5123,32 +5130,47 @@
return null;
}
- private boolean sendP2pTetherRequestBroadcast() {
- String tetheringServicePackage = findTetheringServicePackage();
- if (TextUtils.isEmpty(tetheringServicePackage)) return false;
- Log.i(TAG, "sending p2p tether request broadcast to "
- + tetheringServicePackage);
-
+ private boolean sendP2pTetherRequestBroadcastPreU() {
String[] receiverPermissionsForTetheringRequest = {
android.Manifest.permission.TETHER_PRIVILEGED
};
- if (SdkLevel.isAtLeastU()) {
- receiverPermissionsForTetheringRequest = RECEIVER_PERMISSIONS_FOR_TETHERING;
- }
- Intent intent = getP2pConnectionChangedIntent();
- intent.setPackage(tetheringServicePackage);
- if (SdkLevel.isAtLeastU()) {
- // Adding the flag to allow recipient to run at foreground priority with a shorter
- // timeout interval.
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- }
+ return sendP2pTetherRequestBroadcastCommon(receiverPermissionsForTetheringRequest,
+ false, 0);
+ }
+ private boolean sendP2pTetherRequestBroadcastPostU() {
+ return sendP2pTetherRequestBroadcastCommon(RECEIVER_PERMISSIONS_MAINLINE_NETWORK_STACK,
+ true, Intent.FLAG_RECEIVER_FOREGROUND);
+ }
+
+ private boolean sendP2pTetherRequestBroadcastCommon(String[] permissions,
+ boolean setAdditionalFlags, int flags) {
+ String tetheringServicePackage = findTetheringServicePackage();
+ if (TextUtils.isEmpty(tetheringServicePackage)) return false;
+ Log.i(TAG, "sending p2p tether request broadcast to " + tetheringServicePackage
+ + " with permission " + Arrays.toString(permissions));
+ Intent intent = getP2pConnectionChangedIntent();
+ if (setAdditionalFlags) {
+ intent.addFlags(flags);
+ }
+ intent.setPackage(tetheringServicePackage);
Context context = mContext.createContextAsUser(UserHandle.ALL, 0);
- context.sendBroadcastWithMultiplePermissions(
- intent, receiverPermissionsForTetheringRequest);
+ context.sendBroadcastWithMultiplePermissions(intent, permissions);
return true;
}
+ private void sendBroadcastWithMainlineNetworkStackPermissionPostU() {
+ String[] receiverPermissions = RECEIVER_PERMISSIONS_MAINLINE_NETWORK_STACK;
+ Intent intent = getP2pConnectionChangedIntent();
+ // Adding the flag to allow recipient to run at foreground priority with a shorter
+ // timeout interval.
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ Log.i(TAG, "sending p2p connection changed broadcast with permission "
+ + Arrays.toString(receiverPermissions));
+ Context context = mContext.createContextAsUser(UserHandle.ALL, 0);
+ context.sendBroadcastWithMultiplePermissions(intent, receiverPermissions);
+ }
+
private void sendP2pPersistentGroupsChangedBroadcast() {
if (mVerboseLoggingEnabled) logd("sending p2p persistent groups changed broadcast");
Intent intent = new Intent(WifiP2pManager.ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED);
@@ -6903,6 +6925,11 @@
return false;
}
+ if (TextUtils.isEmpty(mSavedPeerConfig.deviceAddress)) {
+ logd("Saved peer address is empty");
+ return false;
+ }
+
if (!devAddr.equals(MacAddress.fromString(mSavedPeerConfig.deviceAddress))) {
logd("Saved peer address is different from " + devAddr);
return false;
diff --git a/service/java/com/android/server/wifi/util/ApConfigUtil.java b/service/java/com/android/server/wifi/util/ApConfigUtil.java
index 8b5b8e1..96c2984 100644
--- a/service/java/com/android/server/wifi/util/ApConfigUtil.java
+++ b/service/java/com/android/server/wifi/util/ApConfigUtil.java
@@ -29,6 +29,9 @@
import static android.net.wifi.SoftApCapability.SOFTAP_FEATURE_WPA3_OWE_TRANSITION;
import static android.net.wifi.SoftApCapability.SOFTAP_FEATURE_WPA3_SAE;
+import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDGE;
+import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_STA;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -52,6 +55,7 @@
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.SoftApManager;
import com.android.server.wifi.WifiNative;
+import com.android.server.wifi.WifiSettingsConfigStore;
import com.android.server.wifi.coex.CoexManager;
import com.android.wifi.resources.R;
@@ -1001,6 +1005,27 @@
}
/**
+ * Helper function to update SoftApCapability instance based on config store.
+ *
+ * @param capability the original softApCapability
+ * @param configStore where we stored the Capability after first time fetch from driver.
+ * @return SoftApCapability which updated from the config store.
+ */
+ @NonNull
+ public static SoftApCapability updateCapabilityFromConfigStore(
+ SoftApCapability capability,
+ WifiSettingsConfigStore configStore) {
+ if (capability == null) {
+ return null;
+ }
+ if (capability.areFeaturesSupported(SOFTAP_FEATURE_IEEE80211_BE)) {
+ capability.setSupportedFeatures(isIeee80211beEnabledInConfig(configStore),
+ SOFTAP_FEATURE_IEEE80211_BE);
+ }
+ return capability;
+ }
+
+ /**
* Helper function to get device support 802.11 AX on Soft AP or not
*
* @param context the caller context used to get value from resource file.
@@ -1023,6 +1048,18 @@
}
/**
+ * Helper function to check Config supports 802.11 BE on Soft AP or not
+ *
+ * @param configStore to check the support from WifiSettingsConfigStore
+ * @return true if supported, false otherwise.
+ */
+ public static boolean isIeee80211beEnabledInConfig(
+ WifiSettingsConfigStore configStore) {
+ return configStore.get(
+ WifiSettingsConfigStore.WIFI_WIPHY_11BE_SUPPORTED);
+ }
+
+ /**
* Helper function to get device support AP MAC randomization or not.
*
* @param context the caller context used to get value from resource file.
@@ -1037,22 +1074,33 @@
* Helper function to get HAL support bridged AP or not.
*
* @param context the caller context used to get value from resource file.
+ * @param wifiNative to get the Iface combination from device.
* @return true if supported, false otherwise.
*/
- public static boolean isBridgedModeSupported(@NonNull Context context) {
+ public static boolean isBridgedModeSupported(
+ @NonNull Context context, @NonNull WifiNative wifiNative) {
return SdkLevel.isAtLeastS() && context.getResources().getBoolean(
- R.bool.config_wifiBridgedSoftApSupported);
+ R.bool.config_wifiBridgedSoftApSupported)
+ && wifiNative.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
+ put(HDM_CREATE_IFACE_AP_BRIDGE, 1);
+ }});
}
/**
* Helper function to get HAL support STA + bridged AP or not.
*
* @param context the caller context used to get value from resource file.
+ * @param wifiNative to get the Iface combination from device.
* @return true if supported, false otherwise.
*/
- public static boolean isStaWithBridgedModeSupported(@NonNull Context context) {
+ public static boolean isStaWithBridgedModeSupported(
+ @NonNull Context context, @NonNull WifiNative wifiNative) {
return SdkLevel.isAtLeastS() && context.getResources().getBoolean(
- R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported);
+ R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported)
+ && wifiNative.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
+ put(HDM_CREATE_IFACE_AP_BRIDGE, 1);
+ put(HDM_CREATE_IFACE_STA, 1);
+ }});
}
/**
diff --git a/service/java/com/android/server/wifi/util/XmlUtil.java b/service/java/com/android/server/wifi/util/XmlUtil.java
index 47da81f..52a8704 100644
--- a/service/java/com/android/server/wifi/util/XmlUtil.java
+++ b/service/java/com/android/server/wifi/util/XmlUtil.java
@@ -424,7 +424,7 @@
EncryptedData[] encryptedDataArray = new EncryptedData[len];
for (int i = 0; i < len; i++) {
if (wepKeys[i] == null) {
- encryptedDataArray[i] = new EncryptedData(null, null);
+ encryptedDataArray[i] = new EncryptedData(new byte[0], new byte[0]);
} else {
encryptedDataArray[i] = encryptionUtil.encrypt(wepKeys[i].getBytes());
if (encryptedDataArray[i] == null) {
@@ -735,7 +735,12 @@
List<String> wepKeyList = new ArrayList<>();
final List<EncryptedData> encryptedDataList =
XmlUtil.EncryptedDataXmlUtil.parseListFromXml(in, outerTagDepth);
+ EncryptedData emptyData = new EncryptedData(new byte[0], new byte[0]);
for (int i = 0; i < encryptedDataList.size(); i++) {
+ if (encryptedDataList.get(i).equals(emptyData)) {
+ wepKeyList.add(null);
+ continue;
+ }
byte[] passphraseBytes = encryptionUtil.decrypt(encryptedDataList.get(i));
if (passphraseBytes == null) {
Log.wtf(TAG, "Decryption of passphraseBytes failed");
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index e3361c9..46051d8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -684,6 +684,7 @@
when(mWifiGlobals.getPollRssiIntervalMillis()).thenReturn(3000);
when(mWifiGlobals.getIpReachabilityDisconnectEnabled()).thenReturn(true);
+ when(mWifiGlobals.getRepeatedNudFailuresThreshold()).thenReturn(Integer.MAX_VALUE);
when(mFrameworkFacade.getIntegerSetting(mContext,
Settings.Global.WIFI_FREQUENCY_BAND,
@@ -7397,6 +7398,57 @@
verify(mWifiNative).disconnect(WIFI_IFACE_NAME);
}
+ /**
+ * Verify that when HandleRssiOrganicKernelFailuresEnabled, multiple IP reachability failures
+ * within a specified time window will lead to disconnect and network disabled.
+ */
+ @Test
+ public void testRepeatedIpReachabilityFailureDisableNetwork() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastU());
+ when(mDeviceConfigFacade.isHandleRssiOrganicKernelFailuresEnabled()).thenReturn(true);
+ int failureThreshold = 5;
+ int failureWindowMs = 60000;
+ when(mWifiGlobals.getRepeatedNudFailuresThreshold()).thenReturn(failureThreshold);
+ when(mWifiGlobals.getRepeatedNudFailuresWindowMs()).thenReturn(failureWindowMs);
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
+
+ connect();
+ expectRegisterNetworkAgent((agentConfig) -> { }, (cap) -> { });
+ reset(mWifiNetworkAgent);
+
+ for (int i = 0; i < failureThreshold; i++) {
+ // increment time outside the failure window. Failure counter should never add up and
+ // thus not trigger blocking.
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(
+ (long) (i + 1) * (failureWindowMs + 1));
+ verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME);
+ verify(mWifiConfigManager, never()).updateNetworkSelectionStatus(anyInt(),
+ eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_REPEATED_NUD_FAILURES));
+ ReachabilityLossInfoParcelable lossInfo =
+ new ReachabilityLossInfoParcelable("", ReachabilityLossReason.ORGANIC);
+ mIpClientCallback.onReachabilityFailure(lossInfo);
+ mLooper.dispatchAll();
+ }
+
+ // Now trigger NUD failure within the failure window and verify the network is blocked.
+ for (int i = 0; i < failureThreshold - 1; i++) {
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(
+ (long) (i + failureThreshold + 1) * (failureWindowMs));
+ verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME);
+ verify(mWifiConfigManager, never()).updateNetworkSelectionStatus(anyInt(),
+ eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_REPEATED_NUD_FAILURES));
+ ReachabilityLossInfoParcelable lossInfo =
+ new ReachabilityLossInfoParcelable("", ReachabilityLossReason.ORGANIC);
+ mIpClientCallback.onReachabilityFailure(lossInfo);
+ mLooper.dispatchAll();
+ }
+
+ // Should disconnect and block network after the last iteration.
+ verify(mWifiConfigManager).updateNetworkSelectionStatus(anyInt(),
+ eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_REPEATED_NUD_FAILURES));
+ verify(mWifiNative).disconnect(WIFI_IFACE_NAME);
+ }
+
@Test
public void testIpReachabilityFailureOrganic_enableHandleRssiOrganicKernelFailuresFlag()
throws Exception {
@@ -10444,18 +10496,19 @@
@Test
public void testEnableTdls() throws Exception {
connect();
- when(mWifiNative.getMaxSupportedConcurrentTdlsSessions(WIFI_IFACE_NAME)).thenReturn(5);
+ when(mWifiNative.getMaxSupportedConcurrentTdlsSessions(WIFI_IFACE_NAME)).thenReturn(1);
when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME))
.thenReturn(WifiManager.WIFI_FEATURE_TDLS);
when(mWifiNative.startTdls(eq(WIFI_IFACE_NAME), eq(TEST_TDLS_PEER_ADDR_STR), anyBoolean()))
.thenReturn(true);
- assertEquals(5, mCmi.getMaxSupportedConcurrentTdlsSessions());
+ assertEquals(1, mCmi.getMaxSupportedConcurrentTdlsSessions());
assertTrue(mCmi.isTdlsOperationCurrentlyAvailable());
- mCmi.enableTdls(TEST_TDLS_PEER_ADDR_STR, true);
+ assertTrue(mCmi.enableTdls(TEST_TDLS_PEER_ADDR_STR, true));
assertEquals(1, mCmi.getNumberOfEnabledTdlsSessions());
verify(mWifiNative).startTdls(eq(WIFI_IFACE_NAME), eq(TEST_TDLS_PEER_ADDR_STR),
eq(true));
- mCmi.enableTdls(TEST_TDLS_PEER_ADDR_STR, false);
+ assertFalse(mCmi.enableTdls(TEST_TDLS_PEER_ADDR_STR, true));
+ assertTrue(mCmi.enableTdls(TEST_TDLS_PEER_ADDR_STR, false));
verify(mWifiNative).startTdls(eq(WIFI_IFACE_NAME), eq(TEST_TDLS_PEER_ADDR_STR),
eq(false));
assertEquals(0, mCmi.getNumberOfEnabledTdlsSessions());
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
index 3d7ca24..20cef21 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -31,6 +31,8 @@
import static com.android.server.wifi.ActiveModeManager.ROLE_SOFTAP_LOCAL_ONLY;
import static com.android.server.wifi.ActiveModeManager.ROLE_SOFTAP_TETHERED;
+import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDGE;
+import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_STA;
import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR;
import static com.google.common.truth.Truth.assertThat;
@@ -80,6 +82,7 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.util.LocalLog;
+import android.util.SparseArray;
import android.util.SparseIntArray;
import androidx.test.filters.SmallTest;
@@ -161,6 +164,9 @@
private static final int[] TEST_SUPPORTED_24G_CHANNELS = new int[] {1, 2};
private static final int[] TEST_SUPPORTED_5G_CHANNELS = new int[] {36, 149};
+ private boolean mApBridgeIfaceCobinationSupported = true;
+ private boolean mApBridgeWithStaIfaceCobinationSupported = true;
+
private TestLooper mLooper;
private TestAlarmManager mAlarmManager;
private SoftApInfo mTestSoftApInfo; // Use for single Ap mode test case
@@ -347,6 +353,22 @@
.thenReturn(ALLOWED_6G_FREQS);
when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_60_GHZ))
.thenReturn(ALLOWED_60G_FREQS);
+ when(mWifiNative.canDeviceSupportCreateTypeCombo(any()))
+ .thenAnswer(answer -> {
+ SparseArray<Integer> combo = answer.getArgument(0);
+ if (combo.contentEquals(new SparseArray<Integer>() {{
+ put(HDM_CREATE_IFACE_AP_BRIDGE, 1);
+ }})) {
+ return mApBridgeIfaceCobinationSupported;
+ }
+ if (combo.contentEquals(new SparseArray<Integer>() {{
+ put(HDM_CREATE_IFACE_AP_BRIDGE, 1);
+ put(HDM_CREATE_IFACE_STA, 1);
+ }})) {
+ return mApBridgeWithStaIfaceCobinationSupported;
+ }
+ return false;
+ });
when(mWifiNative.getApFactoryMacAddress(any())).thenReturn(TEST_INTERFACE_MAC_ADDRESS);
when(mWifiApConfigStore.randomizeBssidIfUnset(any(), any())).thenAnswer(
(invocation) -> invocation.getArgument(1));
@@ -391,7 +413,8 @@
| SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT
| SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD
| SoftApCapability.SOFTAP_FEATURE_WPA3_SAE
- | SoftApCapability.SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION;
+ | SoftApCapability.SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION
+ | SoftApCapability.SOFTAP_FEATURE_IEEE80211_BE;
mTestSoftApCapability = new SoftApCapability(testSoftApFeature);
mTestSoftApCapability.setMaxSupportedClients(10);
mTestSoftApCapability.setSupportedChannelList(
@@ -617,6 +640,8 @@
@Test
public void testStartSoftApNotPossibleToCreateApInterfaceIncrementsMetrics()
throws Exception {
+ when(mWifiNative.setupInterfaceForSoftApMode(
+ any(), any(), anyInt(), anyBoolean(), any())).thenReturn(null);
when(mWifiNative.isItPossibleToCreateApIface(any())).thenReturn(false);
Builder configBuilder = new SoftApConfiguration.Builder();
configBuilder.setBand(SoftApConfiguration.BAND_2GHZ);
@@ -625,6 +650,7 @@
IFACE_IP_MODE_LOCAL_ONLY, configBuilder.build(),
mTestSoftApCapability, TEST_COUNTRY_CODE);
mSoftApManager = createSoftApManager(apConfig, ROLE_SOFTAP_TETHERED);
+ verify(mWifiNative).isItPossibleToCreateApIface(any());
verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
WifiManager.SAP_START_FAILURE_GENERAL);
verify(mListener).onStartFailure(mSoftApManager);
@@ -664,6 +690,7 @@
mSoftApManager = createSoftApManager(nullApConfig, ROLE_SOFTAP_TETHERED);
verify(mCallback).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
WifiManager.SAP_START_FAILURE_GENERAL);
+ verify(mWifiNative).isItPossibleToCreateApIface(any());
verify(mListener).onStartFailure(mSoftApManager);
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
if (SdkLevel.isAtLeastSv2()) {
@@ -2394,10 +2421,17 @@
randomizedBssidConfig = randomizedBssidConfigBuilder.build();
when(mWifiApConfigStore.randomizeBssidIfUnset(any(), any())).thenReturn(
randomizedBssidConfig);
- expectedConfig = new SoftApConfiguration.Builder(randomizedBssidConfig)
- .build();
+
+ expectedConfig = randomizedBssidConfig;
} else {
- expectedConfig = new SoftApConfiguration.Builder(config)
+ expectedConfig = config;
+ }
+ if (SdkLevel.isAtLeastT()
+ && expectedConfig.isIeee80211beEnabled()
+ && !softApConfig.getCapability().areFeaturesSupported(
+ SoftApCapability.SOFTAP_FEATURE_IEEE80211_BE)) {
+ expectedConfig = new SoftApConfiguration.Builder(expectedConfig)
+ .setIeee80211beEnabled(false)
.build();
}
}
@@ -2432,7 +2466,6 @@
mWifiNativeInterfaceCallbackCaptor.capture(), eq(TEST_WORKSOURCE),
eq(expectedConfig.getBand()), eq(expectedConfig.getBands().length > 1),
eq(mSoftApManager));
-
// Simulate user approval
ArgumentCaptor<StateMachine> stateMachineCaptor =
ArgumentCaptor.forClass(StateMachine.class);
@@ -2446,6 +2479,9 @@
stateMachineCaptor.getValue().sendMessage(Message.obtain(messageCaptor.getValue()));
mLooper.dispatchAll();
}
+ // isItPossibleToCreateApIface should never happen in normal case since it may fail in
+ // normal use case
+ verify(mWifiNative, never()).isItPossibleToCreateApIface(any());
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mFakeSoftApNotifier).dismissSoftApShutdownTimeoutExpiredNotification();
order.verify(mWifiNative).setupInterfaceForSoftApMode(
@@ -2511,8 +2547,7 @@
verify(mListener).onStarted(mSoftApManager);
verify(mWifiMetrics).addSoftApUpChangedEvent(true, softApConfig.getTargetMode(),
TEST_DEFAULT_SHUTDOWN_TIMEOUT_MILLIS, expectedConfig.getBands().length > 1);
- verify(mWifiMetrics).updateSoftApConfiguration(config == null
- ? randomizedBssidConfig : expectedConfig, softApConfig.getTargetMode(),
+ verify(mWifiMetrics).updateSoftApConfiguration(expectedConfig, softApConfig.getTargetMode(),
expectedConfig.getBands().length > 1);
verify(mWifiMetrics)
.updateSoftApCapability(
@@ -3722,7 +3757,7 @@
}
@Test
- public void testFallbackToSingleModeDueToStaExistButStaWithBridgedApNotSupported()
+ public void testFallbackToSingleModeDueToStaExistButStaWithBridgedApNotSupportedByOverlay()
throws Exception {
assumeTrue(SdkLevel.isAtLeastS());
when(mResources.getBoolean(R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported))
@@ -3740,6 +3775,25 @@
}
@Test
+ public void testFallbackToSingleModeDueToStaExistButStaWithBridgedApNotSupportedByDriver()
+ throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mResources.getBoolean(R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported))
+ .thenReturn(true);
+ mApBridgeWithStaIfaceCobinationSupported = false;
+ Builder configBuilder = new SoftApConfiguration.Builder(
+ generateBridgedModeSoftApConfig(null));
+
+ SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
+ WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
+ mTestSoftApCapability, TEST_COUNTRY_CODE);
+ // Reset band to 2.4G | 5G to generate expected configuration since it should fallback to
+ // single AP mode
+ configBuilder.setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ);
+ startSoftApAndVerifyEnabled(apConfig, configBuilder.build(), false);
+ }
+
+ @Test
public void testFallbackToSingleModeDueToUnableToCreateBridgedAp()
throws Exception {
assumeTrue(SdkLevel.isAtLeastS());
@@ -3866,5 +3920,24 @@
startSoftApAndVerifyEnabled(apConfig, configBuilder.build(), false);
}
+ /**
+ * Tests that 11BE is set to disabled in the SoftApConfiguration if it isn't supported by
+ * SoftApCapability.
+ */
+ @Test
+ public void testStartSoftApRemoves11BEIfNotSupported() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastT());
+ mTestSoftApCapability.setSupportedFeatures(false,
+ SoftApCapability.SOFTAP_FEATURE_IEEE80211_BE);
+ Builder configBuilder = new SoftApConfiguration.Builder();
+ configBuilder.setBand(SoftApConfiguration.BAND_2GHZ);
+ configBuilder.setSsid(TEST_SSID);
+ configBuilder.setIeee80211beEnabled(true);
+ SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
+ WifiManager.IFACE_IP_MODE_TETHERED, configBuilder.build(),
+ mTestSoftApCapability, TEST_COUNTRY_CODE);
+ SoftApConfiguration expectedConfig = configBuilder.setIeee80211beEnabled(false).build();
+ startSoftApAndVerifyEnabled(apConfig, expectedConfig, false);
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java
index e3f0695..da6d2b7 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java
@@ -1349,6 +1349,30 @@
}
/**
+ * Tests the handling of incorrect network password for AP_BUSY error code
+ *
+ * If the disconnect reason is "NO_MORE_STAS - Disassociated because AP is unable
+ * to handle all currently associated STAs", do not call it a password mismatch.
+ */
+ @Test
+ public void testApBusy() throws Exception {
+ executeAndValidateInitializationSequence();
+ assertNotNull(mISupplicantStaIfaceCallback);
+
+ int reasonCode = StaIfaceReasonCode.DISASSOC_AP_BUSY;
+
+ mISupplicantStaIfaceCallback.onStateChanged(
+ StaIfaceCallbackState.FOURWAY_HANDSHAKE,
+ NativeUtil.macAddressToByteArray(BSSID),
+ SUPPLICANT_NETWORK_ID,
+ NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(SUPPLICANT_SSID)), false);
+ mISupplicantStaIfaceCallback.onDisconnected(
+ NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
+ verify(mWifiMonitor, never()).broadcastAuthenticationFailureEvent(any(), anyInt(),
+ anyInt(), any(), any());
+ }
+
+ /**
* Tests the handling of eap failure during disconnect.
*/
@Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java
index 7f01d7b..16bcdf0 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java
@@ -1586,6 +1586,30 @@
}
/**
+ * Tests the handling of incorrect network password for AP_BUSY error code
+ *
+ * If the disconnect reason is "NO_MORE_STAS - Disassociated because AP is unable
+ * to handle all currently associated STAs", do not call it a password mismatch.
+ */
+ @Test
+ public void testApBusy() throws Exception {
+ executeAndValidateInitializationSequence();
+ assertNotNull(mISupplicantStaIfaceCallback);
+
+ int reasonCode = ISupplicantStaIfaceCallback.ReasonCode.DISASSOC_AP_BUSY;
+
+ mISupplicantStaIfaceCallback.onStateChanged(
+ ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE,
+ NativeUtil.macAddressToByteArray(BSSID),
+ SUPPLICANT_NETWORK_ID,
+ NativeUtil.decodeSsid(SUPPLICANT_SSID));
+ mISupplicantStaIfaceCallback.onDisconnected(
+ NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
+ verify(mWifiMonitor, never()).broadcastAuthenticationFailureEvent(any(), anyInt(),
+ anyInt(), any(), any());
+ }
+
+ /**
* Tests the handling of eap failure during disconnect.
*/
@Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
index 66e3f8a..4e91710 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
@@ -22,6 +22,8 @@
import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE;
import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION;
+import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDGE;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertArrayEquals;
@@ -50,6 +52,7 @@
import android.os.Build;
import android.os.Handler;
import android.os.test.TestLooper;
+import android.util.SparseArray;
import androidx.test.filters.SmallTest;
@@ -97,6 +100,7 @@
@Mock private Context mContext;
@Mock private WifiInjector mWifiInjector;
+ @Mock private WifiNative mWifiNative;
@Mock private WifiMetrics mWifiMetrics;
private TestLooper mLooper;
private Handler mHandler;
@@ -141,8 +145,20 @@
mRandom = new Random();
when(mWifiInjector.getMacAddressUtil()).thenReturn(mMacAddressUtil);
+ when(mWifiInjector.getWifiNative()).thenReturn(mWifiNative);
when(mMacAddressUtil.calculatePersistentMacForSap(any(), anyInt()))
.thenReturn(TEST_RANDOMIZED_MAC);
+ when(mWifiNative.canDeviceSupportCreateTypeCombo(any()))
+ .thenAnswer(answer -> {
+ SparseArray<Integer> combo = answer.getArgument(0);
+ if (combo.contentEquals(new SparseArray<Integer>() {{
+ put(HDM_CREATE_IFACE_AP_BRIDGE, 1);
+ }})) {
+ return true;
+ }
+ return false;
+ });
+
mResources.setBoolean(R.bool.config_wifi_ap_mac_randomization_supported, true);
mResources.setBoolean(
R.bool.config_wifiSoftapAutoAppendLowerBandsToBandConfigurationEnabled, true);
@@ -527,7 +543,8 @@
// Default, new feature doesn't supported
WifiApConfigStore store = createWifiApConfigStore();
SoftApConfiguration config = store.getApConfiguration();
- assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
}
/**
@@ -543,7 +560,8 @@
SoftApConfiguration.BAND_2GHZ);
// verify that the config passes the validateApWifiConfiguration check
- assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
}
/**
@@ -562,9 +580,9 @@
.generateLocalOnlyHotspotConfig(mContext, null, mSoftApCapability);
verifyDefaultLocalOnlyApConfig(config, TEST_DEFAULT_HOTSPOT_SSID,
SoftApConfiguration.BAND_5GHZ);
-
// verify that the config passes the validateApWifiConfiguration check
- assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
}
/**
@@ -583,7 +601,8 @@
SoftApConfiguration.BAND_2GHZ);
// verify that the config passes the validateApWifiConfiguration check
- assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
}
/**
@@ -607,7 +626,8 @@
.build();
// verify that the config passes the validateApWifiConfiguration check
- assertTrue(WifiApConfigStore.validateApWifiConfiguration(updatedConfig, true, mContext));
+ assertTrue(WifiApConfigStore.validateApWifiConfiguration(updatedConfig, true, mContext,
+ mWifiNative));
}
/**
@@ -626,7 +646,8 @@
SoftApConfiguration.BAND_2GHZ);
// verify that the config passes the validateApWifiConfiguration check
- assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
}
@Test
@@ -786,12 +807,12 @@
configBuilder.setSsid(null);
// Invalid due to null SSID.
assertFalse(WifiApConfigStore.validateApWifiConfiguration(
- configBuilder.build(), true, mContext));
+ configBuilder.build(), true, mContext, mWifiNative));
// SSID is set, so the config is now valid.
configBuilder.setSsid("ssid");
assertTrue(WifiApConfigStore.validateApWifiConfiguration(
- configBuilder.build(), true, mContext));
+ configBuilder.build(), true, mContext, mWifiNative));
}
/**
@@ -806,23 +827,23 @@
// OPEN
configBuilder.setPassphrase(null, SoftApConfiguration.SECURITY_TYPE_OPEN);
assertFalse(WifiApConfigStore.validateApWifiConfiguration(
- configBuilder.build(), true, mContext));
+ configBuilder.build(), true, mContext, mWifiNative));
// WPA2
configBuilder.setPassphrase("somepassword", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK);
assertFalse(WifiApConfigStore.validateApWifiConfiguration(
- configBuilder.build(), true, mContext));
+ configBuilder.build(), true, mContext, mWifiNative));
// WPA3 SAE (should succeed)
configBuilder.setPassphrase("somepassword", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE);
assertTrue(WifiApConfigStore.validateApWifiConfiguration(
- configBuilder.build(), true, mContext));
+ configBuilder.build(), true, mContext, mWifiNative));
// WPA3 SAE-Transition
configBuilder.setPassphrase("somepassword",
SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION);
assertFalse(WifiApConfigStore.validateApWifiConfiguration(
- configBuilder.build(), true, mContext));
+ configBuilder.build(), true, mContext, mWifiNative));
if (SdkLevel.isAtLeastT()) {
// WPA3 OWE-Transition
@@ -830,7 +851,7 @@
configBuilder.setPassphrase(null,
SoftApConfiguration.SECURITY_TYPE_WPA3_OWE_TRANSITION);
assertFalse(WifiApConfigStore.validateApWifiConfiguration(
- configBuilder.build(), true, mContext));
+ configBuilder.build(), true, mContext, mWifiNative));
}
}
}
@@ -847,7 +868,7 @@
assertTrue(WifiApConfigStore.validateApWifiConfiguration(
new SoftApConfiguration.Builder()
.setSsid(TEST_DEFAULT_HOTSPOT_SSID)
- .build(), true, mContext));
+ .build(), true, mContext, mWifiNative));
}
/**
@@ -869,7 +890,7 @@
generateRandomString(mRandom.nextInt(maxLen - minLen) + minLen),
SoftApConfiguration.SECURITY_TYPE_WPA2_PSK);
assertTrue(WifiApConfigStore.validateApWifiConfiguration(
- configBuilder.build(), true, mContext));
+ configBuilder.build(), true, mContext, mWifiNative));
}
@Test
@@ -883,7 +904,7 @@
generateRandomString(maxLen + 1),
SoftApConfiguration.SECURITY_TYPE_WPA3_SAE);
assertFalse(WifiApConfigStore.validateApWifiConfiguration(
- configBuilder.build(), true, mContext));
+ configBuilder.build(), true, mContext, mWifiNative));
}
@@ -903,11 +924,11 @@
"測試測試測試測試",
SoftApConfiguration.SECURITY_TYPE_WPA2_PSK);
assertFalse(WifiApConfigStore.validateApWifiConfiguration(
- configBuilder.build(), true, mContext));
+ configBuilder.build(), true, mContext, mWifiNative));
// Disable ascii encodable check
mResources.setBoolean(R.bool.config_wifiSoftapPassphraseAsciiEncodableCheck, false);
assertTrue(WifiApConfigStore.validateApWifiConfiguration(
- configBuilder.build(), true, mContext));
+ configBuilder.build(), true, mContext, mWifiNative));
}
@@ -936,7 +957,8 @@
SoftApConfiguration.BAND_2GHZ, true);
// verify that the config passes the validateApWifiConfiguration check
- assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
}
@@ -954,7 +976,8 @@
SoftApConfiguration.BAND_2GHZ, true, true);
// verify that the config passes the validateApWifiConfiguration check
- assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
}
/**
@@ -973,7 +996,8 @@
SoftApConfiguration.BAND_2GHZ, true, false);
// verify that the config passes the validateApWifiConfiguration check
- assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
}
/**
@@ -997,7 +1021,8 @@
SoftApConfiguration.BAND_2GHZ, true, false);
// verify that the config passes the validateApWifiConfiguration check
- assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
}
@@ -1186,7 +1211,7 @@
configBuilder.setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE);
}
assertFalse(WifiApConfigStore.validateApWifiConfiguration(configBuilder.build(),
- false, mContext));
+ false, mContext, mWifiNative));
}
/**
@@ -1202,7 +1227,7 @@
configBuilder.setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE);
}
assertTrue(WifiApConfigStore.validateApWifiConfiguration(configBuilder.build(),
- true, mContext));
+ true, mContext, mWifiNative));
}
@Test
@@ -1211,38 +1236,47 @@
SoftApConfiguration config = new SoftApConfiguration.Builder(store.getApConfiguration())
.setBand(mBand25660G).build();
// Default is all bands supported.
- assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertTrue(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
mResources.setBoolean(R.bool.config_wifi24ghzSupport, false);
- assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
setupAllBandsSupported();
mResources.setBoolean(R.bool.config_wifiSoftap24ghzSupported, false);
- assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
setupAllBandsSupported();
mResources.setBoolean(R.bool.config_wifi5ghzSupport, false);
- assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
setupAllBandsSupported();
mResources.setBoolean(R.bool.config_wifiSoftap5ghzSupported, false);
- assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
setupAllBandsSupported();
mResources.setBoolean(R.bool.config_wifi6ghzSupport, false);
- assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
setupAllBandsSupported();
mResources.setBoolean(R.bool.config_wifiSoftap6ghzSupported, false);
- assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
setupAllBandsSupported();
mResources.setBoolean(R.bool.config_wifi60ghzSupport, false);
- assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
setupAllBandsSupported();
mResources.setBoolean(R.bool.config_wifiSoftap60ghzSupported, false);
- assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext));
+ assertFalse(WifiApConfigStore.validateApWifiConfiguration(config, true, mContext,
+ mWifiNative));
}
@Test
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 74e4d5e..99ea3f7 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -1924,6 +1924,101 @@
}
/**
+ * Verify that the protected WifiEnterpriseConfig fields are set correctly.
+ */
+ @Test
+ public void testWifiEnterpriseConfigProtectedFields() {
+ // Add an external config. Expect the internal config to have the default values.
+ WifiConfiguration externalConfig = WifiConfigurationTestUtil.createEapNetwork();
+ externalConfig.enterpriseConfig.setUserApproveNoCaCert(true);
+ externalConfig.enterpriseConfig.setTofuDialogState(
+ WifiEnterpriseConfig.TOFU_DIALOG_STATE_ACCEPTED);
+
+ NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(externalConfig);
+ WifiConfiguration internalConfig = mWifiConfigManager.getConfiguredNetwork(
+ result.getNetworkId());
+ assertFalse(internalConfig.enterpriseConfig.isUserApproveNoCaCert());
+ assertEquals(
+ WifiEnterpriseConfig.TOFU_DIALOG_STATE_UNSPECIFIED,
+ internalConfig.enterpriseConfig.getTofuDialogState());
+
+ // Update using an external config. Expect internal config to retain the default values.
+ result = verifyUpdateNetworkToWifiConfigManager(externalConfig);
+ internalConfig = mWifiConfigManager.getConfiguredNetwork(
+ result.getNetworkId());
+ assertFalse(internalConfig.enterpriseConfig.isUserApproveNoCaCert());
+ assertEquals(
+ WifiEnterpriseConfig.TOFU_DIALOG_STATE_UNSPECIFIED,
+ internalConfig.enterpriseConfig.getTofuDialogState());
+
+ // If the internal config's values are updated by the framework, merging
+ // with an external config should not overwrite the internal values.
+ mWifiConfigManager.setUserApproveNoCaCert(externalConfig.networkId, true);
+ mWifiConfigManager.setTofuDialogApproved(externalConfig.networkId, true);
+ externalConfig.enterpriseConfig.setUserApproveNoCaCert(false);
+ externalConfig.enterpriseConfig.setTofuDialogApproved(false);
+
+ result = verifyUpdateNetworkToWifiConfigManager(externalConfig);
+ internalConfig = mWifiConfigManager.getConfiguredNetwork(
+ result.getNetworkId());
+ assertTrue(internalConfig.enterpriseConfig.isUserApproveNoCaCert());
+ assertEquals(
+ WifiEnterpriseConfig.TOFU_DIALOG_STATE_ACCEPTED,
+ internalConfig.enterpriseConfig.getTofuDialogState());
+ }
+
+ /**
+ * Verify that the TOFU connection state is set correctly when an Enterprise config is added or
+ * updated.
+ */
+ @Test
+ public void testEnterpriseConfigTofuStateMerge() {
+ long featureSet = WifiManager.WIFI_FEATURE_TRUST_ON_FIRST_USE;
+ when(mPrimaryClientModeManager.getSupportedFeatures()).thenReturn(featureSet);
+
+ // If the configuration has never connected, the merged TOFU connection state
+ // should be set based on the latest external configuration.
+ WifiConfiguration config =
+ prepareTofuEapConfig(
+ WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE);
+ config.enterpriseConfig.enableTrustOnFirstUse(false);
+ NetworkUpdateResult result = addNetworkToWifiConfigManager(config);
+ WifiConfiguration internalConfig =
+ mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+ assertEquals(
+ WifiEnterpriseConfig.TOFU_STATE_NOT_ENABLED,
+ internalConfig.enterpriseConfig.getTofuConnectionState());
+
+ // Enabling TOFU in the external config should lead to the Enabled Pre-Connection state.
+ config.enterpriseConfig.enableTrustOnFirstUse(true);
+ config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
+ result = updateNetworkToWifiConfigManager(config);
+ internalConfig = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+ assertEquals(
+ WifiEnterpriseConfig.TOFU_STATE_ENABLED_PRE_CONNECTION,
+ internalConfig.enterpriseConfig.getTofuConnectionState());
+
+ // Invalid post-connection values in the external config should be ignored,
+ // since external configs should not be setting their own TOFU connection state.
+ config.enterpriseConfig.setTofuConnectionState(
+ WifiEnterpriseConfig.TOFU_STATE_CERT_PINNING);
+ result = updateNetworkToWifiConfigManager(config);
+ internalConfig = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+ assertEquals(
+ WifiEnterpriseConfig.TOFU_STATE_ENABLED_PRE_CONNECTION,
+ internalConfig.enterpriseConfig.getTofuConnectionState());
+
+ // Post-connection states in the internal config should always persist.
+ mWifiConfigManager.setTofuPostConnectionState(
+ result.getNetworkId(), WifiEnterpriseConfig.TOFU_STATE_CERT_PINNING);
+ result = updateNetworkToWifiConfigManager(config);
+ internalConfig = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+ assertEquals(
+ WifiEnterpriseConfig.TOFU_STATE_CERT_PINNING,
+ internalConfig.enterpriseConfig.getTofuConnectionState());
+ }
+
+ /**
* Verifies the modification of a single network using
* {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} by passing in nulls
* in all the publicly exposed fields.
@@ -7270,6 +7365,36 @@
}
/**
+ * Verify that the protected WifiEnterpriseConfig fields are loaded correctly
+ * from the XML store.
+ */
+ @Test
+ public void testLoadEnterpriseConfigProtectedFields() throws Exception {
+ WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
+ config.enterpriseConfig.setUserApproveNoCaCert(true);
+ config.enterpriseConfig.setTofuDialogState(WifiEnterpriseConfig.TOFU_DIALOG_STATE_ACCEPTED);
+ config.enterpriseConfig.setTofuConnectionState(
+ WifiEnterpriseConfig.TOFU_STATE_CERT_PINNING);
+ List<WifiConfiguration> storedConfigs = Arrays.asList(config);
+
+ // Setup xml storage
+ setupStoreDataForRead(storedConfigs, Arrays.asList());
+ assertTrue(mWifiConfigManager.loadFromStore());
+ verify(mWifiConfigStore).read();
+
+ List<WifiConfiguration> retrievedNetworks =
+ mWifiConfigManager.getConfiguredNetworksWithPasswords();
+ assertEquals(1, retrievedNetworks.size());
+ assertTrue(retrievedNetworks.get(0).enterpriseConfig.isUserApproveNoCaCert());
+ assertEquals(
+ WifiEnterpriseConfig.TOFU_DIALOG_STATE_ACCEPTED,
+ retrievedNetworks.get(0).enterpriseConfig.getTofuDialogState());
+ assertEquals(
+ WifiEnterpriseConfig.TOFU_STATE_CERT_PINNING,
+ retrievedNetworks.get(0).enterpriseConfig.getTofuConnectionState());
+ }
+
+ /**
* Verify that updating an existing config to a incompatible type works well.
*/
@Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
index 42f9c6a..0abc488 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
@@ -77,6 +77,9 @@
public static final String[] TEST_WEP_KEYS =
{"\"WifiTestWep12\"", "\"WifiTestWep34\"",
"45342312ab", "45342312ab45342312ab34ac12"};
+ public static final String[] TEST_WEP_KEYS_WITH_NULL = {
+ "\"WifiTestWep12\"", "\"WifiTestWep34\"", "45342312ab45342312ab34ac12", null
+ };
public static final String TEST_EAP_PASSWORD = "WifiConfigurationTestUtilEapPassword";
public static final int TEST_WEP_TX_KEY_INDEX = 1;
public static final String TEST_FQDN = "WifiConfigurationTestUtilFQDN";
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiDialogManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiDialogManagerTest.java
index dc837eb..794629c 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiDialogManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiDialogManagerTest.java
@@ -61,6 +61,7 @@
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -84,6 +85,9 @@
@Mock Resources mResources;
@Mock PowerManager mPowerManager;
@Mock ActivityManager mActivityManager;
+ @Mock WifiInjector mWifiInjector;
+ @Mock WifiDeviceStateChangeManager mWifiDeviceStateChangeManager;
+ @Captor ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverArgumentCaptor;
private WifiDialogManager mDialogManager;
@Before
@@ -94,11 +98,15 @@
when(mWifiContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager);
when(mWifiContext.getResources()).thenReturn(mResources);
when(mPowerManager.isInteractive()).thenReturn(true);
+ when(mWifiInjector.getWifiDeviceStateChangeManager())
+ .thenReturn(mWifiDeviceStateChangeManager);
doThrow(SecurityException.class).when(mWifiContext).startActivityAsUser(any(), any(),
any());
mDialogManager =
- new WifiDialogManager(mWifiContext, mWifiThreadRunner, mFrameworkFacade);
+ new WifiDialogManager(mWifiContext, mWifiThreadRunner, mFrameworkFacade, mWifiInjector);
mDialogManager.enableVerboseLogging(true);
+ verify(mWifiContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(), any(),
+ eq(SdkLevel.isAtLeastT() ? Context.RECEIVER_EXPORTED : 0));
}
private void dispatchMockWifiThreadRunner(WifiThreadRunner wifiThreadRunner) {
@@ -754,11 +762,7 @@
// ACTION_CLOSE_SYSTEM_DIALOGS with EXTRA_CLOSE_SYSTEM_DIALOGS_EXCEPT_WIFI should be
// ignored.
- ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor = ArgumentCaptor.forClass(
- BroadcastReceiver.class);
- verify(mWifiContext).registerReceiver(broadcastReceiverCaptor.capture(), any(),
- eq(SdkLevel.isAtLeastT() ? Context.RECEIVER_EXPORTED : 0));
- broadcastReceiverCaptor.getValue().onReceive(mWifiContext,
+ mBroadcastReceiverArgumentCaptor.getValue().onReceive(mWifiContext,
new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
.putExtra(WifiManager.EXTRA_CLOSE_SYSTEM_DIALOGS_EXCEPT_WIFI, true));
dispatchMockWifiThreadRunner(mWifiThreadRunner);
@@ -767,7 +771,7 @@
// ACTION_CLOSE_SYSTEM_DIALOGS due to screen off should be ignored.
when(mPowerManager.isInteractive()).thenReturn(false);
- broadcastReceiverCaptor.getValue().onReceive(mWifiContext,
+ mBroadcastReceiverArgumentCaptor.getValue().onReceive(mWifiContext,
new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
dispatchMockWifiThreadRunner(mWifiThreadRunner);
@@ -775,7 +779,7 @@
// ACTION_CLOSE_SYSTEM_DIALOGS while screen on should cancel the dialog.
when(mPowerManager.isInteractive()).thenReturn(true);
- broadcastReceiverCaptor.getValue().onReceive(mWifiContext,
+ mBroadcastReceiverArgumentCaptor.getValue().onReceive(mWifiContext,
new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
dispatchMockWifiThreadRunner(mWifiThreadRunner);
@@ -811,15 +815,13 @@
launchDialogSynchronous(dialogHandle, TIMEOUT_MILLIS, mWifiThreadRunner);
verify(window).setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
- // Receive ACTION_SCREEN_OFF.
+ // Receive screen off event.
when(dialog.isShowing()).thenReturn(true);
- ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor = ArgumentCaptor.forClass(
- BroadcastReceiver.class);
- verify(mWifiContext).registerReceiver(broadcastReceiverCaptor.capture(), any(),
- eq(SdkLevel.isAtLeastT() ? Context.RECEIVER_EXPORTED : 0));
- broadcastReceiverCaptor.getValue().onReceive(mWifiContext,
- new Intent(Intent.ACTION_SCREEN_OFF));
- dispatchMockWifiThreadRunner(mWifiThreadRunner);
+ ArgumentCaptor<WifiDeviceStateChangeManager.StateChangeCallback> callbackArgumentCaptor =
+ ArgumentCaptor.forClass(WifiDeviceStateChangeManager.StateChangeCallback.class);
+ verify(mWifiDeviceStateChangeManager).registerStateChangeCallback(
+ callbackArgumentCaptor.capture());
+ callbackArgumentCaptor.getValue().onScreenStateChanged(false);
// Verify dialog was dismissed and relaunched with window type TYPE_APPLICATION_OVERLAY.
verify(dialog, never()).cancel();
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index 7f2be4b..98fe4b5 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -8693,6 +8693,16 @@
validateWifiActivityEnergyInfo(infoCaptor.getValue());
}
+ /**
+ * Tests that {@link WifiServiceImpl#getWifiActivityEnergyInfoAsync} throws exception when
+ * listener is null
+ */
+ @Test
+ public void getWifiActivityEnergyInfoWithNullListener() throws Exception {
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiServiceImpl.getWifiActivityEnergyInfoAsync(null));
+ }
+
@Test
public void testCarrierConfigChangeUpdateSoftApCapability() throws Exception {
lenient().when(SubscriptionManager.getActiveDataSubscriptionId())
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 546da0c..88e869a 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
@@ -172,6 +172,7 @@
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -7013,6 +7014,27 @@
WpsInfo.PBC, WifiP2pManager.CONNECTION_REQUEST_ACCEPT);
}
+ /** Verify the failure scenario for setConnectionRequestResult without a saved peer config. */
+ @Test
+ public void testSetConnectionRequestResultFailureWithoutSavedPeerConfig() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
+ .thenReturn(true);
+ when(mWifiPermissionsUtil.checkNearbyDevicesPermission(any(), anyBoolean(), any()))
+ .thenReturn(true);
+ Binder binder = new Binder();
+ mockEnterGroupCreatedState();
+ sendSetConnectionRequestResultMsg(
+ mClientMessenger,
+ MacAddress.fromString(mTestWifiP2pDevice.deviceAddress),
+ WifiP2pManager.CONNECTION_REQUEST_ACCEPT,
+ binder);
+ ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ verify(mClientHandler).sendMessage(messageCaptor.capture());
+ List<Message> messages = messageCaptor.getAllValues();
+ assertEquals(WifiP2pManager.SET_CONNECTION_REQUEST_RESULT_FAILED, messages.get(0).what);
+ }
+
/**
* Verify that deferring pin to the framework works normally.
*/
@@ -7630,4 +7652,130 @@
verify(mWifiNative, never()).configureEapolIpAddressAllocationParams(anyInt(),
anyInt(), anyInt(), anyInt());
}
+
+ @Test
+ public void testSendP2pConnectionChangedBroadcast() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastT());
+ when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ ArgumentCaptor<String[]> permissionCaptor = ArgumentCaptor.forClass(String[].class);
+ String[] receiverPermissions;
+ int flags = Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT;
+
+ // mock p2p enabled
+ forceP2pEnabled(mClient1);
+ if (!SdkLevel.isAtLeastU()) {
+ receiverPermissions = new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION,
+ android.Manifest.permission.ACCESS_WIFI_STATE};
+ verify(mContext).sendBroadcastWithMultiplePermissions(argThat((Intent intent) -> {
+ WifiP2pInfo p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
+ WifiP2pGroup p2pGroup = intent.getParcelableExtra(
+ WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
+ assert p2pInfo != null;
+ return intent.getAction().equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)
+ && intent.getFlags() == Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ && Objects.isNull(intent.getPackage())
+ && !p2pInfo.groupFormed && Objects.isNull(p2pGroup);
+ }), permissionCaptor.capture());
+ assertEquals(receiverPermissions, permissionCaptor.getValue());
+ } else {
+ receiverPermissions = new String[]{NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK};
+ flags |= Intent.FLAG_RECEIVER_FOREGROUND;
+ verify(mContext).sendBroadcastWithMultiplePermissions(intentCaptor.capture(),
+ permissionCaptor.capture());
+ Intent intent = intentCaptor.getValue();
+ assertEquals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION, intent.getAction());
+ assertEquals(flags, intent.getFlags());
+ WifiP2pInfo p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
+ WifiP2pGroup p2pGroup = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
+ assert p2pInfo != null;
+ assertFalse(p2pInfo.groupFormed);
+ assertFalse(p2pInfo.isGroupOwner);
+ assertNull(p2pGroup);
+ assertEquals(receiverPermissions, permissionCaptor.getValue());
+ }
+
+ // mock group started
+ WifiP2pGroup group = new WifiP2pGroup();
+ group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
+ group.setNetworkName("DIRECT-xy-NEW");
+ group.setOwner(new WifiP2pDevice("thisDeviceMac"));
+ group.setIsGroupOwner(true);
+ group.setInterface(IFACE_NAME_P2P);
+ sendGroupStartedMsg(group);
+ simulateTetherReady();
+
+ // reassign captor again, otherwise captor.getAllValues() will include previous values
+ intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ permissionCaptor = ArgumentCaptor.forClass(String[].class);
+ if (!SdkLevel.isAtLeastU()) {
+ // there are other broadcasts from sendThisDeviceChangedBroadcast() called by
+ // updateThisDevice()
+ verify(mContext, times(6)).sendBroadcastWithMultiplePermissions(intentCaptor.capture(),
+ permissionCaptor.capture());
+ } else {
+ verify(mContext, times(3)).sendBroadcastWithMultiplePermissions(intentCaptor.capture(),
+ permissionCaptor.capture());
+ }
+ ArrayList<Intent> intentArrayList = new ArrayList<>();
+ ArrayList<String[]> permissionArrayList = new ArrayList<>();
+ for (int i = 0; i < intentCaptor.getAllValues().size(); i++) {
+ Intent intent = intentCaptor.getAllValues().get(i);
+ if (intent.getAction().equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
+ intentArrayList.add(intent);
+ permissionArrayList.add(permissionCaptor.getAllValues().get(i));
+ }
+ }
+ assertEquals(3, intentArrayList.size());
+ /* Total three WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION broadcasts are as follows.
+ * ----------------------------------------------------------------------------------------
+ * State p2pInfo.groupFormed p2pGroup intent.permission intent.flag intent.package
+ * ----------------------------------------------------------------------------------------
+ * PreU:
+ * P2pEnabledState :false null RECEIVER_PERMISSIONS_FOR_BROADCAST(location ON)
+ * Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ * null
+ * GroupCreatingState :false p2pGroup.isGo RECEIVER_PERMISSIONS_FOR_BROADCAST(location ON)
+ * Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ * null
+ * GroupNegotiationState:true p2pGroup.isGo android.Manifest.permission.TETHER_PRIVILEGED
+ * Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ * com.android.networkstack.tethering
+ *
+ * PostU:
+ * P2pEnabledState : false null android.permission.MAINLINE_NETWORK_STACK
+ * Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT|Intent.FLAG_RECEIVER_FOREGROUND
+ * null
+ * GroupCreatingState : false p2pGroup.isGo android.permission.MAINLINE_NETWORK_STACK
+ * Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT|Intent.FLAG_RECEIVER_FOREGROUND
+ * null
+ * GroupNegotiationState: true p2pGroup.isGo android.permission.MAINLINE_NETWORK_STACK
+ * Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT|Intent.FLAG_RECEIVER_FOREGROUND
+ * com.android.networkstack.tethering
+ */
+ Intent intent = intentArrayList.get(1);
+ assertEquals(flags, intent.getFlags());
+ assertNull(intent.getPackage());
+ WifiP2pInfo p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
+ assert p2pInfo != null;
+ assertFalse(p2pInfo.groupFormed);
+ WifiP2pGroup p2pGroup = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
+ assert p2pGroup != null;
+ assertTrue(p2pGroup.isGroupOwner());
+ assertEquals(receiverPermissions, permissionArrayList.get(1));
+
+ intent = intentArrayList.get(2);
+ assertEquals(flags, intent.getFlags());
+ assertNotNull(intent.getPackage());
+ p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
+ assert p2pInfo != null;
+ assertTrue(p2pInfo.groupFormed);
+ p2pGroup = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
+ assert p2pGroup != null;
+ assertTrue(p2pGroup.isGroupOwner());
+ if (!SdkLevel.isAtLeastU()) {
+ receiverPermissions = new String[]{android.Manifest.permission.TETHER_PRIVILEGED};
+ }
+ assertEquals(receiverPermissions, permissionArrayList.get(2));
+ }
}
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 fc393d3..40f1c53 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
@@ -16,6 +16,11 @@
package com.android.server.wifi.util;
+import static android.net.wifi.SoftApCapability.SOFTAP_FEATURE_IEEE80211_BE;
+
+import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDGE;
+import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_STA;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -23,6 +28,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@@ -41,6 +47,7 @@
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
+import android.util.SparseArray;
import android.util.SparseIntArray;
import androidx.test.filters.SmallTest;
@@ -49,6 +56,7 @@
import com.android.server.wifi.SoftApManager;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiNative;
+import com.android.server.wifi.WifiSettingsConfigStore;
import com.android.server.wifi.coex.CoexManager;
import com.android.wifi.resources.R;
@@ -155,7 +163,10 @@
@Mock Resources mResources;
@Mock WifiNative mWifiNative;
@Mock CoexManager mCoexManager;
+ @Mock WifiSettingsConfigStore mConfigStore;
private SoftApCapability mCapability;
+ private boolean mApBridgeIfaceCobinationSupported = false;
+ private boolean mApBridgeWithStaIfaceCobinationSupported = false;
/**
* Setup test.
*/
@@ -169,11 +180,93 @@
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(mContext.getResources()).thenReturn(mResources);
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(mResources.getBoolean(R.bool.config_wifiBridgedSoftApSupported)).thenReturn(true);
+ when(mResources.getBoolean(
+ R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported)).thenReturn(true);
when(mWifiNative.getUsableChannels(anyInt(), anyInt(), anyInt())).thenReturn(null);
+ when(mConfigStore.get(
+ WifiSettingsConfigStore.WIFI_WIPHY_11BE_SUPPORTED)).thenReturn(false);
+ when(mWifiNative.canDeviceSupportCreateTypeCombo(any()))
+ .thenAnswer(answer -> {
+ SparseArray<Integer> combo = answer.getArgument(0);
+ if (combo.contentEquals(new SparseArray<Integer>() {{
+ put(HDM_CREATE_IFACE_AP_BRIDGE, 1);
+ }})) {
+ return mApBridgeIfaceCobinationSupported;
+ }
+ if (combo.contentEquals(new SparseArray<Integer>() {{
+ put(HDM_CREATE_IFACE_AP_BRIDGE, 1);
+ put(HDM_CREATE_IFACE_STA, 1);
+ }})) {
+ return mApBridgeWithStaIfaceCobinationSupported;
+ }
+ return false;
+ });
+ }
+
+ /**
+ * Verify Bridge AP support when Iface combination for AP bridge is allowed.
+ */
+ @Test
+ public void testIsBridgeApSupportedWhenIfaceCombinationForBridgeIsEnabled() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ mApBridgeIfaceCobinationSupported = true;
+ assertTrue("Bridge AP is not supported even when Combination is allowed.",
+ ApConfigUtil.isBridgedModeSupported(mContext, mWifiNative));
+ }
+
+ /**
+ * Verify Bridge AP support when Iface combination for AP bridge is not allowed.
+ */
+ @Test
+ public void testIsBridgeApSupportedWhenIfaceCombinationForBridgeIsDisabled() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ mApBridgeIfaceCobinationSupported = false;
+ assertFalse("Bridge AP is supported even when Combination is not allowed.",
+ ApConfigUtil.isStaWithBridgedModeSupported(mContext, mWifiNative));
+ }
+
+ /**
+ * Verify Bridge AP + STA support when Iface combination for AP bridge with Sta is allowed.
+ */
+ @Test
+ public void testIsBridgeApWithStaSupportedWhenIfaceCombinationForStaBridgeApIsEnabled()
+ throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ mApBridgeWithStaIfaceCobinationSupported = true;
+ assertTrue("Bridge AP with Sta is not supported even when Combination is allowed.",
+ ApConfigUtil.isStaWithBridgedModeSupported(mContext, mWifiNative));
+ }
+
+ /**
+ * Verify Bridge AP + STA support when Iface combination for AP bridge with Sta is not allowed.
+ */
+ @Test
+ public void testIsBridgeApWithStaSupportedWhenIfaceCombinationForStaBridgeApIsDisabled()
+ throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ mApBridgeWithStaIfaceCobinationSupported = false;
+ assertFalse("Bridge AP with Sta is supported even when Combination is not allowed.",
+ ApConfigUtil.isBridgedModeSupported(mContext, mWifiNative));
+ }
+
+ /**
+ * Verify Bridge AP not supported for pre-S.
+ */
+ @Test
+ public void testIsBridgeApSupportedReturnsFalseForPreS() throws Exception {
+ assumeTrue(!SdkLevel.isAtLeastS());
+ mApBridgeIfaceCobinationSupported = true;
+ mApBridgeWithStaIfaceCobinationSupported = true;
+ assertFalse("Bridge AP is supported even for pre-S platform.",
+ ApConfigUtil.isBridgedModeSupported(mContext, mWifiNative));
+ assertFalse("Bridge AP with Sta is supported even for pre-S platform.",
+ ApConfigUtil.isStaWithBridgedModeSupported(mContext, mWifiNative));
}
/**
@@ -731,7 +824,6 @@
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))
@@ -791,7 +883,6 @@
int test_max_client = 10;
capability.setMaxSupportedClients(test_max_client);
- when(mContext.getResources()).thenReturn(mResources);
when(mResources.getInteger(R.integer.config_wifiHardwareSoftapMaxClientCount))
.thenReturn(test_max_client);
when(mResources.getBoolean(R.bool.config_wifi_softap_acs_supported))
@@ -812,6 +903,23 @@
capability);
}
+
+ /**
+ * Verify updating capability from config store.
+ * Force 11BE capa to be true and then try to set it to false
+ * using updateCapabilityFromConfigStore
+ * assert if capability still has 11BE enabled.
+ */
+ @Test
+ public void testSoftApCapabilityInitWithWifiConfiguration() throws Exception {
+ long features = 0;
+ // Forcefully make 11BE as true in capability
+ features |= SOFTAP_FEATURE_IEEE80211_BE;
+ SoftApCapability capability = new SoftApCapability(features);
+ ApConfigUtil.updateCapabilityFromConfigStore(capability, mConfigStore);
+ assertFalse(capability.areFeaturesSupported(SOFTAP_FEATURE_IEEE80211_BE));
+ }
+
@Test
public void testConvertInvalidWifiConfigurationToSoftApConfiguration() throws Exception {
WifiConfiguration wifiConfig = new WifiConfiguration();
@@ -982,7 +1090,6 @@
public void testUpdateBandInConfigOnFindingUnavailableChannels() throws Exception {
SoftApConfiguration config;
SoftApCapability testSoftApCapability = new SoftApCapability(0);
- when(mContext.getResources()).thenReturn(mResources);
if (SdkLevel.isAtLeastS()) {
// 6GHz channels not available - {2GHz|6GHz, 5GHz} => {2GHz, 5GHz}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
index 79d9cce..c6c876e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
@@ -143,7 +143,9 @@
throws IOException, XmlPullParserException {
mWifiConfigStoreEncryptionUtil = mock(WifiConfigStoreEncryptionUtil.class);
WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+ wepNetwork.wepKeys = WifiConfigurationTestUtil.TEST_WEP_KEYS_WITH_NULL;
for (int i = 0; i < wepNetwork.wepKeys.length; i++) {
+ if (wepNetwork.wepKeys[i] == null) continue;
EncryptedData encryptedData = new EncryptedData(new byte[]{(byte) i},
new byte[]{(byte) i});
when(mWifiConfigStoreEncryptionUtil.encrypt(wepNetwork.wepKeys[i].getBytes()))
@@ -163,7 +165,9 @@
throws IOException, XmlPullParserException {
mWifiConfigStoreEncryptionUtil = mock(WifiConfigStoreEncryptionUtil.class);
WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+ wepNetwork.wepKeys = WifiConfigurationTestUtil.TEST_WEP_KEYS_WITH_NULL;
for (int i = 0; i < wepNetwork.wepKeys.length; i++) {
+ if (wepNetwork.wepKeys[i] == null) continue;
when(mWifiConfigStoreEncryptionUtil.encrypt(wepNetwork.wepKeys[i].getBytes()))
.thenReturn(null);
}