Merge "[WifiTrackerLib] Fix OWE security parsing for WifiEntry" into rvc-dev
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java
index 9aaf346..b3b99e0 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java
@@ -35,6 +35,7 @@
import android.text.TextUtils;
import android.util.Pair;
+import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
@@ -50,6 +51,9 @@
class OsuWifiEntry extends WifiEntry {
static final String KEY_PREFIX = "OsuWifiEntry:";
+ private final Object mLock = new Object();
+ // Scan result list must be thread safe for generating the verbose scan summary
+ @GuardedBy("mLock")
@NonNull private final List<ScanResult> mCurrentScanResults = new ArrayList<>();
@NonNull private final String mKey;
@@ -265,10 +269,12 @@
throws IllegalArgumentException {
if (scanResults == null) scanResults = new ArrayList<>();
- mCurrentScanResults.clear();
- mCurrentScanResults.addAll(scanResults);
+ synchronized (mLock) {
+ mCurrentScanResults.clear();
+ mCurrentScanResults.addAll(scanResults);
+ }
- final ScanResult bestScanResult = getBestScanResultByLevel(mCurrentScanResults);
+ final ScanResult bestScanResult = getBestScanResultByLevel(scanResults);
if (bestScanResult == null) {
mLevel = WIFI_LEVEL_UNREACHABLE;
} else {
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java
index b26d035..e7ed153 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java
@@ -40,6 +40,7 @@
import android.os.Handler;
import android.text.TextUtils;
+import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
@@ -57,7 +58,11 @@
public class PasspointWifiEntry extends WifiEntry {
static final String KEY_PREFIX = "PasspointWifiEntry:";
+ private final Object mLock = new Object();
+ // Scan result list must be thread safe for generating the verbose scan summary
+ @GuardedBy("mLock")
private final List<ScanResult> mCurrentHomeScanResults = new ArrayList<>();
+ @GuardedBy("mLock")
private final List<ScanResult> mCurrentRoamingScanResults = new ArrayList<>();
@NonNull private final String mKey;
@@ -405,13 +410,15 @@
throws IllegalArgumentException {
mIsRoaming = false;
mWifiConfig = wifiConfig;
- mCurrentHomeScanResults.clear();
- mCurrentRoamingScanResults.clear();
- if (homeScanResults != null) {
- mCurrentHomeScanResults.addAll(homeScanResults);
- }
- if (roamingScanResults != null) {
- mCurrentRoamingScanResults.addAll(roamingScanResults);
+ synchronized (mLock) {
+ mCurrentHomeScanResults.clear();
+ mCurrentRoamingScanResults.clear();
+ if (homeScanResults != null) {
+ mCurrentHomeScanResults.addAll(homeScanResults);
+ }
+ if (roamingScanResults != null) {
+ mCurrentRoamingScanResults.addAll(roamingScanResults);
+ }
}
if (mWifiConfig != null) {
mSecurity = getSecurityTypeFromWifiConfiguration(wifiConfig);
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java
index d30fcc4..68f58dd 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java
@@ -45,7 +45,6 @@
import java.time.Clock;
import java.util.Collections;
-import java.util.Optional;
/**
* Implementation of NetworkDetailsTracker that tracks a single StandardWifiEntry.
@@ -107,7 +106,8 @@
checkNotNull(intent, "Intent cannot be null!");
final WifiConfiguration updatedConfig =
(WifiConfiguration) intent.getExtra(WifiManager.EXTRA_WIFI_CONFIGURATION);
- if (updatedConfig != null && TextUtils.equals(
+ if (updatedConfig != null && !updatedConfig.isPasspoint()
+ && !updatedConfig.fromWifiNetworkSuggestion && TextUtils.equals(
wifiConfigToStandardWifiEntryKey(updatedConfig), mChosenEntry.getKey())) {
final int changeReason = intent.getIntExtra(WifiManager.EXTRA_CHANGE_REASON,
-1 /* defaultValue*/);
@@ -172,11 +172,15 @@
* null if it does not exist.
*/
private void conditionallyUpdateConfig() {
- Optional<WifiConfiguration> optionalConfig = mWifiManager.getConfiguredNetworks()
- .stream().filter(config -> TextUtils.equals(
- wifiConfigToStandardWifiEntryKey(config), mChosenEntry.getKey()))
- .findAny();
- mChosenEntry.updateConfig(optionalConfig.orElse(null));
+ WifiConfiguration config = mWifiManager.getConfiguredNetworks().stream()
+ .filter(savedConfig -> TextUtils.equals(
+ wifiConfigToStandardWifiEntryKey(savedConfig), mChosenEntry.getKey()))
+ .findAny().orElse(mWifiManager.getPrivilegedConfiguredNetworks().stream()
+ .filter(suggestedConfig -> TextUtils.equals(
+ wifiConfigToStandardWifiEntryKey(suggestedConfig),
+ mChosenEntry.getKey()))
+ .findAny().orElse(null));
+ mChosenEntry.updateConfig(config);
}
/**
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java
index 642313a..5f8d44d 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java
@@ -46,6 +46,7 @@
import android.os.SystemClock;
import android.text.TextUtils;
+import androidx.annotation.GuardedBy;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -98,7 +99,10 @@
private static final int PSK_WPA_WPA2 = 2;
private static final int PSK_UNKNOWN = 3;
- private final List<ScanResult> mCurrentScanResults = new ArrayList<>();
+ private final Object mLock = new Object();
+ // Scan result list must be thread safe for generating the verbose scan summary
+ @GuardedBy("mLock")
+ @NonNull private final List<ScanResult> mCurrentScanResults = new ArrayList<>();
@NonNull private final String mKey;
@NonNull private final String mSsid;
@@ -107,6 +111,7 @@
private @EapType int mEapType = EAP_UNKNOWN;
private @PskType int mPskType = PSK_UNKNOWN;
@Nullable private WifiConfiguration mWifiConfig;
+ private boolean mIsUserShareable = false;
@Nullable private String mRecommendationServiceLabel;
private boolean mShouldAutoOpenCaptivePortal = false;
@@ -225,14 +230,6 @@
private String getConnectStateDescription() {
if (getConnectedState() == CONNECTED_STATE_CONNECTED) {
if (!isSaved()) {
- // For ephemeral networks.
- final String suggestionOrSpecifierPackageName = mWifiInfo != null
- ? mWifiInfo.getRequestingPackageName() : null;
- if (!TextUtils.isEmpty(suggestionOrSpecifierPackageName)) {
- return mContext.getString(R.string.connected_via_app,
- getAppLabel(mContext, suggestionOrSpecifierPackageName));
- }
-
// Special case for connected + ephemeral networks.
if (!TextUtils.isEmpty(mRecommendationServiceLabel)) {
return String.format(mContext.getString(R.string.connected_via_network_scorer),
@@ -241,6 +238,14 @@
return mContext.getString(R.string.connected_via_network_scorer_default);
}
+ // For network suggestions
+ final String suggestionOrSpecifierPackageName = mWifiInfo != null
+ ? mWifiInfo.getRequestingPackageName() : null;
+ if (!TextUtils.isEmpty(suggestionOrSpecifierPackageName)) {
+ return mContext.getString(R.string.connected_via_app,
+ getAppLabel(mContext, suggestionOrSpecifierPackageName));
+ }
+
String networkCapabilitiesinformation =
getCurrentNetworkCapabilitiesInformation(mContext, mNetworkCapabilities);
if (!TextUtils.isEmpty(networkCapabilitiesinformation)) {
@@ -300,7 +305,10 @@
@Override
public WifiConfiguration getWifiConfiguration() {
- return mWifiConfig;
+ if (mWifiConfig != null && !mWifiConfig.fromWifiNetworkSuggestion) {
+ return mWifiConfig;
+ }
+ return null;
}
@Override
@@ -373,12 +381,12 @@
@Override
public boolean canForget() {
- return isSaved();
+ return getWifiConfiguration() != null;
}
@Override
public void forget(@Nullable ForgetCallback callback) {
- if (mWifiConfig != null) {
+ if (canForget()) {
mForgetCallback = callback;
mWifiManager.forget(mWifiConfig.networkId, new ForgetActionListener());
}
@@ -407,7 +415,7 @@
*/
@Override
public boolean canShare() {
- if (!isSaved()) {
+ if (getWifiConfiguration() == null) {
return false;
}
@@ -429,7 +437,7 @@
*/
@Override
public boolean canEasyConnect() {
- if (!isSaved()) {
+ if (getWifiConfiguration() == null) {
return false;
}
@@ -467,8 +475,8 @@
@Override
@MeteredChoice
public int getMeteredChoice() {
- if (mWifiConfig != null) {
- final int meteredOverride = mWifiConfig.meteredOverride;
+ if (getWifiConfiguration() != null) {
+ final int meteredOverride = getWifiConfiguration().meteredOverride;
if (meteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED) {
return METERED_CHOICE_METERED;
} else if (meteredOverride == WifiConfiguration.METERED_OVERRIDE_NOT_METERED) {
@@ -480,12 +488,12 @@
@Override
public boolean canSetMeteredChoice() {
- return isSaved();
+ return getWifiConfiguration() != null;
}
@Override
public void setMeteredChoice(int meteredChoice) {
- if (mWifiConfig == null) {
+ if (!canSetMeteredChoice()) {
return;
}
@@ -501,17 +509,14 @@
@Override
public boolean canSetPrivacy() {
- return isSaved();
+ return getWifiConfiguration() != null;
}
@Override
@Privacy
public int getPrivacy() {
- if (mWifiConfig == null) {
- return PRIVACY_UNKNOWN;
- }
-
- if (mWifiConfig.macRandomizationSetting == WifiConfiguration.RANDOMIZATION_NONE) {
+ if (mWifiConfig != null
+ && mWifiConfig.macRandomizationSetting == WifiConfiguration.RANDOMIZATION_NONE) {
return PRIVACY_DEVICE_MAC;
} else {
return PRIVACY_RANDOMIZED_MAC;
@@ -531,7 +536,7 @@
@Override
public boolean isAutoJoinEnabled() {
- if (mWifiConfig == null) {
+ if (!isSaved()) {
return false;
}
@@ -616,10 +621,12 @@
}
}
- mCurrentScanResults.clear();
- mCurrentScanResults.addAll(scanResults);
+ synchronized (mLock) {
+ mCurrentScanResults.clear();
+ mCurrentScanResults.addAll(scanResults);
+ }
- final ScanResult bestScanResult = getBestScanResultByLevel(mCurrentScanResults);
+ final ScanResult bestScanResult = getBestScanResultByLevel(scanResults);
if (bestScanResult == null) {
mLevel = WIFI_LEVEL_UNREACHABLE;
} else {
@@ -697,6 +704,22 @@
notifyOnUpdated();
}
+ /**
+ * Sets whether the suggested config for this entry is shareable to the user or not.
+ */
+ @WorkerThread
+ void setUserShareable(boolean isUserShareable) {
+ mIsUserShareable = isUserShareable;
+ }
+
+ /**
+ * Returns whether the suggested config for this entry is shareable to the user or not.
+ */
+ @WorkerThread
+ boolean isUserShareable() {
+ return mIsUserShareable;
+ }
+
@WorkerThread
protected boolean connectionInfoMatches(@NonNull WifiInfo wifiInfo,
@NonNull NetworkInfo networkInfo) {
@@ -704,7 +727,16 @@
return false;
}
- return mWifiConfig != null && mWifiConfig.networkId == wifiInfo.getNetworkId();
+ if (mWifiConfig != null) {
+ if (mWifiConfig.fromWifiNetworkSuggestion) {
+ // Match network suggestions with SSID since the net id is prone to change.
+ return TextUtils.equals(mSsid, sanitizeSsid(wifiInfo.getSSID()));
+ }
+ if (mWifiConfig.networkId == wifiInfo.getNetworkId()) {
+ return true;
+ }
+ }
+ return false;
}
private void updateRecommendationServiceLabel() {
@@ -731,8 +763,10 @@
@Override
String getScanResultDescription() {
- if (mCurrentScanResults.size() == 0) {
- return "";
+ synchronized (mLock) {
+ if (mCurrentScanResults.size() == 0) {
+ return "";
+ }
}
final StringBuilder description = new StringBuilder();
@@ -745,11 +779,14 @@
}
private String getScanResultDescription(int minFrequency, int maxFrequency) {
- final List<ScanResult> scanResults = mCurrentScanResults.stream()
- .filter(scanResult -> scanResult.frequency >= minFrequency
- && scanResult.frequency <= maxFrequency)
- .sorted(Comparator.comparingInt(scanResult -> -1 * scanResult.level))
- .collect(Collectors.toList());
+ final List<ScanResult> scanResults;
+ synchronized (mLock) {
+ scanResults = mCurrentScanResults.stream()
+ .filter(scanResult -> scanResult.frequency >= minFrequency
+ && scanResult.frequency <= maxFrequency)
+ .sorted(Comparator.comparingInt(scanResult -> -1 * scanResult.level))
+ .collect(Collectors.toList());
+ }
final int scanResultCount = scanResults.size();
if (scanResultCount == 0) {
diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
index 0c6d7d6..c08b47c 100644
--- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
+++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
@@ -44,6 +44,7 @@
import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.os.Handler;
+import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -91,9 +92,14 @@
// Cache containing saved WifiConfigurations mapped by StandardWifiEntry key
private final Map<String, WifiConfiguration> mWifiConfigCache = new HashMap<>();
+
+ private final Map<String, WifiConfiguration> mSuggestedConfigCache = new HashMap<>();
// Cache containing visible StandardWifiEntries. Must be accessed only by the worker thread.
private final Map<String, StandardWifiEntry> mStandardWifiEntryCache = new HashMap<>();
-
+ // Cache containing available suggested StandardWifiEntries. These entries may be already
+ // represented in mStandardWifiEntryCache, so filtering must be done before they are returned in
+ // getWifiEntry() and getConnectedWifiEntry().
+ private final Map<String, StandardWifiEntry> mSuggestedWifiEntryCache = new HashMap<>();
// Cache containing saved PasspointConfigurations mapped by PasspointWifiEntry key.
private final Map<String, PasspointConfiguration> mPasspointConfigCache = new HashMap<>();
// Cache containing visible PasspointWifiEntries. Must be accessed only by the worker thread.
@@ -173,6 +179,8 @@
@Override
protected void handleOnStart() {
updateStandardWifiEntryConfigs(mWifiManager.getConfiguredNetworks());
+ updateSuggestedWifiEntryConfigs(mWifiManager.getPrivilegedConfiguredNetworks().stream()
+ .filter(config -> config.fromWifiNetworkSuggestion).collect(toList()));
updatePasspointWifiEntryConfigs(mWifiManager.getPasspointConfigurations());
mScanResultUpdater.update(mWifiManager.getScanResults());
conditionallyUpdateScanResults(true /* lastScanSucceeded */);
@@ -181,6 +189,7 @@
updateConnectionInfo(wifiInfo, networkInfo);
// Create a StandardWifiEntry for the current connection if there are no scan results yet.
conditionallyCreateConnectedStandardWifiEntry(wifiInfo, networkInfo);
+ conditionallyCreateConnectedSuggestedWifiEntry(wifiInfo, networkInfo);
conditionallyCreateConnectedPasspointWifiEntry(wifiInfo, networkInfo);
handleLinkPropertiesChanged(mConnectivityManager.getLinkProperties(
mWifiManager.getCurrentNetwork()));
@@ -213,11 +222,14 @@
final WifiConfiguration config =
(WifiConfiguration) intent.getExtra(WifiManager.EXTRA_WIFI_CONFIGURATION);
- if (config != null) {
+ if (config != null && !config.isPasspoint() && !config.fromWifiNetworkSuggestion) {
updateStandardWifiEntryConfig(
config, (Integer) intent.getExtra(WifiManager.EXTRA_CHANGE_REASON));
} else {
updateStandardWifiEntryConfigs(mWifiManager.getConfiguredNetworks());
+ updateSuggestedWifiEntryConfigs(mWifiManager.getPrivilegedConfiguredNetworks().stream()
+ .filter((privilegedConfig) -> privilegedConfig.fromWifiNetworkSuggestion)
+ .collect(toList()));
}
updatePasspointWifiEntryConfigs(mWifiManager.getPasspointConfigurations());
// Update scans since config changes may result in different entries being shown.
@@ -240,6 +252,7 @@
updateConnectionInfo(wifiInfo, networkInfo);
// Create a StandardWifiEntry for the current connection if there are no scan results yet.
conditionallyCreateConnectedStandardWifiEntry(wifiInfo, networkInfo);
+ conditionallyCreateConnectedSuggestedWifiEntry(wifiInfo, networkInfo);
conditionallyCreateConnectedPasspointWifiEntry(wifiInfo, networkInfo);
updateWifiEntries();
}
@@ -268,19 +281,19 @@
@WorkerThread
private void updateWifiEntries() {
synchronized (mLock) {
- mWifiEntries.clear();
- mWifiEntries.addAll(mStandardWifiEntryCache.values().stream().filter(entry ->
- entry.getConnectedState() == CONNECTED_STATE_DISCONNECTED).collect(toList()));
- mWifiEntries.addAll(mPasspointWifiEntryCache.values().stream().filter(entry ->
- entry.getConnectedState() == CONNECTED_STATE_DISCONNECTED).collect(toList()));
- mWifiEntries.addAll(mOsuWifiEntryCache.values().stream().filter(entry ->
- entry.getConnectedState() == CONNECTED_STATE_DISCONNECTED).collect(toList()));
mConnectedWifiEntry = mStandardWifiEntryCache.values().stream().filter(entry -> {
final @WifiEntry.ConnectedState int connectedState = entry.getConnectedState();
return connectedState == CONNECTED_STATE_CONNECTED
|| connectedState == CONNECTED_STATE_CONNECTING;
}).findAny().orElse(null /* other */);
if (mConnectedWifiEntry == null) {
+ mConnectedWifiEntry = mSuggestedWifiEntryCache.values().stream().filter(entry -> {
+ final @WifiEntry.ConnectedState int connectedState = entry.getConnectedState();
+ return connectedState == CONNECTED_STATE_CONNECTED
+ || connectedState == CONNECTED_STATE_CONNECTING;
+ }).findAny().orElse(null /* other */);
+ }
+ if (mConnectedWifiEntry == null) {
mConnectedWifiEntry = mPasspointWifiEntryCache.values().stream().filter(entry -> {
final @WifiEntry.ConnectedState int connectedState = entry.getConnectedState();
return connectedState == CONNECTED_STATE_CONNECTED
@@ -294,6 +307,32 @@
|| connectedState == CONNECTED_STATE_CONNECTING;
}).findAny().orElse(null /* other */);
}
+ mWifiEntries.clear();
+ for (String key : mStandardWifiEntryCache.keySet()) {
+ // Continue if we're connected to this network with a non-user-shareable config.
+ if (mConnectedWifiEntry != null
+ && TextUtils.equals(key, mConnectedWifiEntry.getKey())) {
+ continue;
+ }
+ StandardWifiEntry entry = mStandardWifiEntryCache.get(key);
+ StandardWifiEntry suggestedEntry = mSuggestedWifiEntryCache.get(key);
+ // Return a user-shareable suggested network to the user if one exists
+ if (!entry.isSaved()
+ && suggestedEntry != null && suggestedEntry.isUserShareable()) {
+ if (suggestedEntry.getConnectedState() == CONNECTED_STATE_DISCONNECTED) {
+ mWifiEntries.add(suggestedEntry);
+ }
+ } else {
+ if (entry.getConnectedState() == CONNECTED_STATE_DISCONNECTED) {
+ mWifiEntries.add(entry);
+ }
+ }
+
+ }
+ mWifiEntries.addAll(mPasspointWifiEntryCache.values().stream().filter(entry ->
+ entry.getConnectedState() == CONNECTED_STATE_DISCONNECTED).collect(toList()));
+ mWifiEntries.addAll(mOsuWifiEntryCache.values().stream().filter(entry ->
+ entry.getConnectedState() == CONNECTED_STATE_DISCONNECTED).collect(toList()));
Collections.sort(mWifiEntries);
if (isVerboseLoggingEnabled()) {
Log.v(TAG, "Connected WifiEntry: " + mConnectedWifiEntry);
@@ -343,6 +382,59 @@
}
}
+ /**
+ * Updates or removes scan results for the corresponding StandardWifiEntries.
+ * New entries will be created for scan results without an existing entry.
+ * Unreachable entries will be removed.
+ *
+ * @param scanResults List of valid scan results to convey as StandardWifiEntries
+ */
+ @WorkerThread
+ private void updateSuggestedWifiEntryScans(@NonNull List<ScanResult> scanResults) {
+ checkNotNull(scanResults, "Scan Result list should not be null!");
+
+ // Group scans by StandardWifiEntry key
+ final Map<String, List<ScanResult>> scanResultsByKey = mapScanResultsToKey(
+ scanResults,
+ true /* chooseSingleSecurity */,
+ mWifiConfigCache,
+ mWifiManager.isWpa3SaeSupported(),
+ mWifiManager.isWpa3SuiteBSupported(),
+ mWifiManager.isEnhancedOpenSupported());
+
+ Map<String, WifiConfiguration> userSharedConfigsByKey =
+ mWifiManager.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(scanResults)
+ .stream()
+ .collect(Collectors.toMap(
+ StandardWifiEntry::wifiConfigToStandardWifiEntryKey,
+ Function.identity()));
+
+ Set<String> seenKeys = new TreeSet<>();
+ for (String key : userSharedConfigsByKey.keySet()) {
+ seenKeys.add(key);
+ if (!mSuggestedWifiEntryCache.containsKey(key)) {
+ mSuggestedWifiEntryCache.put(key, new StandardWifiEntry(mContext, mMainHandler, key,
+ userSharedConfigsByKey.get(key), mWifiManager,
+ false /* forSavedNetworksPage */));
+ }
+ final StandardWifiEntry entry = mSuggestedWifiEntryCache.get(key);
+ entry.setUserShareable(true);
+ entry.updateScanResultInfo(scanResultsByKey.get(key));
+ }
+
+ // Remove entries without configs
+ mSuggestedWifiEntryCache.entrySet()
+ .removeIf(entry -> {
+ StandardWifiEntry wifiEntry = entry.getValue();
+ String key = entry.getKey();
+ if (!seenKeys.contains(key)) {
+ wifiEntry.updateConfig(mSuggestedConfigCache.get(key));
+ wifiEntry.setUserShareable(false);
+ }
+ return !wifiEntry.isSaved();
+ });
+ }
+
@WorkerThread
private void updatePasspointWifiEntryScans(@NonNull List<ScanResult> scanResults) {
checkNotNull(scanResults, "Scan Result list should not be null!");
@@ -415,6 +507,7 @@
private void conditionallyUpdateScanResults(boolean lastScanSucceeded) {
if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED) {
updateStandardWifiEntryScans(Collections.emptyList());
+ updateSuggestedWifiEntryScans(Collections.emptyList());
updatePasspointWifiEntryScans(Collections.emptyList());
updateOsuWifiEntryScans(Collections.emptyList());
return;
@@ -432,6 +525,7 @@
List<ScanResult> scanResults = mScanResultUpdater.getScanResults(scanAgeWindow);
updateStandardWifiEntryScans(scanResults);
+ updateSuggestedWifiEntryScans(scanResults);
updatePasspointWifiEntryScans(scanResults);
updateOsuWifiEntryScans(scanResults);
}
@@ -483,12 +577,33 @@
}
@WorkerThread
+ private void updateSuggestedWifiEntryConfigs(@NonNull List<WifiConfiguration> configs) {
+ checkNotNull(configs, "Config list should not be null!");
+ mSuggestedConfigCache.clear();
+ mSuggestedConfigCache.putAll(configs.stream().collect(Collectors.toMap(
+ StandardWifiEntry::wifiConfigToStandardWifiEntryKey,
+ Function.identity())));
+
+ // Iterate through current entries and update each entry's config
+ mSuggestedWifiEntryCache.entrySet().removeIf((entry) -> {
+ final StandardWifiEntry wifiEntry = entry.getValue();
+ final String key = wifiEntry.getKey();
+ final WifiConfiguration cachedConfig = mSuggestedConfigCache.get(key);
+ if (cachedConfig != null) {
+ wifiEntry.updateConfig(cachedConfig);
+ return false;
+ } else {
+ return true;
+ }
+ });
+ }
+
+ @WorkerThread
private void updatePasspointWifiEntryConfigs(@NonNull List<PasspointConfiguration> configs) {
checkNotNull(configs, "Config list should not be null!");
-
mPasspointConfigCache.clear();
mPasspointConfigCache.putAll(configs.stream().collect(
- toMap((config) -> uniqueIdToPasspointWifiEntryKey(
+ toMap(config -> uniqueIdToPasspointWifiEntryKey(
config.getUniqueId()), Function.identity())));
// Iterate through current entries and update each entry's config or remove if no config
@@ -517,6 +632,9 @@
for (WifiEntry entry : mStandardWifiEntryCache.values()) {
entry.updateConnectionInfo(wifiInfo, networkInfo);
}
+ for (WifiEntry entry : mSuggestedWifiEntryCache.values()) {
+ entry.updateConnectionInfo(wifiInfo, networkInfo);
+ }
for (WifiEntry entry : mPasspointWifiEntryCache.values()) {
entry.updateConnectionInfo(wifiInfo, networkInfo);
}
@@ -534,7 +652,7 @@
@WorkerThread
private void conditionallyCreateConnectedStandardWifiEntry(@Nullable WifiInfo wifiInfo,
@Nullable NetworkInfo networkInfo) {
- if (wifiInfo.isPasspointAp()) {
+ if (wifiInfo.isPasspointAp() || wifiInfo.isOsuAp()) {
return;
}
@@ -554,7 +672,37 @@
}
/**
- * Creates and caches a StandardWifiEntry representing the current connection using the current
+ * Creates and caches a suggested StandardWifiEntry representing the current connection using
+ * the current WifiInfo and NetworkInfo if there are no scans results available for the network
+ * yet.
+ * @param wifiInfo WifiInfo of the current connection
+ * @param networkInfo NetworkInfo of the current connection
+ */
+ @WorkerThread
+ private void conditionallyCreateConnectedSuggestedWifiEntry(@Nullable WifiInfo wifiInfo,
+ @Nullable NetworkInfo networkInfo) {
+ if (wifiInfo.isPasspointAp() || wifiInfo.isOsuAp()) {
+ return;
+ }
+
+ mSuggestedConfigCache.values().stream()
+ .filter(config ->
+ TextUtils.equals(config.SSID, wifiInfo.getSSID())
+ && !mSuggestedWifiEntryCache.containsKey(
+ wifiConfigToStandardWifiEntryKey(config)))
+ .findAny().ifPresent(config -> {
+ final StandardWifiEntry connectedEntry =
+ new StandardWifiEntry(mContext, mMainHandler,
+ wifiConfigToStandardWifiEntryKey(config), config, mWifiManager,
+ false /* forSavedNetworksPage */);
+ connectedEntry.updateConnectionInfo(wifiInfo, networkInfo);
+ mSuggestedWifiEntryCache.put(connectedEntry.getKey(), connectedEntry);
+ });
+ }
+
+
+ /**
+ * Creates and caches a PasspointWifiEntry representing the current connection using the current
* WifiInfo and NetworkInfo if there are no scans results available for the network yet.
* @param wifiInfo WifiInfo of the current connection
* @param networkInfo NetworkInfo of the current connection
diff --git a/service/Android.bp b/service/Android.bp
index 928f9c5..0fdc7fe 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -58,7 +58,7 @@
"jsr305",
"framework-annotations-lib",
// load the resources from the resources APK.
- "wifi-service-resources",
+ "ServiceWifiResources",
// need pre-jarjar symbols so that wifi-service can reference the original class names at
// compile time
"framework-wifi-pre-jarjar",
@@ -143,11 +143,9 @@
}
// APK to hold all the wifi overlayable resources.
-// TODO: This should be signed by a wifi specific certificate.
// ============================================================
android_app {
- // TODO: Rename to service-wifi-resources? What about b/151678653?
- name: "wifi-service-resources",
+ name: "ServiceWifiResources",
defaults: ["wifi-service-common"],
resource_dirs: [
"res",
@@ -156,6 +154,16 @@
sdk_version: "system_current",
export_package_resources: true,
manifest: "AndroidManifest_Resources.xml",
+ apex_available: [
+ "com.android.wifi",
+ "test_com.android.wifi",
+ ],
+ certificate: ":com.android.wifi.resources.certificate",
+}
+
+android_app_certificate {
+ name: "com.android.wifi.resources.certificate",
+ certificate: "resources-certs/com.android.wifi.resources"
}
// Prebuilt for the wifi.rc file.
diff --git a/service/AndroidManifest_Resources.xml b/service/AndroidManifest_Resources.xml
index 4585721..a6b2a58 100644
--- a/service/AndroidManifest_Resources.xml
+++ b/service/AndroidManifest_Resources.xml
@@ -26,5 +26,12 @@
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true"
android:usesCleartextTraffic="true">
+ <!-- This is only used to identify this app by resolving the action.
+ The activity is never actually triggered. -->
+ <activity android:name="android.app.Activity" android:exported="true" android:enabled="true">
+ <intent-filter>
+ <action android:name="com.android.server.wifi.intent.action.SERVICE_WIFI_RESOURCES_APK" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/service/apex/Android.bp b/service/apex/Android.bp
index 65cd6d5..e23d9cc 100644
--- a/service/apex/Android.bp
+++ b/service/apex/Android.bp
@@ -30,8 +30,8 @@
key: "com.android.wifi.key",
certificate: ":com.android.wifi.certificate",
apps: [
- "wifi-service-resources",
"OsuLogin",
+ "ServiceWifiResources",
],
}
diff --git a/service/java/com/android/server/wifi/BssidBlocklistMonitor.java b/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
index 897090c..70c9193 100644
--- a/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
+++ b/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
@@ -154,13 +154,10 @@
pw.println("BssidBlocklistMonitor - Bssid blocklist End ----");
}
- private void addToBlocklist(@NonNull BssidStatus entry, long durationMs,
- boolean doNotClearUntilTimeout, String reasonString) {
+ private void addToBlocklist(@NonNull BssidStatus entry, long durationMs, String reasonString) {
entry.addToBlocklist(durationMs);
- entry.doNotClearUntilTimeout = doNotClearUntilTimeout;
localLog(TAG + " addToBlocklist: bssid=" + entry.bssid + ", ssid=" + entry.ssid
- + ", durationMs=" + durationMs + ", doNotClearUntilTimeout="
- + doNotClearUntilTimeout + ", reason=" + reasonString);
+ + ", durationMs=" + durationMs + ", reason=" + reasonString);
}
/**
@@ -223,8 +220,7 @@
// Return because this BSSID is already being blocked for a longer time.
return;
}
- addToBlocklist(status, durationMs, true,
- FAILURE_BSSID_BLOCKED_BY_FRAMEWORK_REASON_STRING);
+ addToBlocklist(status, durationMs, FAILURE_BSSID_BLOCKED_BY_FRAMEWORK_REASON_STRING);
}
private String getFailureReasonString(@FailureReason int reasonCode) {
@@ -289,7 +285,7 @@
}
addToBlocklist(entry,
getBlocklistDurationWithExponentialBackoff(currentStreak, baseBlockDurationMs),
- false, getFailureReasonString(reasonCode));
+ getFailureReasonString(reasonCode));
mWifiScoreCard.incrementBssidBlocklistStreak(ssid, bssid, reasonCode);
return true;
}
@@ -403,8 +399,7 @@
*/
public void clearBssidBlocklistForSsid(@NonNull String ssid) {
int prevSize = mBssidStatusMap.size();
- mBssidStatusMap.entrySet().removeIf(e -> !e.getValue().doNotClearUntilTimeout
- && e.getValue().ssid.equals(ssid));
+ mBssidStatusMap.entrySet().removeIf(e -> e.getValue().ssid.equals(ssid));
int diff = prevSize - mBssidStatusMap.size();
if (diff > 0) {
localLog(TAG + " clearBssidBlocklistForSsid: SSID=" + ssid
@@ -418,7 +413,7 @@
public void clearBssidBlocklist() {
if (mBssidStatusMap.size() > 0) {
int prevSize = mBssidStatusMap.size();
- mBssidStatusMap.entrySet().removeIf(e -> !e.getValue().doNotClearUntilTimeout);
+ mBssidStatusMap.clear();
localLog(TAG + " clearBssidBlocklist: num BSSIDs cleared="
+ (prevSize - mBssidStatusMap.size()));
}
@@ -506,9 +501,6 @@
// The following are used to flag how long this BSSID stays in the blocklist.
public boolean isInBlocklist;
public long blocklistEndTimeMs;
- // Indicate that this BSSID should not be removed from blacklist through other means
- // such as |clearBssidBlocklist| and |clearBssidBlocklistForSsid|
- public boolean doNotClearUntilTimeout;
BssidStatus(String bssid, String ssid) {
this.bssid = bssid;
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 6941fbf..588564e 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -59,6 +59,7 @@
import android.net.SocketKeepalive;
import android.net.StaticIpConfiguration;
import android.net.TcpKeepalivePacketData;
+import android.net.Uri;
import android.net.ip.IIpClient;
import android.net.ip.IpClientCallbacks;
import android.net.ip.IpClientManager;
@@ -146,6 +147,7 @@
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -3580,6 +3582,7 @@
// Let's remove any ephemeral or passpoint networks.
mWifiConfigManager.removeAllEphemeralOrPasspointConfiguredNetworks();
+ mWifiConfigManager.clearUserTemporarilyDisabledList();
}
void registerConnected() {
@@ -4472,7 +4475,7 @@
}
@Override
- public void onValidationStatus(int status, @Nullable String redirectUrl) {
+ public void onValidationStatus(int status, @Nullable Uri redirectUri) {
if (this != mNetworkAgent) return;
if (status == mLastNetworkStatus) return;
mLastNetworkStatus = status;
@@ -4499,10 +4502,10 @@
}
@Override
- public void onStartSocketKeepalive(int slot, int intervalSeconds,
+ public void onStartSocketKeepalive(int slot, @NonNull Duration interval,
@NonNull KeepalivePacketData packet) {
ClientModeImpl.this.sendMessage(
- CMD_START_IP_PACKET_OFFLOAD, slot, intervalSeconds, packet);
+ CMD_START_IP_PACKET_OFFLOAD, slot, (int) interval.getSeconds(), packet);
}
@Override
@@ -4633,6 +4636,10 @@
.build();
final NetworkCapabilities nc = getCapabilities(getCurrentWifiConfiguration());
synchronized (mNetworkAgentLock) {
+ // This should never happen.
+ if (mNetworkAgent != null) {
+ Log.wtf(TAG, "mNetworkAgent is not null: " + mNetworkAgent);
+ }
mNetworkAgent = new WifiNetworkAgent(mContext, getHandler().getLooper(),
"WifiNetworkAgent", nc, mLinkProperties, 60, naConfig,
mNetworkFactory.getProvider());
@@ -5054,7 +5061,7 @@
}
private void sendConnectedState() {
- mNetworkAgent.setConnected();
+ mNetworkAgent.markConnected();
sendNetworkChangeBroadcast(DetailedState.CONNECTED);
}
diff --git a/service/java/com/android/server/wifi/ConnectToNetworkNotificationBuilder.java b/service/java/com/android/server/wifi/ConnectToNetworkNotificationBuilder.java
index f4bd95f..4f7b4e8 100644
--- a/service/java/com/android/server/wifi/ConnectToNetworkNotificationBuilder.java
+++ b/service/java/com/android/server/wifi/ConnectToNetworkNotificationBuilder.java
@@ -18,7 +18,6 @@
import android.app.Notification;
import android.app.PendingIntent;
-import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.net.wifi.ScanResult;
@@ -51,12 +50,12 @@
public static final String AVAILABLE_NETWORK_NOTIFIER_TAG =
"com.android.server.wifi.ConnectToNetworkNotification.AVAILABLE_NETWORK_NOTIFIER_TAG";
- private Context mContext;
+ private WifiContext mContext;
private WifiInjector mWifiInjector;
private FrameworkFacade mFrameworkFacade;
public ConnectToNetworkNotificationBuilder(
- Context context,
+ WifiContext context,
WifiInjector wifiInjector,
FrameworkFacade framework) {
mContext = context;
@@ -158,7 +157,7 @@
CharSequence title, CharSequence content, String extraData) {
return mFrameworkFacade.makeNotificationBuilder(mContext,
WifiService.NOTIFICATION_NETWORK_AVAILABLE)
- .setSmallIcon(Icon.createWithResource(WifiContext.WIFI_OVERLAY_APK_PKG_NAME,
+ .setSmallIcon(Icon.createWithResource(mContext.getWifiOverlayApkPkgName(),
com.android.wifi.resources.R.drawable.stat_notify_wifi_in_range))
.setTicker(title)
.setContentTitle(title)
diff --git a/service/java/com/android/server/wifi/ConnectionFailureNotificationBuilder.java b/service/java/com/android/server/wifi/ConnectionFailureNotificationBuilder.java
index a16dac2..6f0a487 100644
--- a/service/java/com/android/server/wifi/ConnectionFailureNotificationBuilder.java
+++ b/service/java/com/android/server/wifi/ConnectionFailureNotificationBuilder.java
@@ -21,7 +21,6 @@
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Icon;
@@ -44,14 +43,14 @@
public static final String RANDOMIZATION_SETTINGS_NETWORK_SSID =
"com.android.server.wifi.RANDOMIZATION_SETTINGS_NETWORK_SSID";
- private Context mContext;
+ private WifiContext mContext;
private String mPackageName;
private FrameworkFacade mFrameworkFacade;
private WifiConnectivityManager mWifiConnectivityManager;
private NotificationManager mNotificationManager;
private Handler mHandler;
- public ConnectionFailureNotificationBuilder(Context context, String packageName,
+ public ConnectionFailureNotificationBuilder(WifiContext context, String packageName,
FrameworkFacade framework) {
mContext = context;
mPackageName = packageName;
@@ -81,7 +80,7 @@
return mFrameworkFacade.makeNotificationBuilder(
mContext, WifiService.NOTIFICATION_NETWORK_ALERTS)
- .setSmallIcon(Icon.createWithResource(WifiContext.WIFI_OVERLAY_APK_PKG_NAME,
+ .setSmallIcon(Icon.createWithResource(mContext.getWifiOverlayApkPkgName(),
com.android.wifi.resources.R.drawable.stat_notify_wifi_in_range))
.setTicker(title)
.setContentTitle(title)
diff --git a/service/java/com/android/server/wifi/DppManager.java b/service/java/com/android/server/wifi/DppManager.java
index 11572f1..02b1191 100644
--- a/service/java/com/android/server/wifi/DppManager.java
+++ b/service/java/com/android/server/wifi/DppManager.java
@@ -489,6 +489,7 @@
// Convert from HAL codes to WifiManager/user codes
switch (dppStatusCode) {
case DppSuccessCode.CONFIGURATION_SENT:
+ mDppMetrics.updateDppR1CapableEnrolleeResponderDevices();
dppSuccessCode = EasyConnectStatusCallback
.EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT;
break;
@@ -540,6 +541,7 @@
break;
case DppProgressCode.CONFIGURATION_SENT_WAITING_RESPONSE:
+ mDppMetrics.updateDppR2CapableEnrolleeResponderDevices();
dppProgressCode = EasyConnectStatusCallback
.EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE;
break;
@@ -642,6 +644,7 @@
if (isNetworkInScanCache & !channelMatch) {
Log.d(TAG, "Update the error code to NOT_COMPATIBLE"
+ " as enrollee didn't scan network's operating channel");
+ mDppMetrics.updateDppR2EnrolleeResponderIncompatibleConfiguration();
return false;
}
return true;
diff --git a/service/java/com/android/server/wifi/DppMetrics.java b/service/java/com/android/server/wifi/DppMetrics.java
index 231e7f1..bd62313 100644
--- a/service/java/com/android/server/wifi/DppMetrics.java
+++ b/service/java/com/android/server/wifi/DppMetrics.java
@@ -18,13 +18,17 @@
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_BUSY;
+import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CONFIGURATION;
+import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION;
+import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_GENERIC;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_INVALID_URI;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_TIMEOUT;
+import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT;
import android.net.wifi.EasyConnectStatusCallback;
@@ -90,6 +94,35 @@
}
/**
+ * Update number of DPP R1 capable enrollee responder devices.
+ */
+ public void updateDppR1CapableEnrolleeResponderDevices() {
+ synchronized (mLock) {
+ mWifiDppLogProto.numDppR1CapableEnrolleeResponderDevices++;
+ }
+ }
+
+ /**
+ * Update number of DPP R2 capable enrollee responder devices.
+ */
+ public void updateDppR2CapableEnrolleeResponderDevices() {
+ synchronized (mLock) {
+ mWifiDppLogProto.numDppR2CapableEnrolleeResponderDevices++;
+ }
+ }
+
+ /**
+ * Update number of times DPP R2 compatibility check detected
+ * that enrollee responder device is incompatible with the
+ * network.
+ */
+ public void updateDppR2EnrolleeResponderIncompatibleConfiguration() {
+ synchronized (mLock) {
+ mWifiDppLogProto.numDppR2EnrolleeResponderIncompatibleConfiguration++;
+ }
+ }
+
+ /**
* Update DPP Configurator success counter
*/
public void updateDppConfiguratorSuccess(
@@ -102,6 +135,12 @@
mHistogramDppConfiguratorSuccessCode.get(WifiMetricsProto.WifiDppLog
.EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT) + 1);
break;
+ case EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED:
+ mHistogramDppConfiguratorSuccessCode.put(WifiMetricsProto.WifiDppLog
+ .EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED,
+ mHistogramDppConfiguratorSuccessCode.get(WifiMetricsProto.WifiDppLog
+ .EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED) + 1);
+ break;
default:
break;
}
@@ -168,6 +207,25 @@
mHistogramDppFailureCode.get(WifiMetricsProto.WifiDppLog
.EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK) + 1);
break;
+ case EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK:
+ mHistogramDppFailureCode.put(WifiMetricsProto.WifiDppLog
+ .EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK,
+ mHistogramDppFailureCode.get(WifiMetricsProto.WifiDppLog
+ .EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK) + 1);
+ break;
+ case EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION:
+ mHistogramDppFailureCode.put(WifiMetricsProto.WifiDppLog
+ .EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION,
+ mHistogramDppFailureCode.get(WifiMetricsProto.WifiDppLog
+ .EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION) + 1);
+ break;
+ case EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION:
+ mHistogramDppFailureCode.put(WifiMetricsProto.WifiDppLog
+ .EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION,
+ mHistogramDppFailureCode.get(WifiMetricsProto.WifiDppLog
+ .EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION)
+ + 1);
+ break;
default:
break;
}
@@ -199,6 +257,12 @@
+ mWifiDppLogProto.numDppEnrolleeInitiatorRequests);
pw.println("mWifiDppLogProto.numDppEnrolleeSuccess="
+ mWifiDppLogProto.numDppEnrolleeSuccess);
+ pw.println("mWifiDppLogProto.numDppR1CapableEnrolleeResponderDevices="
+ + mWifiDppLogProto.numDppR1CapableEnrolleeResponderDevices);
+ pw.println("mWifiDppLogProto.numDppR2CapableEnrolleeResponderDevices="
+ + mWifiDppLogProto.numDppR2CapableEnrolleeResponderDevices);
+ pw.println("mWifiDppLogProto.numDppR2EnrolleeResponderIncompatibleConfiguration="
+ + mWifiDppLogProto.numDppR2EnrolleeResponderIncompatibleConfiguration);
if (mHistogramDppFailureCode.size() > 0) {
pw.println("mHistogramDppFailureCode=");
@@ -226,6 +290,9 @@
mWifiDppLogProto.numDppConfiguratorInitiatorRequests = 0;
mWifiDppLogProto.numDppEnrolleeInitiatorRequests = 0;
mWifiDppLogProto.numDppEnrolleeSuccess = 0;
+ mWifiDppLogProto.numDppR1CapableEnrolleeResponderDevices = 0;
+ mWifiDppLogProto.numDppR2CapableEnrolleeResponderDevices = 0;
+ mWifiDppLogProto.numDppR2EnrolleeResponderIncompatibleConfiguration = 0;
mHistogramDppFailureCode.clear();
mHistogramDppOperationTime.clear();
mHistogramDppConfiguratorSuccessCode.clear();
@@ -276,6 +343,12 @@
mWifiDppLogProto.numDppConfiguratorInitiatorRequests;
log.numDppEnrolleeInitiatorRequests = mWifiDppLogProto.numDppEnrolleeInitiatorRequests;
log.numDppEnrolleeSuccess = mWifiDppLogProto.numDppEnrolleeSuccess;
+ log.numDppR1CapableEnrolleeResponderDevices =
+ mWifiDppLogProto.numDppR1CapableEnrolleeResponderDevices;
+ log.numDppR2CapableEnrolleeResponderDevices =
+ mWifiDppLogProto.numDppR2CapableEnrolleeResponderDevices;
+ log.numDppR2EnrolleeResponderIncompatibleConfiguration =
+ mWifiDppLogProto.numDppR2EnrolleeResponderIncompatibleConfiguration;
log.dppFailureCode = consolidateDppFailure(mHistogramDppFailureCode);
log.dppConfiguratorSuccessCode =
consolidateDppSuccess(mHistogramDppConfiguratorSuccessCode);
diff --git a/service/java/com/android/server/wifi/EapFailureNotifier.java b/service/java/com/android/server/wifi/EapFailureNotifier.java
index 1613bbf..3cc80b9 100644
--- a/service/java/com/android/server/wifi/EapFailureNotifier.java
+++ b/service/java/com/android/server/wifi/EapFailureNotifier.java
@@ -42,7 +42,7 @@
private static final String ERROR_MESSAGE_OVERLAY_PREFIX = "wifi_eap_error_message_code_";
private static final long CANCEL_TIMEOUT_MILLISECONDS = 5 * 60 * 1000;
- private final Context mContext;
+ private final WifiContext mContext;
private final NotificationManager mNotificationManager;
private final FrameworkFacade mFrameworkFacade;
private final TelephonyUtil mTelephonyUtil;
@@ -51,7 +51,7 @@
public static final int NOTIFICATION_ID = SystemMessage.NOTE_WIFI_EAP_FAILURE;
private String mCurrentShownSsid;
- public EapFailureNotifier(Context context, FrameworkFacade frameworkFacade,
+ public EapFailureNotifier(WifiContext context, FrameworkFacade frameworkFacade,
TelephonyUtil telephonyUtil) {
mContext = context;
mFrameworkFacade = frameworkFacade;
@@ -77,7 +77,7 @@
mTelephonyUtil.getBestMatchSubscriptionId(config));
if (res == null) return;
int resourceId = res.getIdentifier(ERROR_MESSAGE_OVERLAY_PREFIX + errorCode,
- "string", WifiContext.WIFI_OVERLAY_APK_PKG_NAME);
+ "string", mContext.getWifiOverlayApkPkgName());
if (resourceId == 0) return;
String errorMessage = res.getString(resourceId, config.SSID);
@@ -96,7 +96,7 @@
WifiService.NOTIFICATION_NETWORK_ALERTS)
.setAutoCancel(true)
.setTimeoutAfter(CANCEL_TIMEOUT_MILLISECONDS)
- .setSmallIcon(Icon.createWithResource(WifiContext.WIFI_OVERLAY_APK_PKG_NAME,
+ .setSmallIcon(Icon.createWithResource(mContext.getWifiOverlayApkPkgName(),
com.android.wifi.resources.R.drawable.stat_notify_wifi_in_range))
.setContentTitle(mContext.getString(
com.android.wifi.resources.R.string.wifi_available_title_failed_to_connect))
@@ -114,11 +114,11 @@
* Returns the resources from the given context for the MCC/MNC
* associated with the subscription.
*/
- private Resources getResourcesForSubId(Context context, int subId) {
+ private Resources getResourcesForSubId(WifiContext context, int subId) {
Context resourceContext = null;
try {
resourceContext = context.createPackageContext(
- WifiContext.WIFI_OVERLAY_APK_PKG_NAME, 0);
+ context.getWifiOverlayApkPkgName(), 0);
} catch (PackageManager.NameNotFoundException ex) {
return null;
}
diff --git a/service/java/com/android/server/wifi/SimRequiredNotifier.java b/service/java/com/android/server/wifi/SimRequiredNotifier.java
index 19e369d..8e3d22d 100644
--- a/service/java/com/android/server/wifi/SimRequiredNotifier.java
+++ b/service/java/com/android/server/wifi/SimRequiredNotifier.java
@@ -19,7 +19,6 @@
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.net.wifi.WifiConfiguration;
@@ -33,11 +32,11 @@
*/
public class SimRequiredNotifier {
- private final Context mContext;
+ private final WifiContext mContext;
private final FrameworkFacade mFrameworkFacade;
private final NotificationManager mNotificationManager;
- public SimRequiredNotifier(Context context, FrameworkFacade framework) {
+ public SimRequiredNotifier(WifiContext context, FrameworkFacade framework) {
mContext = context;
mFrameworkFacade = framework;
mNotificationManager =
@@ -84,7 +83,7 @@
.setTicker(title)
.setContentText(message)
.setStyle(new Notification.BigTextStyle().bigText(message))
- .setSmallIcon(Icon.createWithResource(WifiContext.WIFI_OVERLAY_APK_PKG_NAME,
+ .setSmallIcon(Icon.createWithResource(mContext.getWifiOverlayApkPkgName(),
R.drawable.stat_notify_wifi_in_range))
.setContentIntent(launchWirelessSettings())
.build();
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index 42a228e..44bbc73 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -22,7 +22,6 @@
import static com.android.server.wifi.util.ApConfigUtil.SUCCESS;
import android.annotation.NonNull;
-import android.content.Context;
import android.content.Intent;
import android.net.MacAddress;
import android.net.wifi.ScanResult;
@@ -74,7 +73,7 @@
public static final String SOFT_AP_SEND_MESSAGE_TIMEOUT_TAG = TAG
+ " Soft AP Send Message Timeout";
- private final Context mContext;
+ private final WifiContext mContext;
private final FrameworkFacade mFrameworkFacade;
private final WifiNative mWifiNative;
@@ -158,7 +157,7 @@
}
};
- public SoftApManager(@NonNull Context context,
+ public SoftApManager(@NonNull WifiContext context,
@NonNull Looper looper,
@NonNull FrameworkFacade framework,
@NonNull WifiNative wifiNative,
diff --git a/service/java/com/android/server/wifi/SoftApNotifier.java b/service/java/com/android/server/wifi/SoftApNotifier.java
index 741cab8..45114a5 100644
--- a/service/java/com/android/server/wifi/SoftApNotifier.java
+++ b/service/java/com/android/server/wifi/SoftApNotifier.java
@@ -19,7 +19,6 @@
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
@@ -41,11 +40,11 @@
public static final int NOTIFICATION_ID_SOFTAP_AUTO_DISABLED =
SystemMessage.NOTE_SOFTAP_AUTO_DISABLED;
- private final Context mContext;
+ private final WifiContext mContext;
private final FrameworkFacade mFrameworkFacade;
private final NotificationManager mNotificationManager;
- public SoftApNotifier(Context context, FrameworkFacade framework) {
+ public SoftApNotifier(WifiContext context, FrameworkFacade framework) {
mContext = context;
mFrameworkFacade = framework;
mNotificationManager =
@@ -76,7 +75,7 @@
return mFrameworkFacade.makeNotificationBuilder(mContext,
WifiService.NOTIFICATION_NETWORK_STATUS)
- .setSmallIcon(Icon.createWithResource(WifiContext.WIFI_OVERLAY_APK_PKG_NAME,
+ .setSmallIcon(Icon.createWithResource(mContext.getWifiOverlayApkPkgName(),
R.drawable.ic_wifi_settings))
.setContentTitle(title)
.setContentText(contentSummary)
diff --git a/service/java/com/android/server/wifi/WakeupNotificationFactory.java b/service/java/com/android/server/wifi/WakeupNotificationFactory.java
index 11713ba..9eb69b7 100644
--- a/service/java/com/android/server/wifi/WakeupNotificationFactory.java
+++ b/service/java/com/android/server/wifi/WakeupNotificationFactory.java
@@ -18,7 +18,6 @@
import android.app.Notification;
import android.app.PendingIntent;
-import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
@@ -41,11 +40,11 @@
/** Notification channel ID for onboarding messages. */
public static final int ONBOARD_ID = SystemMessage.NOTE_WIFI_WAKE_ONBOARD;
- private final Context mContext;
+ private final WifiContext mContext;
private final WifiInjector mWifiInjector;
private final FrameworkFacade mFrameworkFacade;
- WakeupNotificationFactory(Context context, WifiInjector wifiInjector,
+ WakeupNotificationFactory(WifiContext context, WifiInjector wifiInjector,
FrameworkFacade frameworkFacade) {
mContext = context;
mWifiInjector = wifiInjector;
@@ -68,7 +67,7 @@
return mFrameworkFacade.makeNotificationBuilder(mContext,
WifiService.NOTIFICATION_NETWORK_STATUS)
- .setSmallIcon(Icon.createWithResource(WifiContext.WIFI_OVERLAY_APK_PKG_NAME,
+ .setSmallIcon(Icon.createWithResource(mContext.getWifiOverlayApkPkgName(),
R.drawable.ic_wifi_settings))
.setTicker(title)
.setContentTitle(title)
diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java
index 972cd52..4921f8c 100644
--- a/service/java/com/android/server/wifi/WifiApConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiApConfigStore.java
@@ -36,7 +36,6 @@
import java.util.Random;
import javax.annotation.Nullable;
-import javax.crypto.Mac;
/**
* Provides API for reading/writing soft access point configuration.
@@ -68,7 +67,6 @@
private final WifiMetrics mWifiMetrics;
private final BackupManagerProxy mBackupManagerProxy;
private final MacAddressUtil mMacAddressUtil;
- private final Mac mMac;
private final WifiConfigManager mWifiConfigManager;
private final ActiveModeWarden mActiveModeWarden;
private boolean mHasNewDataToSerialize = false;
@@ -118,11 +116,6 @@
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_HOTSPOT_CONFIG_USER_TAPPED_CONTENT);
mMacAddressUtil = wifiInjector.getMacAddressUtil();
- mMac = mMacAddressUtil.obtainMacRandHashFunctionForSap(Process.WIFI_UID);
- if (mMac == null) {
- Log.wtf(TAG, "Failed to obtain secret for SAP MAC randomization."
- + " All randomized MAC addresses are lost!");
- }
}
/**
@@ -290,7 +283,8 @@
SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(config);
if (config.getBssid() == null && context.getResources().getBoolean(
R.bool.config_wifi_ap_mac_randomization_supported)) {
- MacAddress macAddress = mMacAddressUtil.calculatePersistentMac(config.getSsid(), mMac);
+ MacAddress macAddress = mMacAddressUtil.calculatePersistentMac(config.getSsid(),
+ mMacAddressUtil.obtainMacRandHashFunctionForSap(Process.WIFI_UID));
if (macAddress == null) {
Log.e(TAG, "Failed to calculate MAC from SSID. "
+ "Generating new random MAC instead.");
diff --git a/service/java/com/android/server/wifi/WifiBackupDataParser.java b/service/java/com/android/server/wifi/WifiBackupDataParser.java
index 7699c55..e61cab2 100644
--- a/service/java/com/android/server/wifi/WifiBackupDataParser.java
+++ b/service/java/com/android/server/wifi/WifiBackupDataParser.java
@@ -42,4 +42,11 @@
*/
List<WifiConfiguration> parseNetworkConfigurationsFromXml(XmlPullParser in, int outerTagDepth,
int minorVersion) throws XmlPullParserException, IOException;
+
+ /**
+ * Get the highest supported minor version for this major version.
+ * This is used for generating the version code when serializing the data.
+ * @return Indicating the max supported minor version by this major version parser.
+ */
+ int getHighestSupportedMinorVersion();
}
diff --git a/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java b/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java
index b787df2..89ab9a9 100644
--- a/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java
+++ b/service/java/com/android/server/wifi/WifiBackupDataV1Parser.java
@@ -141,6 +141,7 @@
IpConfigurationXmlUtil.XML_TAG_PROXY_PAC_FILE,
}));
+ @Override
public List<WifiConfiguration> parseNetworkConfigurationsFromXml(XmlPullParser in,
int outerTagDepth, int minorVersion) throws XmlPullParserException, IOException {
// clamp down the minorVersion to the highest one that this parser version supports
@@ -165,6 +166,11 @@
return configurations;
}
+ @Override
+ public int getHighestSupportedMinorVersion() {
+ return HIGHEST_SUPPORTED_MINOR_VERSION;
+ }
+
/**
* Parses the configuration data elements from the provided XML stream to a Configuration.
*
@@ -350,6 +356,9 @@
case WifiConfigurationXmlUtil.XML_TAG_METERED_OVERRIDE:
configuration.meteredOverride = (int) value;
break;
+ case WifiConfigurationXmlUtil.XML_TAG_IS_AUTO_JOIN:
+ configuration.allowAutojoin = (boolean) value;
+ break;
default:
// should never happen, since other tags are filtered out earlier
throw new XmlPullParserException(
diff --git a/service/java/com/android/server/wifi/WifiBackupRestore.java b/service/java/com/android/server/wifi/WifiBackupRestore.java
index 078cb77..c55236e 100644
--- a/service/java/com/android/server/wifi/WifiBackupRestore.java
+++ b/service/java/com/android/server/wifi/WifiBackupRestore.java
@@ -81,7 +81,7 @@
* Note that bumping up only the minor version will still allow restoring the backup set to
* lower versions of SDK_INT.
*/
- private static final float CURRENT_BACKUP_DATA_VERSION = 1.1f;
+ private static final int CURRENT_BACKUP_DATA_MAJOR_VERSION = 1;
/** This list of older versions will be used to restore data from older backups. */
/**
@@ -128,12 +128,36 @@
private byte[] mDebugLastBackupDataRetrieved;
private byte[] mDebugLastBackupDataRestored;
private byte[] mDebugLastSupplicantBackupDataRestored;
+ private byte[] mDebugLastIpConfigBackupDataRestored;
public WifiBackupRestore(WifiPermissionsUtil wifiPermissionsUtil) {
mWifiPermissionsUtil = wifiPermissionsUtil;
}
/**
+ * Retrieve the version for serialization.
+ */
+ private Float getVersion() {
+ WifiBackupDataParser parser =
+ getWifiBackupDataParser(CURRENT_BACKUP_DATA_MAJOR_VERSION);
+ if (parser == null) {
+ Log.e(TAG, "Major version of backup data is unknown to this Android"
+ + " version; not backing up");
+ return null;
+ }
+ int minorVersion = parser.getHighestSupportedMinorVersion();
+ Float version;
+ try {
+ version = Float.valueOf(
+ CURRENT_BACKUP_DATA_MAJOR_VERSION + "." + minorVersion);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "Failed to generate version", e);
+ return null;
+ }
+ return version;
+ }
+
+ /**
* Retrieve an XML byte stream representing the data that needs to be backed up from the
* provided configurations.
*
@@ -154,7 +178,9 @@
// Start writing the XML stream.
XmlUtil.writeDocumentStart(out, XML_TAG_DOCUMENT_HEADER);
- XmlUtil.writeNextValue(out, XML_TAG_VERSION, CURRENT_BACKUP_DATA_VERSION);
+ Float version = getVersion();
+ if (version == null) return null;
+ XmlUtil.writeNextValue(out, XML_TAG_VERSION, version.floatValue());
writeNetworkConfigurationsToXml(out, configurations);
@@ -342,6 +368,7 @@
if (mVerboseLoggingEnabled) {
mDebugLastSupplicantBackupDataRestored = supplicantData;
+ mDebugLastIpConfigBackupDataRestored = ipConfigData;
}
SupplicantBackupMigration.SupplicantNetworks supplicantNetworks =
@@ -394,6 +421,7 @@
mDebugLastBackupDataRetrieved = null;
mDebugLastBackupDataRestored = null;
mDebugLastSupplicantBackupDataRestored = null;
+ mDebugLastIpConfigBackupDataRestored = null;
}
}
@@ -415,10 +443,14 @@
+ createLogFromBackupData(mDebugLastBackupDataRestored));
}
if (mDebugLastSupplicantBackupDataRestored != null) {
- pw.println("Last old backup data restored: "
+ pw.println("Last old supplicant backup data restored: "
+ SupplicantBackupMigration.createLogFromBackupData(
mDebugLastSupplicantBackupDataRestored));
}
+ if (mDebugLastIpConfigBackupDataRestored != null) {
+ pw.println("Last old ipconfig backup data restored: "
+ + mDebugLastIpConfigBackupDataRestored);
+ }
}
/**
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index b13251d..4e4f51d 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -198,16 +198,19 @@
/**
* General sorting algorithm of all networks for scanning purposes:
- * Place the configurations in descending order of their |numAssociation| values. If networks
- * have the same |numAssociation|, place the configurations with
+ * Place the configurations in ascending order of their AgeIndex. AgeIndex is based on most
+ * recently connected order. The lower the more recently connected.
+ * If networks have the same AgeIndex, place the configurations with
* |lastSeenInQualifiedNetworkSelection| set first.
*/
- public static final WifiConfigurationUtil.WifiConfigurationComparator sScanListComparator =
+ private final WifiConfigurationUtil.WifiConfigurationComparator mScanListComparator =
new WifiConfigurationUtil.WifiConfigurationComparator() {
@Override
public int compareNetworksWithSameStatus(WifiConfiguration a, WifiConfiguration b) {
- if (a.numAssociation != b.numAssociation) {
- return Long.compare(b.numAssociation, a.numAssociation);
+ int indexA = mLruConnectionTracker.getAgeIndexOfNetwork(a);
+ int indexB = mLruConnectionTracker.getAgeIndexOfNetwork(b);
+ if (indexA != indexB) {
+ return Integer.compare(indexA, indexB);
} else {
boolean isConfigALastSeen =
a.getNetworkSelectionStatus()
@@ -2634,22 +2637,6 @@
}
/**
- * Find the most recently connected network from a list of networks, and place it at top
- */
- private void putMostRecentlyConnectedNetworkAtTop(List<WifiConfiguration> networks) {
- WifiConfiguration lastConnectedNetwork =
- networks.stream()
- .max(Comparator.comparing(
- (WifiConfiguration config) -> config.lastConnected))
- .get();
- if (lastConnectedNetwork.lastConnected != 0) {
- int lastConnectedNetworkIdx = networks.indexOf(lastConnectedNetwork);
- networks.remove(lastConnectedNetworkIdx);
- networks.add(0, lastConnectedNetwork);
- }
- }
-
- /**
* Retrieves a list of channels for partial single scans
*
* @param ageInMillis only consider scan details whose timestamps are more recent than this.
@@ -2675,10 +2662,7 @@
}
// Sort the networks with the most frequent ones at the front of the network list.
- Collections.sort(networks, sScanListComparator);
-
- // Find the most recently connected network and move it to the front of the network list.
- putMostRecentlyConnectedNetworkAtTop(networks);
+ Collections.sort(networks, mScanListComparator);
Set<Integer> channelSet = new HashSet<>();
long nowInMillis = mClock.getWallClockMillis();
@@ -2793,7 +2777,7 @@
List<WifiConfiguration> networks = getConfiguredNetworks();
// Remove any non hidden networks.
networks.removeIf(config -> !config.hiddenSSID);
- networks.sort(sScanListComparator);
+ networks.sort(mScanListComparator);
// The most frequently connected network has the highest priority now.
for (WifiConfiguration config : networks) {
hiddenList.add(new WifiScanner.ScanSettings.HiddenNetwork(config.SSID));
@@ -2877,9 +2861,8 @@
}
/**
- * Clear all deleted ephemeral networks.
+ * Clear all user temporarily disabled networks.
*/
- @VisibleForTesting
public void clearUserTemporarilyDisabledList() {
mUserTemporarilyDisabledList.clear();
}
@@ -3447,4 +3430,8 @@
}
return scanMaxRssi;
}
+
+ public Comparator<WifiConfiguration> getScanListComparator() {
+ return mScanListComparator;
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 31fcfca..712dbcd 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -52,7 +52,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
@@ -1302,11 +1301,8 @@
if (networks.isEmpty()) {
return Collections.EMPTY_LIST;
}
- Collections.sort(networks, WifiConfigManager.sScanListComparator);
- if (mContext.getResources().getBoolean(R.bool.config_wifiPnoRecencySortingEnabled)) {
- // Find the most recently connected network and move it to the front of the list.
- putMostRecentlyConnectedNetworkAtTop(networks);
- }
+ Collections.sort(networks, mConfigManager.getScanListComparator());
+
WifiScoreCard scoreCard = null;
if (mContext.getResources().getBoolean(R.bool.config_wifiPnoFrequencyCullingEnabled)) {
scoreCard = mWifiInjector.getWifiScoreCard();
@@ -1334,22 +1330,6 @@
return pnoList;
}
- /**
- * Find the most recently connected network from a list of networks, and place it at top
- */
- private void putMostRecentlyConnectedNetworkAtTop(List<WifiConfiguration> networks) {
- WifiConfiguration lastConnectedNetwork =
- networks.stream()
- .max(Comparator.comparing(
- (WifiConfiguration config) -> config.lastConnected))
- .get();
- if (lastConnectedNetwork.lastConnected != 0) {
- int lastConnectedNetworkIdx = networks.indexOf(lastConnectedNetwork);
- networks.remove(lastConnectedNetworkIdx);
- networks.add(0, lastConnectedNetwork);
- }
- }
-
// Stop PNO scan.
private void stopPnoScan() {
if (!mPnoScanStarted) return;
diff --git a/service/java/com/android/server/wifi/WifiContext.java b/service/java/com/android/server/wifi/WifiContext.java
index 2040d73..b360a8e 100644
--- a/service/java/com/android/server/wifi/WifiContext.java
+++ b/service/java/com/android/server/wifi/WifiContext.java
@@ -19,18 +19,29 @@
import android.annotation.NonNull;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.util.Log;
+import com.android.server.wifi.util.Environment;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
/**
* Wrapper for context to override getResources method. Resources for wifi mainline jar needs to be
* fetched from the resources APK.
*/
public class WifiContext extends ContextWrapper {
private static final String TAG = "WifiContext";
- public static final String WIFI_OVERLAY_APK_PKG_NAME = "com.android.wifi.resources";
+ /** Intent action that is used to identify ServiceWifiResources.apk */
+ private static final String ACTION_RESOURCES_APK =
+ "com.android.server.wifi.intent.action.SERVICE_WIFI_RESOURCES_APK";
+
+ private String mWifiOverlayApkPkgName;
// Cached resources from the resources APK.
private AssetManager mWifiAssetsFromApk;
@@ -41,9 +52,45 @@
super(contextBase);
}
+ /** Get the package name of ServiceWifiResources.apk */
+ public String getWifiOverlayApkPkgName() {
+ if (mWifiOverlayApkPkgName != null) {
+ return mWifiOverlayApkPkgName;
+ }
+
+ List<ResolveInfo> resolveInfos = getPackageManager().queryIntentActivities(
+ new Intent(ACTION_RESOURCES_APK),
+ PackageManager.MATCH_SYSTEM_ONLY);
+
+ // remove apps that don't live in the Wifi apex
+ resolveInfos.removeIf(info ->
+ !Environment.isAppInWifiApex(info.activityInfo.applicationInfo));
+
+ if (resolveInfos.isEmpty()) {
+ // Resource APK not loaded yet, print a stack trace to see where this is called from
+ Log.e(TAG, "Attempted to fetch resources before Wifi Resources APK is loaded!",
+ new IllegalStateException());
+ return null;
+ }
+
+ if (resolveInfos.size() > 1) {
+ // multiple apps found, log a warning, but continue
+ Log.w(TAG, "Found > 1 APK that can resolve Wifi Resources APK intent: "
+ + resolveInfos.stream()
+ .map(info -> info.activityInfo.applicationInfo.packageName)
+ .collect(Collectors.joining(", ")));
+ }
+
+ // Assume the first ResolveInfo is the one we're looking for
+ ResolveInfo info = resolveInfos.get(0);
+ mWifiOverlayApkPkgName = info.activityInfo.applicationInfo.packageName;
+ Log.i(TAG, "Found Wifi Resources APK at: " + mWifiOverlayApkPkgName);
+ return mWifiOverlayApkPkgName;
+ }
+
private Context getResourcesApkContext() {
try {
- return createPackageContext(WIFI_OVERLAY_APK_PKG_NAME, 0);
+ return createPackageContext(getWifiOverlayApkPkgName(), 0);
} catch (PackageManager.NameNotFoundException e) {
Log.wtf(TAG, "Failed to load resources", e);
}
diff --git a/service/java/com/android/server/wifi/WifiDataStall.java b/service/java/com/android/server/wifi/WifiDataStall.java
index fd29934..ba1de32 100644
--- a/service/java/com/android/server/wifi/WifiDataStall.java
+++ b/service/java/com/android/server/wifi/WifiDataStall.java
@@ -48,7 +48,7 @@
// Maximum time that a data stall start time stays valid.
public static final long VALIDITY_PERIOD_OF_DATA_STALL_START_MS = 30 * 1000; // 0.5 minutes
// Default Tx packet error rate when there is no Tx attempt
- public static final int DEFAULT_TX_PACKET_ERROR_RATE = 20;
+ public static final int DEFAULT_TX_PACKET_ERROR_RATE = 5;
// Default CCA level when CCA stats are not available
public static final int DEFAULT_CCA_LEVEL_2G = CHANNEL_UTILIZATION_SCALE * 16 / 100;
public static final int DEFAULT_CCA_LEVEL_ABOVE_2G = CHANNEL_UTILIZATION_SCALE * 6 / 100;
@@ -230,6 +230,7 @@
int currFrequency = wifiInfo.getFrequency();
mWifiChannelUtilization.refreshChannelStatsAndChannelUtilization(newStats, currFrequency);
int ccaLevel = mWifiChannelUtilization.getUtilizationRatio(currFrequency);
+ mWifiMetrics.incrementChannelUtilizationCount(ccaLevel, currFrequency);
if (oldStats == null || newStats == null) {
// First poll after new association
@@ -242,6 +243,7 @@
}
mIsThroughputSufficient = true;
mWifiMetrics.resetWifiIsUnusableLinkLayerStats();
+ mWifiMetrics.incrementThroughputKbpsCount(mTxTputKbps, mRxTputKbps, currFrequency);
return WifiIsUnusableEvent.TYPE_UNKNOWN;
}
@@ -322,6 +324,7 @@
} else {
mRxTputKbps = INVALID_THROUGHPUT;
}
+ mWifiMetrics.incrementThroughputKbpsCount(mTxTputKbps, mRxTputKbps, currFrequency);
mIsThroughputSufficient = isThroughputSufficientInternal(mTxTputKbps, mRxTputKbps,
isTxTrafficHigh, isRxTrafficHigh, timeDeltaLastTwoPollsMs);
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index a6aa034..6daca90 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -83,7 +83,7 @@
static WifiInjector sWifiInjector = null;
- private final Context mContext;
+ private final WifiContext mContext;
private final BatteryStatsManager mBatteryStats;
private final FrameworkFacade mFrameworkFacade;
private final DeviceConfigFacade mDeviceConfigFacade;
@@ -169,7 +169,7 @@
private final SettingsMigrationDataHolder mSettingsMigrationDataHolder;
private final LruConnectionTracker mLruConnectionTracker;
- public WifiInjector(Context context) {
+ public WifiInjector(WifiContext context) {
if (context == null) {
throw new IllegalStateException(
"WifiInjector should not be initialized with a null Context.");
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index fb61737..c563a4b 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -442,6 +442,26 @@
// Connection duration stats collected while link layer stats reports are on
private final ConnectionDurationStats mConnectionDurationStats = new ConnectionDurationStats();
+ private static final int[] CHANNEL_UTILIZATION_BUCKETS =
+ {25, 50, 75, 100, 125, 150, 175, 200, 225};
+
+ private final IntHistogram mChannelUtilizationHistogram2G =
+ new IntHistogram(CHANNEL_UTILIZATION_BUCKETS);
+
+ private final IntHistogram mChannelUtilizationHistogramAbove2G =
+ new IntHistogram(CHANNEL_UTILIZATION_BUCKETS);
+
+ private static final int[] THROUGHPUT_MBPS_BUCKETS =
+ {1, 5, 10, 15, 25, 50, 100, 150, 200, 300, 450, 600, 800, 1200, 1600};
+ private final IntHistogram mTxThroughputMbpsHistogram2G =
+ new IntHistogram(THROUGHPUT_MBPS_BUCKETS);
+ private final IntHistogram mRxThroughputMbpsHistogram2G =
+ new IntHistogram(THROUGHPUT_MBPS_BUCKETS);
+ private final IntHistogram mTxThroughputMbpsHistogramAbove2G =
+ new IntHistogram(THROUGHPUT_MBPS_BUCKETS);
+ private final IntHistogram mRxThroughputMbpsHistogramAbove2G =
+ new IntHistogram(THROUGHPUT_MBPS_BUCKETS);
+
// Wi-Fi off metrics
private final WifiOffMetrics mWifiOffMetrics = new WifiOffMetrics();
@@ -2039,6 +2059,54 @@
}
/**
+ * Increment occurrence count of channel utilization
+ * @param channelUtilization Channel utilization of current network
+ * @param frequency Channel frequency of current network
+ */
+ @VisibleForTesting
+ public void incrementChannelUtilizationCount(int channelUtilization, int frequency) {
+ if (channelUtilization < InformationElementUtil.BssLoad.MIN_CHANNEL_UTILIZATION
+ || channelUtilization > InformationElementUtil.BssLoad.MAX_CHANNEL_UTILIZATION) {
+ return;
+ }
+ synchronized (mLock) {
+ if (frequency <= KnownBandsChannelHelper.BAND_24_GHZ_END_FREQ) {
+ mChannelUtilizationHistogram2G.increment(channelUtilization);
+ } else {
+ mChannelUtilizationHistogramAbove2G.increment(channelUtilization);
+ }
+ }
+ }
+
+ /**
+ * Increment occurrence count of Tx and Rx throughput
+ * @param txThroughputKbps Tx throughput of current network in Kbps
+ * @param rxThroughputKbps Rx throughput of current network in Kbps
+ * @param frequency Channel frequency of current network in MHz
+ */
+ @VisibleForTesting
+ public void incrementThroughputKbpsCount(int txThroughputKbps, int rxThroughputKbps,
+ int frequency) {
+ synchronized (mLock) {
+ if (frequency <= KnownBandsChannelHelper.BAND_24_GHZ_END_FREQ) {
+ if (txThroughputKbps >= 0) {
+ mTxThroughputMbpsHistogram2G.increment(txThroughputKbps / 1000);
+ }
+ if (rxThroughputKbps >= 0) {
+ mRxThroughputMbpsHistogram2G.increment(rxThroughputKbps / 1000);
+ }
+ } else {
+ if (txThroughputKbps >= 0) {
+ mTxThroughputMbpsHistogramAbove2G.increment(txThroughputKbps / 1000);
+ }
+ if (rxThroughputKbps >= 0) {
+ mRxThroughputMbpsHistogramAbove2G.increment(rxThroughputKbps / 1000);
+ }
+ }
+ }
+ }
+
+ /**
* Increment count of Watchdog successes.
*/
public void incrementNumLastResortWatchdogSuccesses() {
@@ -3403,6 +3471,18 @@
+ mWifiOffMetrics.toString());
pw.println("mWifiLogProto.softApConfigLimitationMetrics="
+ mSoftApConfigLimitationMetrics.toString());
+ pw.println("mChannelUtilizationHistogram2G:\n"
+ + mChannelUtilizationHistogram2G);
+ pw.println("mChannelUtilizationHistogramAbove2G:\n"
+ + mChannelUtilizationHistogramAbove2G);
+ pw.println("mTxThroughputMbpsHistogram2G:\n"
+ + mTxThroughputMbpsHistogram2G);
+ pw.println("mRxThroughputMbpsHistogram2G:\n"
+ + mRxThroughputMbpsHistogram2G);
+ pw.println("mTxThroughputMbpsHistogramAbove2G:\n"
+ + mTxThroughputMbpsHistogramAbove2G);
+ pw.println("mRxThroughputMbpsHistogramAbove2G:\n"
+ + mRxThroughputMbpsHistogramAbove2G);
}
}
}
@@ -3974,6 +4054,22 @@
mWifiLogProto.connectionDurationStats = mConnectionDurationStats.toProto();
mWifiLogProto.wifiOffMetrics = mWifiOffMetrics.toProto();
mWifiLogProto.softApConfigLimitationMetrics = mSoftApConfigLimitationMetrics.toProto();
+ mWifiLogProto.channelUtilizationHistogram =
+ new WifiMetricsProto.ChannelUtilizationHistogram();
+ mWifiLogProto.channelUtilizationHistogram.utilization2G =
+ mChannelUtilizationHistogram2G.toProto();
+ mWifiLogProto.channelUtilizationHistogram.utilizationAbove2G =
+ mChannelUtilizationHistogramAbove2G.toProto();
+ mWifiLogProto.throughputMbpsHistogram =
+ new WifiMetricsProto.ThroughputMbpsHistogram();
+ mWifiLogProto.throughputMbpsHistogram.tx2G =
+ mTxThroughputMbpsHistogram2G.toProto();
+ mWifiLogProto.throughputMbpsHistogram.txAbove2G =
+ mTxThroughputMbpsHistogramAbove2G.toProto();
+ mWifiLogProto.throughputMbpsHistogram.rx2G =
+ mRxThroughputMbpsHistogram2G.toProto();
+ mWifiLogProto.throughputMbpsHistogram.rxAbove2G =
+ mRxThroughputMbpsHistogramAbove2G.toProto();
}
}
@@ -4166,6 +4262,12 @@
mWifiLockLowLatencyActiveSessionDurationSecHistogram.clear();
mWifiLockStats.clear();
mWifiToggleStats.clear();
+ mChannelUtilizationHistogram2G.clear();
+ mChannelUtilizationHistogramAbove2G.clear();
+ mTxThroughputMbpsHistogram2G.clear();
+ mRxThroughputMbpsHistogram2G.clear();
+ mTxThroughputMbpsHistogramAbove2G.clear();
+ mRxThroughputMbpsHistogramAbove2G.clear();
mPasspointProvisionFailureCounts.clear();
mNumProvisionSuccess = 0;
mBssidBlocklistStats = new BssidBlocklistStats();
diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
index c82539b..19c9da1 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
@@ -126,7 +126,7 @@
*/
private static final int NUMBER_OF_HIDDEN_NETWORK_FOR_ONE_SCAN = 100;
- private final Context mContext;
+ private final WifiContext mContext;
private final Resources mResources;
private final Handler mHandler;
private final AppOpsManager mAppOps;
@@ -568,7 +568,7 @@
}
};
- public WifiNetworkSuggestionsManager(Context context, Handler handler,
+ public WifiNetworkSuggestionsManager(WifiContext context, Handler handler,
WifiInjector wifiInjector, WifiPermissionsUtil wifiPermissionsUtil,
WifiConfigManager wifiConfigManager, WifiConfigStore wifiConfigStore,
WifiMetrics wifiMetrics, TelephonyUtil telephonyUtil,
@@ -800,15 +800,15 @@
public @WifiManager.NetworkSuggestionsStatusCode int add(
List<WifiNetworkSuggestion> networkSuggestions, int uid, String packageName,
@Nullable String featureId) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "Adding " + networkSuggestions.size() + " networks from " + packageName);
- }
- if (networkSuggestions.isEmpty()) {
+ if (networkSuggestions == null || networkSuggestions.isEmpty()) {
Log.w(TAG, "Empty list of network suggestions for " + packageName + ". Ignoring");
return WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
}
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "Adding " + networkSuggestions.size() + " networks from " + packageName);
+ }
if (!validateNetworkSuggestions(networkSuggestions)) {
- Log.e(TAG, "Invalid suggestion from app: " + packageName);
+ Log.e(TAG, "Invalid suggestion add from app: " + packageName);
return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID;
}
if (!validateCarrierNetworkSuggestions(networkSuggestions, uid, packageName)) {
@@ -928,6 +928,9 @@
private boolean validateNetworkSuggestions(List<WifiNetworkSuggestion> networkSuggestions) {
for (WifiNetworkSuggestion wns : networkSuggestions) {
+ if (wns == null || wns.wifiConfiguration == null) {
+ return false;
+ }
if (wns.passpointConfiguration == null) {
if (!WifiConfigurationUtil.validate(wns.wifiConfiguration,
WifiConfigurationUtil.VALIDATE_FOR_ADD)) {
@@ -1037,9 +1040,18 @@
*/
public @WifiManager.NetworkSuggestionsStatusCode int remove(
List<WifiNetworkSuggestion> networkSuggestions, int uid, String packageName) {
+ if (networkSuggestions == null) {
+ Log.w(TAG, "Null list of network suggestions for " + packageName + ". Ignoring");
+ return WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
+ }
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Removing " + networkSuggestions.size() + " networks from " + packageName);
}
+
+ if (!validateNetworkSuggestions(networkSuggestions)) {
+ Log.e(TAG, "Invalid suggestion remove from app: " + packageName);
+ return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID;
+ }
PerAppInfo perAppInfo = mActiveNetworkSuggestionsPerApp.get(packageName);
if (perAppInfo == null) {
Log.e(TAG, "Failed to remove network suggestions for " + packageName
@@ -1305,7 +1317,7 @@
CharSequence appName = getAppName(packageName, uid);
Notification notification = mFrameworkFacade.makeNotificationBuilder(
mContext, WifiService.NOTIFICATION_NETWORK_STATUS)
- .setSmallIcon(Icon.createWithResource(WifiContext.WIFI_OVERLAY_APK_PKG_NAME,
+ .setSmallIcon(Icon.createWithResource(mContext.getWifiOverlayApkPkgName(),
com.android.wifi.resources.R.drawable.stat_notify_wifi_in_range))
.setTicker(mResources.getString(R.string.wifi_suggestion_title))
.setContentTitle(mResources.getString(R.string.wifi_suggestion_title))
@@ -1347,7 +1359,7 @@
Notification notification = mFrameworkFacade.makeNotificationBuilder(
mContext, WifiService.NOTIFICATION_NETWORK_STATUS)
- .setSmallIcon(Icon.createWithResource(WifiContext.WIFI_OVERLAY_APK_PKG_NAME,
+ .setSmallIcon(Icon.createWithResource(mContext.getWifiOverlayApkPkgName(),
com.android.wifi.resources.R.drawable.stat_notify_wifi_in_range))
.setTicker(mResources.getString(
R.string.wifi_suggestion_imsi_privacy_title, carrierName))
@@ -1979,11 +1991,12 @@
continue;
}
if (carrierId == TelephonyManager.UNKNOWN_CARRIER_ID) {
- Log.v(TAG, "Carrier privilege revoked for " + appInfo.packageName);
+ Log.i(TAG, "Carrier privilege revoked for " + appInfo.packageName);
removeInternal(Collections.EMPTY_LIST, appInfo.packageName, appInfo);
mActiveNetworkSuggestionsPerApp.remove(appInfo.packageName);
continue;
}
+ Log.i(TAG, "Carrier privilege granted for " + appInfo.packageName);
appInfo.carrierId = carrierId;
for (ExtendedWifiNetworkSuggestion ewns : appInfo.extNetworkSuggestions) {
ewns.wns.wifiConfiguration.carrierId = carrierId;
@@ -2031,7 +2044,14 @@
@NonNull List<WifiNetworkSuggestion> wifiNetworkSuggestions,
@NonNull List<ScanResult> scanResults) {
Map<WifiNetworkSuggestion, List<ScanResult>> filteredScanResults = new HashMap<>();
+ if (wifiNetworkSuggestions == null || wifiNetworkSuggestions.isEmpty()
+ || scanResults == null || scanResults.isEmpty()) {
+ return filteredScanResults;
+ }
for (WifiNetworkSuggestion suggestion : wifiNetworkSuggestions) {
+ if (suggestion == null || suggestion.wifiConfiguration == null) {
+ continue;
+ }
if (suggestion.passpointConfiguration != null) {
filteredScanResults.put(suggestion,
mWifiInjector.getPasspointManager().getMatchingScanResults(
diff --git a/service/java/com/android/server/wifi/WifiService.java b/service/java/com/android/server/wifi/WifiService.java
index 552afd4..0197246 100644
--- a/service/java/com/android/server/wifi/WifiService.java
+++ b/service/java/com/android/server/wifi/WifiService.java
@@ -39,12 +39,15 @@
public static final String NOTIFICATION_NETWORK_ALERTS = "NETWORK_ALERTS";
public static final String NOTIFICATION_NETWORK_AVAILABLE = "NETWORK_AVAILABLE";
- final WifiServiceImpl mImpl;
+ private final WifiServiceImpl mImpl;
+ private final WifiContext mWifiContext;
public WifiService(Context contextBase) {
- super(new WifiContext(contextBase));
- mImpl = new WifiServiceImpl(getContext(), new WifiInjector(getContext()),
- new WifiAsyncChannel(TAG));
+ super(contextBase);
+ mWifiContext = new WifiContext(contextBase);
+ WifiInjector injector = new WifiInjector(mWifiContext);
+ WifiAsyncChannel channel = new WifiAsyncChannel(TAG);
+ mImpl = new WifiServiceImpl(mWifiContext, injector, channel);
}
@Override
@@ -56,7 +59,7 @@
@Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
- createNotificationChannels(getContext());
+ createNotificationChannels(mWifiContext);
mImpl.checkAndStartWifi();
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
mImpl.handleBootCompleted();
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 2e93728..91f7768 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -115,6 +115,7 @@
import com.android.server.wifi.util.ApConfigUtil;
import com.android.server.wifi.util.ExternalCallbackTracker;
import com.android.server.wifi.util.RssiUtil;
+import com.android.server.wifi.util.ScanResultUtil;
import com.android.server.wifi.util.WifiHandler;
import com.android.server.wifi.util.WifiPermissionsUtil;
import com.android.wifi.resources.R;
@@ -1035,8 +1036,10 @@
public boolean setEnablingIfAllowed() {
synchronized (mLock) {
- if (mTetheredSoftApState == WIFI_AP_STATE_ENABLING) return false;
- if (mTetheredSoftApState == WIFI_AP_STATE_ENABLED) return false;
+ if (mTetheredSoftApState != WIFI_AP_STATE_DISABLED
+ && mTetheredSoftApState != WIFI_AP_STATE_FAILED) {
+ return false;
+ }
mTetheredSoftApState = WIFI_AP_STATE_ENABLING;
return true;
}
@@ -2192,6 +2195,10 @@
if (mVerboseLoggingEnabled) {
mLog.info("getMatchingPasspointConfigurations uid=%").c(Binder.getCallingUid()).flush();
}
+ if (!ScanResultUtil.validateScanResultList(scanResults)) {
+ Log.e(TAG, "Attempt to retrieve passpoint with invalid scanResult List");
+ return Collections.emptyMap();
+ }
return mWifiThreadRunner.call(
() -> mPasspointManager.getAllMatchingPasspointProfilesForScanResults(scanResults),
Collections.emptyMap());
@@ -2212,6 +2219,11 @@
if (mVerboseLoggingEnabled) {
mLog.info("getMatchingOsuProviders uid=%").c(Binder.getCallingUid()).flush();
}
+
+ if (!ScanResultUtil.validateScanResultList(scanResults)) {
+ Log.e(TAG, "Attempt to retrieve OsuProviders with invalid scanResult List");
+ return Collections.emptyMap();
+ }
return mWifiThreadRunner.call(
() -> mPasspointManager.getMatchingOsuProviders(scanResults), Collections.emptyMap());
}
@@ -2288,8 +2300,8 @@
mLog.info("getWifiConfigsForMatchedNetworkSuggestions uid=%").c(
Binder.getCallingUid()).flush();
}
- if (scanResults == null) {
- Log.e(TAG, "Attempt to retrieve WifiConfiguration with null scanResult List");
+ if (!ScanResultUtil.validateScanResultList(scanResults)) {
+ Log.e(TAG, "Attempt to retrieve WifiConfiguration with invalid scanResult List");
return new ArrayList<>();
}
return mWifiThreadRunner.call(
@@ -2701,7 +2713,7 @@
return mWifiThreadRunner.call(
() -> {
- if (scanResults == null || scanResults.isEmpty()) {
+ if (!ScanResultUtil.validateScanResultList(scanResults)) {
return mWifiNetworkSuggestionsManager.getMatchingScanResults(
networkSuggestions, mScanRequestProxy.getScanResults());
} else {
@@ -3494,6 +3506,8 @@
}
// Enable all networks restored.
mWifiConfigManager.enableNetwork(networkId, false, callingUid, null);
+ // Restore auto-join param.
+ mWifiConfigManager.allowAutojoin(networkId, configuration.allowAutojoin);
}
});
}
diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java
index 6d7eeed..eb4210f 100644
--- a/service/java/com/android/server/wifi/WifiShellCommand.java
+++ b/service/java/com/android/server/wifi/WifiShellCommand.java
@@ -26,19 +26,23 @@
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiScanner;
import android.net.wifi.nl80211.WifiNl80211Manager;
import android.os.BasicShellCommandHandler;
import android.os.Binder;
+import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.text.TextUtils;
import com.android.server.wifi.util.ApConfigUtil;
+import com.android.server.wifi.util.ArrayUtils;
import com.android.server.wifi.util.ScanResultUtil;
import java.io.PrintWriter;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
@@ -60,6 +64,26 @@
*/
public class WifiShellCommand extends BasicShellCommandHandler {
private static String SHELL_PACKAGE_NAME = "com.android.shell";
+ // These don't require root access.
+ // However, these do perform permission checks in the corresponding WifiService methods.
+ private static final String[] NON_PRIVILEGED_COMMANDS = {
+ "add-suggestion",
+ "connect-network",
+ "forget-network",
+ "get-country-code",
+ "help",
+ "-h",
+ "list-scan-results",
+ "list-networks",
+ "list-suggestions",
+ "remove-suggestion",
+ "remove-all-suggestions",
+ "set-verbose-logging",
+ "set-wifi-enabled",
+ "start-scan",
+ "status",
+ };
+
private final ClientModeImpl mClientModeImpl;
private final WifiLockManager mWifiLockManager;
private final WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
@@ -86,16 +110,22 @@
@Override
public int onCommand(String cmd) {
+ // Treat no command as help command.
+ if (cmd == null || cmd.equals("")) {
+ cmd = "help";
+ }
// Explicit exclusion from root permission
- // Do not require root permission to maintain backwards compatibility with
- // `svc wifi [enable|disable]`.
- if (!"set-wifi-enabled".equals(cmd)) {
- checkRootPermission();
+ if (ArrayUtils.indexOf(NON_PRIVILEGED_COMMANDS, cmd) == -1) {
+ final int uid = Binder.getCallingUid();
+ if (uid != Process.ROOT_UID) {
+ throw new SecurityException(
+ "Uid " + uid + " does not have access to " + cmd + " wifi command");
+ }
}
final PrintWriter pw = getOutPrintWriter();
try {
- switch (cmd != null ? cmd : "") {
+ switch (cmd) {
case "set-ipreach-disconnect": {
boolean enabled;
String nextArg = getNextArgRequired();
@@ -358,12 +388,6 @@
return 0;
}
case "set-wifi-enabled": {
- // This command is explicitly exempted from checkRootPermission() (see beginning
- // of this method).
- // Do not require root permission to maintain backwards compatibility with
- // `svc wifi [enable|disable]`.
- // However, setWifiEnabled() does perform its own check for the
- // android.Manifest.permission.CHANGE_WIFI_STATE permission.
boolean enabled;
String nextArg = getNextArgRequired();
if ("enabled".equals(nextArg)) {
@@ -433,20 +457,21 @@
case "connect-network": {
String ssid = getNextArgRequired();
String type = getNextArgRequired();
- String optionalPassphrase = getNextArg();
WifiConfiguration configuration = new WifiConfiguration();
configuration.SSID = "\"" + ssid + "\"";
if (TextUtils.equals(type, "wpa3")) {
configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
+ configuration.preSharedKey = "\"" + getNextArgRequired() + "\"";
} else if (TextUtils.equals(type, "wpa2")) {
configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
+ configuration.preSharedKey = "\"" + getNextArgRequired() + "\"";
} else if (TextUtils.equals(type, "owe")) {
configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
} else if (TextUtils.equals(type, "open")) {
configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
- }
- if (optionalPassphrase != null) {
- configuration.preSharedKey = "\"" + optionalPassphrase + "\"";
+ } else {
+ pw.println("Unknown network type " + type);
+ return -1;
}
CountDownLatch countDownLatch = new CountDownLatch(1);
IActionListener.Stub actionListener = new IActionListener.Stub() {
@@ -521,6 +546,49 @@
}
mWifiService.enableVerboseLogging(enabled ? 1 : 0);
break;
+ case "add-suggestion":
+ mWifiService.addNetworkSuggestions(
+ Arrays.asList(buildSuggestion(pw)), SHELL_PACKAGE_NAME, null);
+ break;
+ case "remove-suggestion":
+ mWifiService.removeNetworkSuggestions(
+ Arrays.asList(buildSuggestion(pw)), SHELL_PACKAGE_NAME);
+ break;
+ case "remove-all-suggestions":
+ mWifiService.removeNetworkSuggestions(
+ Collections.emptyList(), SHELL_PACKAGE_NAME);
+ break;
+ case "list-suggestions":
+ List<WifiNetworkSuggestion> suggestions =
+ mWifiService.getNetworkSuggestions(SHELL_PACKAGE_NAME);
+ if (suggestions == null || suggestions.isEmpty()) {
+ pw.println("No suggestions");
+ } else {
+ pw.println("SSID Security type");
+ for (WifiNetworkSuggestion suggestion : suggestions) {
+ String securityType = null;
+ if (WifiConfigurationUtil.isConfigForSaeNetwork(
+ suggestion.getWifiConfiguration())) {
+ securityType = "wpa3";
+ } else if (WifiConfigurationUtil.isConfigForPskNetwork(
+ suggestion.getWifiConfiguration())) {
+ securityType = "wpa2";
+ } else if (WifiConfigurationUtil.isConfigForEapNetwork(
+ suggestion.getWifiConfiguration())) {
+ securityType = "eap";
+ } else if (WifiConfigurationUtil.isConfigForOweNetwork(
+ suggestion.getWifiConfiguration())) {
+ securityType = "owe";
+ } else if (WifiConfigurationUtil.isConfigForOpenNetwork(
+ suggestion.getWifiConfiguration())) {
+ securityType = "open";
+ }
+ pw.println(String.format("%-32s %-4s",
+ WifiInfo.sanitizeSsid(suggestion.getWifiConfiguration().SSID),
+ securityType));
+ }
+ }
+ break;
default:
return handleDefaultCommands(cmd);
}
@@ -531,6 +599,27 @@
return -1;
}
+ private WifiNetworkSuggestion buildSuggestion(PrintWriter pw) {
+ String ssid = getNextArgRequired();
+ String type = getNextArgRequired();
+ WifiNetworkSuggestion.Builder suggestionBuilder =
+ new WifiNetworkSuggestion.Builder();
+ suggestionBuilder.setSsid(ssid);
+ if (TextUtils.equals(type, "wpa3")) {
+ suggestionBuilder.setWpa3Passphrase(getNextArgRequired());
+ } else if (TextUtils.equals(type, "wpa2")) {
+ suggestionBuilder.setWpa2Passphrase(getNextArgRequired());
+ } else if (TextUtils.equals(type, "owe")) {
+ suggestionBuilder.setIsEnhancedOpen(true);
+ } else if (TextUtils.equals(type, "open")) {
+ // nothing to do.
+ } else {
+ pw.println("Unknown network type " + type);
+ return null;
+ }
+ return suggestionBuilder.build();
+ }
+
private int sendLinkProbe(PrintWriter pw) throws InterruptedException {
// Note: should match WifiNl80211Manager#SEND_MGMT_FRAME_TIMEOUT_MS
final int sendMgmtFrameTimeoutMs = 1000;
@@ -583,22 +672,63 @@
|| Arrays.binarySearch(allowed6gFreq, apChannelMHz) >= 0;
}
- private void checkRootPermission() {
- final int uid = Binder.getCallingUid();
- if (uid == 0) {
- // Root can do anything.
- return;
- }
- throw new SecurityException("Uid " + uid + " does not have access to wifi commands");
+ private void onHelpNonPrivileged(PrintWriter pw) {
+ pw.println(" get-country-code");
+ pw.println(" Gets country code as a two-letter string");
+ pw.println(" set-wifi-enabled enabled|disabled");
+ pw.println(" Enables/disables Wifi on this device.");
+ pw.println(" list-scan-results");
+ pw.println(" Lists the latest scan results");
+ pw.println(" start-scan");
+ pw.println(" Start a new scan");
+ pw.println(" list-networks");
+ pw.println(" Lists the saved networks");
+ pw.println(" connect-network <ssid> open|owe|wpa2|wpa3 [<passphrase>]");
+ pw.println(" Connect to a network with provided params and save");
+ pw.println(" <ssid> - SSID of the network");
+ pw.println(" open|owe|wpa2|wpa3 - Security type of the network.");
+ pw.println(" - Use 'open' or 'owe' for networks with no passphrase");
+ pw.println(" - 'open' - Open networks (Most prevalent)");
+ pw.println(" - 'owe' - Enhanced open networks");
+ pw.println(" - Use 'wpa2' or 'wpa3' for networks with passphrase");
+ pw.println(" - 'wpa2' - WPA-2 PSK networks (Most prevalent)");
+ pw.println(" - 'wpa3' - WPA-3 PSK networks");
+ pw.println(" forget-network <networkId>");
+ pw.println(" Remove the network mentioned by <networkId>");
+ pw.println(" - Use list-networks to retrieve <networkId> for the network");
+ pw.println(" status");
+ pw.println(" Current wifi status");
+ pw.println(" set-verbose-logging enabled|disabled ");
+ pw.println(" Set the verbose logging enabled or disabled");
+ pw.println(" add-suggestion <ssid> open|owe|wpa2|wpa3 [<passphrase>]");
+ pw.println(" Add a network suggestion with provided params");
+ pw.println(" Use 'network-suggestions-set-user-approved " + SHELL_PACKAGE_NAME + " yes'"
+ + " to approve suggestions added via shell (Needs root access)");
+ pw.println(" <ssid> - SSID of the network");
+ pw.println(" open|owe|wpa2|wpa3 - Security type of the network.");
+ pw.println(" - Use 'open' or 'owe' for networks with no passphrase");
+ pw.println(" - 'open' - Open networks (Most prevalent)");
+ pw.println(" - 'owe' - Enhanced open networks");
+ pw.println(" - Use 'wpa2' or 'wpa3' for networks with passphrase");
+ pw.println(" - 'wpa2' - WPA-2 PSK networks (Most prevalent)");
+ pw.println(" - 'wpa3' - WPA-3 PSK networks");
+ pw.println(" remove-suggestion <ssid> open|owe|wpa2|wpa3");
+ pw.println(" Remove a network suggestion with provided params");
+ pw.println(" <ssid> - SSID of the network");
+ pw.println(" open|owe|wpa2|wpa3 - Security type of the network.");
+ pw.println(" - Use 'open' or 'owe' for networks with no passphrase");
+ pw.println(" - 'open' - Open networks (Most prevalent)");
+ pw.println(" - 'owe' - Enhanced open networks");
+ pw.println(" - Use 'wpa2' or 'wpa3' for networks with passphrase");
+ pw.println(" - 'wpa2' - WPA-2 PSK networks (Most prevalent)");
+ pw.println(" - 'wpa3' - WPA-3 PSK networks");
+ pw.println(" remove-all-suggestions");
+ pw.println(" Removes all suggestions added via shell");
+ pw.println(" list-suggestions");
+ pw.println(" Lists the suggested networks added via shell");
}
- @Override
- public void onHelp() {
- final PrintWriter pw = getOutPrintWriter();
-
- pw.println("Wi-Fi (wifi) commands:");
- pw.println(" help");
- pw.println(" Print this help text.");
+ private void onHelpPrivileged(PrintWriter pw) {
pw.println(" set-ipreach-disconnect enabled|disabled");
pw.println(" Sets whether CMD_IP_REACHABILITY_LOST events should trigger disconnects.");
pw.println(" get-ipreach-disconnect");
@@ -632,42 +762,27 @@
pw.println(" or left for normal operation.");
pw.println(" force-country-code enabled <two-letter code> | disabled ");
pw.println(" Sets country code to <two-letter code> or left for normal value");
- pw.println(" get-country-code");
- pw.println(" Gets country code as a two-letter string");
pw.println(" set-wifi-watchdog enabled|disabled");
pw.println(" Sets whether wifi watchdog should trigger recovery");
pw.println(" get-wifi-watchdog");
pw.println(" Gets setting of wifi watchdog trigger recovery.");
- pw.println(" set-wifi-enabled enabled|disabled");
- pw.println(" Enables/disables Wifi on this device.");
pw.println(" get-softap-supported-features");
pw.println(" Gets softap supported features. Will print 'wifi_softap_acs_supported'");
pw.println(" and/or 'wifi_softap_wpa3_sae_supported', each on a separate line.");
pw.println(" settings-reset");
pw.println(" Initiates wifi settings reset");
- pw.println(" list-scan-results");
- pw.println(" Lists the latest scan results");
- pw.println(" start-scan");
- pw.println(" Start a new scan");
- pw.println(" list-networks");
- pw.println(" Lists the saved networks");
- pw.println(" connect-network <ssid> open|owe|wpa2|wpa3 [<passphrase>]");
- pw.println(" Connect to a network with provided params and save");
- pw.println(" <ssid> - SSID of the network");
- pw.println(" open|owe|wpa2|wpa3 - Security type of the network.");
- pw.println(" - Use 'open' or 'owe' for networks with no passphrase");
- pw.println(" - 'open' - Open networks (Most prevalent)");
- pw.println(" - 'owe' - Enhanced open networks");
- pw.println(" - Use 'wpa2' or 'wpa3' for networks with passphrase");
- pw.println(" - 'wpa2' - WPA-2 PSK networks (Most prevalent)");
- pw.println(" - 'wpa3' - WPA-3 PSK networks");
- pw.println(" forget-network <networkId>");
- pw.println(" Remove the network mentioned by <networkId>");
- pw.println(" - Use list-networks to retrieve <networkId> for the network");
- pw.println(" status");
- pw.println(" Current wifi status");
- pw.println(" set-verbose-logging enabled|disabled ");
- pw.println(" Set the verbose logging enabled or disabled");
+ }
+
+ @Override
+ public void onHelp() {
+ final PrintWriter pw = getOutPrintWriter();
+ pw.println("Wi-Fi (wifi) commands:");
+ pw.println(" help or -h");
+ pw.println(" Print this help text.");
+ onHelpNonPrivileged(pw);
+ if (Binder.getCallingUid() == Process.ROOT_UID) {
+ onHelpPrivileged(pw);
+ }
pw.println();
}
}
diff --git a/service/java/com/android/server/wifi/WrongPasswordNotifier.java b/service/java/com/android/server/wifi/WrongPasswordNotifier.java
index d086ad5..9975f97 100644
--- a/service/java/com/android/server/wifi/WrongPasswordNotifier.java
+++ b/service/java/com/android/server/wifi/WrongPasswordNotifier.java
@@ -42,11 +42,11 @@
// Flag indicating if a wrong password error is detected for the current connection.
private boolean mWrongPasswordDetected;
- private final Context mContext;
+ private final WifiContext mContext;
private final NotificationManager mNotificationManager;
private final FrameworkFacade mFrameworkFacade;
- public WrongPasswordNotifier(Context context, FrameworkFacade frameworkFacade) {
+ public WrongPasswordNotifier(WifiContext context, FrameworkFacade frameworkFacade) {
mContext = context;
mFrameworkFacade = frameworkFacade;
mNotificationManager =
@@ -86,7 +86,7 @@
.setAutoCancel(true)
.setTimeoutAfter(CANCEL_TIMEOUT_MILLISECONDS)
// TODO(zqiu): consider creating a new icon.
- .setSmallIcon(Icon.createWithResource(WifiContext.WIFI_OVERLAY_APK_PKG_NAME,
+ .setSmallIcon(Icon.createWithResource(mContext.getWifiOverlayApkPkgName(),
com.android.wifi.resources.R.drawable.stat_notify_wifi_in_range))
.setContentTitle(mContext.getString(
com.android.wifi.resources.R.string.wifi_available_title_failed_to_connect))
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
index 682af56..18ff047 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
@@ -1554,7 +1554,7 @@
* Tell the network agent the network is now connected.
*/
public void setConnected(WifiAwareNetworkAgent networkAgent) {
- networkAgent.setConnected();
+ networkAgent.markConnected();
}
}
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
index 1884536..ad8480a 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
@@ -20,6 +20,8 @@
import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.net.Network;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
@@ -53,7 +55,7 @@
import com.android.server.wifi.hotspot2.soap.command.BrowserUri;
import com.android.server.wifi.hotspot2.soap.command.PpsMoData;
import com.android.server.wifi.hotspot2.soap.command.SppCommand;
-import com.android.wifi.resources.R;
+import com.android.server.wifi.util.Environment;
import java.net.MalformedURLException;
import java.net.URL;
@@ -781,24 +783,43 @@
}
Intent intent = new Intent(WifiManager.ACTION_PASSPOINT_LAUNCH_OSU_VIEW);
- intent.setPackage(mContext.getResources()
- .getString(R.string.config_wifiOsuLoginPackage));
intent.putExtra(WifiManager.EXTRA_OSU_NETWORK, mNetwork);
intent.putExtra(WifiManager.EXTRA_URL, mWebUrl);
+ intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setFlags(
- Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
-
- // Verify that the intent will resolve to an activity
- if (intent.resolveActivity(mContext.getPackageManager()) != null) {
- mContext.startActivityAsUser(intent, UserHandle.CURRENT);
- invokeProvisioningCallback(PROVISIONING_STATUS,
- ProvisioningCallback.OSU_STATUS_WAITING_FOR_REDIRECT_RESPONSE);
- changeState(STATE_WAITING_FOR_REDIRECT_RESPONSE);
- } else {
+ List<ResolveInfo> resolveInfos = mContext.getPackageManager()
+ .queryIntentActivities(
+ intent,
+ PackageManager.MATCH_DEFAULT_ONLY | PackageManager.MATCH_SYSTEM_ONLY);
+ if (resolveInfos == null || resolveInfos.isEmpty()) {
Log.e(TAG, "can't resolve the activity for the intent");
resetStateMachineForFailure(ProvisioningCallback.OSU_FAILURE_NO_OSU_ACTIVITY_FOUND);
+ return;
}
+
+ if (resolveInfos.size() > 1) {
+ if (mVerboseLoggingEnabled) {
+ Log.i(TAG, "Multiple OsuLogin apps found: "
+ + resolveInfos.stream()
+ .map(info -> info.activityInfo.applicationInfo.packageName)
+ .collect(Collectors.joining(", ")));
+ }
+
+ // if multiple apps are found, filter out the default implementation supplied
+ // in the Wifi apex and let other implementations override.
+ resolveInfos.removeIf(info ->
+ Environment.isAppInWifiApex(info.activityInfo.applicationInfo));
+ }
+ // forcefully resolve to the first one
+ String packageName = resolveInfos.get(0).activityInfo.applicationInfo.packageName;
+ intent.setPackage(packageName);
+ if (mVerboseLoggingEnabled) {
+ Log.i(TAG, "Opening OsuLogin app: " + packageName);
+ }
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+ invokeProvisioningCallback(PROVISIONING_STATUS,
+ ProvisioningCallback.OSU_STATUS_WAITING_FOR_REDIRECT_RESPONSE);
+ changeState(STATE_WAITING_FOR_REDIRECT_RESPONSE);
}
/**
diff --git a/service/java/com/android/server/wifi/util/Environment.java b/service/java/com/android/server/wifi/util/Environment.java
index b4df26d..a423d55 100644
--- a/service/java/com/android/server/wifi/util/Environment.java
+++ b/service/java/com/android/server/wifi/util/Environment.java
@@ -17,6 +17,7 @@
package com.android.server.wifi.util;
import android.content.ApexEnvironment;
+import android.content.pm.ApplicationInfo;
import android.os.UserHandle;
import java.io.File;
@@ -33,6 +34,13 @@
private static final String WIFI_APEX_NAME = "com.android.wifi";
/**
+ * The path where the Wifi apex is mounted.
+ * Current value = "/apex/com.android.wifi"
+ */
+ private static final String WIFI_APEX_PATH =
+ new File("/apex", WIFI_APEX_NAME).getAbsolutePath();
+
+ /**
* Wifi shared folder.
*/
public static File getWifiSharedDirectory() {
@@ -46,4 +54,12 @@
return ApexEnvironment.getApexEnvironment(WIFI_APEX_NAME)
.getCredentialProtectedDataDirForUser(UserHandle.of(userId));
}
+
+ /**
+ * Returns true if the app is in the Wifi apex, false otherwise.
+ * Checks if the app's path starts with "/apex/com.android.wifi".
+ */
+ public static boolean isAppInWifiApex(ApplicationInfo appInfo) {
+ return appInfo.sourceDir.startsWith(WIFI_APEX_PATH);
+ }
}
diff --git a/service/java/com/android/server/wifi/util/ScanResultUtil.java b/service/java/com/android/server/wifi/util/ScanResultUtil.java
index 320490c..dc2281a 100644
--- a/service/java/com/android/server/wifi/util/ScanResultUtil.java
+++ b/service/java/com/android/server/wifi/util/ScanResultUtil.java
@@ -243,4 +243,24 @@
}
}
}
+
+ /**
+ * Check if ScarResult list is valid.
+ */
+ public static boolean validateScanResultList(List<ScanResult> scanResults) {
+ if (scanResults == null || scanResults.isEmpty()) {
+ return false;
+ }
+ for (ScanResult scanResult : scanResults) {
+ if (!validate(scanResult)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean validate(ScanResult scanResult) {
+ return scanResult != null && scanResult.SSID != null
+ && scanResult.capabilities != null && scanResult.BSSID != null;
+ }
}
diff --git a/service/java/com/android/server/wifi/util/TelephonyUtil.java b/service/java/com/android/server/wifi/util/TelephonyUtil.java
index 9b541db..b7b2d9e 100644
--- a/service/java/com/android/server/wifi/util/TelephonyUtil.java
+++ b/service/java/com/android/server/wifi/util/TelephonyUtil.java
@@ -1143,6 +1143,7 @@
public int getCarrierIdForPackageWithCarrierPrivileges(String packageName) {
List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
if (subInfoList == null || subInfoList.isEmpty()) {
+ if (mVerboseLogEnabled) Log.v(TAG, "No subs for carrier privilege check");
return TelephonyManager.UNKNOWN_CARRIER_ID;
}
for (SubscriptionInfo info : subInfoList) {
diff --git a/service/java/com/android/server/wifi/util/XmlUtil.java b/service/java/com/android/server/wifi/util/XmlUtil.java
index d20ee7e..1984e41 100644
--- a/service/java/com/android/server/wifi/util/XmlUtil.java
+++ b/service/java/com/android/server/wifi/util/XmlUtil.java
@@ -456,8 +456,6 @@
configuration.allowedSuiteBCiphers.toByteArray());
XmlUtil.writeNextValue(out, XML_TAG_SHARED, configuration.shared);
XmlUtil.writeNextValue(out, XML_TAG_IS_AUTO_JOIN, configuration.allowAutojoin);
- XmlUtil.writeNextValue(out, XML_TAG_IS_TRUSTED, configuration.trusted);
-
}
/**
@@ -487,6 +485,7 @@
@Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
writeCommonElementsToXml(out, configuration, encryptionUtil);
+ XmlUtil.writeNextValue(out, XML_TAG_IS_TRUSTED, configuration.trusted);
XmlUtil.writeNextValue(out, XML_TAG_BSSID, configuration.BSSID);
XmlUtil.writeNextValue(out, XML_TAG_STATUS, configuration.status);
XmlUtil.writeNextValue(out, XML_TAG_FQDN, configuration.FQDN);
diff --git a/service/proto/src/metrics.proto b/service/proto/src/metrics.proto
index f2ed398..34eb283 100644
--- a/service/proto/src/metrics.proto
+++ b/service/proto/src/metrics.proto
@@ -640,6 +640,12 @@
// Metrics related to limitation in soft ap config
optional SoftApConfigLimitationMetrics soft_ap_config_limitation_metrics = 178;
+
+ // WiFi channel utilization histogram of various RF bands
+ optional ChannelUtilizationHistogram channel_utilization_histogram = 179;
+
+ // WiFi Tx and Rx throughput histogram at various RF bands
+ optional ThroughputMbpsHistogram throughput_mbps_histogram = 180;
}
// Information that gets logged for every WiFi connection.
@@ -2602,6 +2608,15 @@
// Easy Connect (DPP) operation time bucket
repeated HistogramBucketInt32 dpp_operation_time = 7;
+ // Number of Enrollee-Responder peer devices supporting DPP protocol version 1
+ optional int32 num_dpp_r1_capable_enrollee_responder_devices = 8;
+
+ // Number of Enrollee-Responder peer devices supporting DPP protocol version 2
+ optional int32 num_dpp_r2_capable_enrollee_responder_devices = 9;
+
+ // Number of Enrollee-Responder incompatible configurations found in DPP R2 compatibility check.
+ optional int32 num_dpp_r2_enrollee_responder_incompatible_configuration = 10;
+
// Histogram bucket for Wi-Fi DPP configurator success
message DppConfiguratorSuccessStatusHistogramBucket {
// status type defining the bucket
@@ -2626,6 +2641,9 @@
// Easy Connect Configurator success event: Configuration sent to enrollee
EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 1;
+
+ // Easy Connect Configurator success event: Configuration applied by enrollee
+ EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 2;
}
enum DppFailureCode {
@@ -2661,6 +2679,15 @@
// Easy Connect Failure event: Invalid network provided to Easy Connect configurator.
// Network must either be WPA3-Personal (SAE) or WPA2-Personal (PSK).
EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = 9;
+
+ // Easy Connect R2 Failure event: Enrollee cannot find the network.
+ EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = 10;
+
+ // Easy Connect R2 Failure event: Enrollee failed to authenticate with the network.
+ EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = 11;
+
+ // Easy Connect R2 Failure event: Enrollee rejected the configuration.
+ EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = 12;
}
}
@@ -3055,3 +3082,25 @@
// setting limitation
repeated Int32Count max_client_setting_when_reach_histogram = 4;
}
+
+// Channel utilization histogram
+// The valid utilization range is between 0 and 255 corresponding to
+// utilization ratio between 0 and 1
+message ChannelUtilizationHistogram {
+ // Histogram at 2G
+ repeated HistogramBucketInt32 utilization_2g = 1;
+ // Histogram above 2G
+ repeated HistogramBucketInt32 utilization_above_2g = 2;
+}
+
+// Throughput histogram
+message ThroughputMbpsHistogram {
+ // Tx histogram at 2G
+ repeated HistogramBucketInt32 tx_2g = 1;
+ // Tx histogram above 2G
+ repeated HistogramBucketInt32 tx_above_2g = 2;
+ // Rx histogram at 2G
+ repeated HistogramBucketInt32 rx_2g = 3;
+ // Rx histogram above 2G
+ repeated HistogramBucketInt32 rx_above_2g = 4;
+}
diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index e51e640..b5037b7 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -399,7 +399,4 @@
<!-- Enable WPA2 to WPA3 auto-upgrade offload to capable Driver/Firmware -->
<bool translatable="false" name="config_wifiSaeUpgradeOffloadEnabled">false</bool>
-
- <!-- Package name for the OSU Login APK -->
- <string translatable="false" name="config_wifiOsuLoginPackage">com.android.hotspot2.osulogin</string>
</resources>
diff --git a/service/res/values/overlayable.xml b/service/res/values/overlayable.xml
index a6a37a3..7244911 100644
--- a/service/res/values/overlayable.xml
+++ b/service/res/values/overlayable.xml
@@ -126,7 +126,6 @@
<item type="integer" name="config_wifiPollRssiIntervalMilliseconds" />
<item type="bool" name="config_wifiSaeUpgradeEnabled" />
<item type="bool" name="config_wifiSaeUpgradeOffloadEnabled" />
- <item type="string" name="config_wifiOsuLoginPackage" />
<!-- Params from config.xml that can be overlayed -->
<!-- Params from strings.xml that can be overlayed -->
@@ -190,7 +189,6 @@
<item type="string" name="wifi_eap_error_message_code_32766" />
<item type="string" name="wifi_softap_auto_shutdown_timeout_expired_title" />
<item type="string" name="wifi_softap_auto_shutdown_timeout_expired_summary" />
- <item type="string" name="wifi_softap_auto_shutdown_timeout_expired_detail" />
<item type="string" name="wifi_sim_required_title" />
<item type="string" name="wifi_sim_required_message" />
<!-- Params from strings.xml that can be overlayed -->
diff --git a/service/resources-certs/com.android.wifi.resources.pk8 b/service/resources-certs/com.android.wifi.resources.pk8
new file mode 100644
index 0000000..50cca90
--- /dev/null
+++ b/service/resources-certs/com.android.wifi.resources.pk8
Binary files differ
diff --git a/service/resources-certs/com.android.wifi.resources.x509.pem b/service/resources-certs/com.android.wifi.resources.x509.pem
new file mode 100644
index 0000000..c321be1
--- /dev/null
+++ b/service/resources-certs/com.android.wifi.resources.x509.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGJzCCBA+gAwIBAgIUYJCfWCLIVw8RN9EmWeX78BvlReMwDQYJKoZIhvcNAQEL
+BQAwgaExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
+DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
+b2lkMR0wGwYDVQQDDBRTZXJ2aWNlV2lmaVJlc291cmNlczEiMCAGCSqGSIb3DQEJ
+ARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAgFw0yMDAzMjUwMzA0MDFaGA80NzU4MDIx
+OTAzMDQwMVowgaExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYw
+FAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQL
+DAdBbmRyb2lkMR0wGwYDVQQDDBRTZXJ2aWNlV2lmaVJlc291cmNlczEiMCAGCSqG
+SIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQAD
+ggIPADCCAgoCggIBAOqOCNZuwS5nIEg5wUPop40+WSAZEQ5SL/uSNU1dnGMSxkD5
+QqZQ3eWKlLSvP1FXtbQPTojXn2fa8w2P39dUAe33NXgpSHZVk18DMgeepNCAbynJ
+fciqYCMjnT3G1scIZP8HCxAXsuoynqLSms7IyombgM4iePVKKKwRpe3F3BmWgjgz
+RatW6C2CJLHc4KgCD53b4w9XHrQ8l3L1c3bgIwjaDSd0VxKIa41KtHHWp3LuvxX5
+4wz6tbBNW5ZMNDEfvF7CGmTCkdbMAYkWcJxZxA57E2tpxXd+2TnEDo6HL7Yq28jG
+r8jN6U63zRsKHLMi+Dtyei0w1nBxtTf5KsWI7B5Cxavl+V+tCsnNfq5Gu+vjJnlL
+0kpFcBixG/TPv7H+NgyO5D7joAyGSctfMkTPWdSRD/FNTs30yil+hxUIu4mFYtXO
++c6yIm11OBmGz1IoqetgbBhQiUwy+p8oqge2NtFDaIJ3dkd5cmNUF/EXI89aUhu0
+o/Vo2coUpR/cYZTgexfk2RKcH3RkuG69HXofrC9SGY0RI7GgmaG0e1inBjVrOydP
+1XXJmF3DV8yy8NmkJklbljsGD52XuBC6VQ0eIh7cLKWjgMCJFFNkNgU0syZ3+bma
+28FWvzJzd3ii5seWqePGgcrfdgjxblNzQEKWw0Me9Wn/S0OKOz/5OAM9Z7RDAgMB
+AAGjUzBRMB0GA1UdDgQWBBQjYEU0cbWxEO42h68+ttN5+wDSITAfBgNVHSMEGDAW
+gBQjYEU0cbWxEO42h68+ttN5+wDSITAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
+DQEBCwUAA4ICAQCatnV7MZsIQTPo3AbbvmSPfyFM4/ncRDao+hxxvDKwMMWw6O2r
+uKPIbdj3xcH4vwvM2v3Kg+YCNrRgTTG23QHXNzHgXM75o1q7djGEiuOaZ6lwGh0G
+KD0B1xnYVRKqpacoP7SJ2MLWpum1i6c12P3s4JLBIiU4OtHKOozai37YMFM1Iwla
+QsGwgXyScRPs091aGe0G4eC0/10skHW0ASS4VUjbvqQE6opfMLdoMhuqAxTY8Nlz
+51B2smf/w7AAU4dpOE5sgdctbWpMNovAZe8yxt3Wk48pFIYPwTRXM6wSXoqYzX23
+s/rJmuGzX3PKV5hVZazYetj5clK/HB4Y/Clf3bVaoOKKSUgtOT3KB732yHIfFJDl
+vhqe5niRNf2Decy6aYJFw/IqMYM/3Fh4B1JcDFHzOq4Ta6yuvhqbXVdbM5dPzcgQ
+CO640v20uQVMjpknnxdBu7QxLMYuAfeuJkoWnvRtjSwQHPisnCWfxu6ryBIN3Xg7
+HtiEv+CVrvyq2UGbKhCtk/Z50eOdyRTAldoP3AcGbakZHtKAuz/m9TlTYDCnh/tH
+79soVqj2HMaM5XzslueGaERt149pr8uOhhK4NO+e1bc65Fw9ysHVrVn4pcaq8OGm
+yPSAsaHXcskBG5CywWfPcBaSij/0+QLbddie1cyeCFxz0aDypNMH+SCgsA==
+-----END CERTIFICATE-----
diff --git a/service/resources-certs/key.pem b/service/resources-certs/key.pem
new file mode 100644
index 0000000..31acc3c
--- /dev/null
+++ b/service/resources-certs/key.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQDqjgjWbsEuZyBI
+OcFD6KeNPlkgGREOUi/7kjVNXZxjEsZA+UKmUN3lipS0rz9RV7W0D06I159n2vMN
+j9/XVAHt9zV4KUh2VZNfAzIHnqTQgG8pyX3IqmAjI509xtbHCGT/BwsQF7LqMp6i
+0prOyMqJm4DOInj1SiisEaXtxdwZloI4M0WrVugtgiSx3OCoAg+d2+MPVx60PJdy
+9XN24CMI2g0ndFcSiGuNSrRx1qdy7r8V+eMM+rWwTVuWTDQxH7xewhpkwpHWzAGJ
+FnCcWcQOexNracV3ftk5xA6Ohy+2KtvIxq/IzelOt80bChyzIvg7cnotMNZwcbU3
++SrFiOweQsWr5flfrQrJzX6uRrvr4yZ5S9JKRXAYsRv0z7+x/jYMjuQ+46AMhknL
+XzJEz1nUkQ/xTU7N9MopfocVCLuJhWLVzvnOsiJtdTgZhs9SKKnrYGwYUIlMMvqf
+KKoHtjbRQ2iCd3ZHeXJjVBfxFyPPWlIbtKP1aNnKFKUf3GGU4HsX5NkSnB90ZLhu
+vR16H6wvUhmNESOxoJmhtHtYpwY1azsnT9V1yZhdw1fMsvDZpCZJW5Y7Bg+dl7gQ
+ulUNHiIe3Cylo4DAiRRTZDYFNLMmd/m5mtvBVr8yc3d4oubHlqnjxoHK33YI8W5T
+c0BClsNDHvVp/0tDijs/+TgDPWe0QwIDAQABAoICAQCXq2SXlGKiqNi9G2uXh/fg
+Y3KqSMs4oXiZij+hWWjov5knJocsmJoD9gqWk8Ozy62ZU1SLNDLFq1UDbgdma9Ib
+mIEgxEExE8EJ7T0KpFEa6hH3yWzmtxUXY84nxk3Xwdvc9Sb4LvroafcefmTQVhJx
+zPYLVUs2AdAvA/JxwEHE4gguYykn1DiqRL+Jq7Qxr7N9dlRq9QDLt2qPUZxqQCEn
+diiPXLF5MHGrmaT4/76jmTJC+aUSHYQjDsKse3Y8VbMu6wC6Kv63EI/ln3cOAxW9
+72PtTyX7UTESI27uRwhZGXmpaKD+jffRiRS96VoJlBFED5BlbHEdoMl3+kzoEtPq
+uIA+8gdl0pXtQpzR340d6vqSU+THnqhR4OCyhZXRSJAqyBIlG7pWmNMnMJoARUIq
+q3vJmiakgNGcFqFaddYL8dUdZiwBg37WIG40GUhEaSaPc9BYpX4mTxheWRqPUHuj
+BUQpZA8qUZx4zlkJ8OpqCznU5wCPs6CRxB9+MXh7+Rk4l0aEir2yvQpkQuoH+qx8
+HzinDpj6B+PPDuHhQkVu7EZxq/hnl3RktHghT+qOH36Z4f6yx6+UqR724NcHC4zn
+igS4JP1wq7egedPbr1v+GZWWa+/HIkUicy1gT2FxvlLAXiYBCQh9lQW80tPLREE5
+OC++g3Znn4BhAxC9Nf9MIQKCAQEA+A/Mq6etUdjEER0F22MMm2H5wca/x+VAPw03
+0PkpuWD6hEXIWEq5olowMAmsy99XDQmLhP4qnARNbVcqJ3/Ad8TDiPc9u4ofHvEI
+r0BiB+90Y+MSydjtE2JCGqZ+7f1o9gv02Ym28ZNmF786oJKoCLTF7oarzuFSyiBL
+V6dcE6zzkaMNpHj9U2boeI/vgdhUlLPZ3ES+o2FUCWvuuhfkj6NheCuyqhKiLTnW
+1M3sLjSbxQKLkY0ebPK0I3l8pasBKRE34MUWRRc5sHQquvdv5YHRLHsL1Ti4zzTM
+jPejMWsBHFdygA2EIz144PV0rLQAXURtu1fp864oRhMmQeIvqwKCAQEA8g+VDmyR
+QJrhea199judCRvURxsFR9Cy6ZQpGdYpK9OQcHA1AGig4hCW2S1+ZIdJCOWvjdBQ
+X2SbtM0tzjOkwqfsMjYubXcPMLB2tM8eOSPD/kOfDL4+G8wjGhDeua8loTOg3Jzl
+MeSCDrPhO5gIzXDr+ysnMQblLrL36YJb+PTwMHgk1NdgCQ9PBa2BHbKpPiK3mMM0
+qQXz+zRublvB0uXYaNlUpgdL35fXo5ChKgrMvk9rOiozh/jE/SFTM1iRGU4WJUlN
+KB1CxXR5Cn+lYeO8yF+aZO0a7lWq9R8i2bXsMReQIr+sOBE2cAZP+VP18chujSkP
+DnAwoLVxmHXVyQKCAQAA9h6285lqXcq0vkYNiZ68425SX/DSV4MeO3Dh8HVG8KdH
+5/VU0kVR6cOSDBeNWro9pLHTvCByJloeeF4DdS1LyYlweHTWyzw/pHOCKl+25Cix
+Umn6OksA7jqPW+HWDktf2MAEL9JzsTyODwGtKaRZFEpIGGGGFb16ZxGjr1ReByeS
+gu1Em+tvbVCtVvF4sVvyj5fikKmkfHYU60QrmHgcTmfMTW8N1bCnODgq7vlhXHbW
+FqJv1/osNeyYzpm7EqSYgiaTSnBBqEti8bBQtTDL1Or4nyl2lBezReMdEMCjKmUA
+tR4OfP7sHArh5FGlcbUmp2M9fKO9fAlP7DcTvkqtAoIBAQDp0hd/6Wud5n5rFSWZ
+1xfoFpPFY9qD9pr8enwBUxhOF31sv1bTYD4YYUH147Y10WDBUW11JYadvweRbKkU
+iFpdFexYzHGol9t6gtsH6RIey+elExjuLE6+d0BpC2a6Iu/MeZynvn6+5SakoSmu
+cTv/h1bMNnETML/tjj9ftua045WonEWnu6wu1DTXHTSdxVkqhkqnK9kQdImrXIhX
+3haqbA/RqC3WezHVeE162Fh1zhzcsMa5Vs6UR7+xbKF79c+jjARkXBxF5Y38Qngx
+pf/RQTW4sHDpkQf0tZgAU+VMPCk9eq9mgZQQTMAzEkXqaCopNh1kCgdbQRAYDWz/
+gsPRAoIBAQCVVhnmVFI3+u0vFcnJsKScw/D/hUcv2czUje0Li7fz84lrT2sXiSfH
+iFsvG9SwFsrSvTVcAy/agumE3nzsvymTQvdu7irVJczKw4lUdx22ZqdupqQRsUMR
+2kx2fzPLUlG5eHnFUpyUDIVwPSfmjSv6MwF2ScWFLWyR0coPDgYz/EdUENDSXkzW
+CCxbF7lH7jc60vOVqMH0HyFT+k5SOQDVWckzQzGLoMhKobv9FHijCnc/jdsAYkOx
++MMdUcFf1X4WjHb9U5be/YrhiOO4Ar41hEm2ezsrcreszr69Zv4Tw3BLpr/nkS37
+adx3U1hB9OzUKVm21xtowKxcrEsOpvR1
+-----END PRIVATE KEY-----
diff --git a/tests/wifitests/Android.bp b/tests/wifitests/Android.bp
index 4d808b7..7fd2a5f 100644
--- a/tests/wifitests/Android.bp
+++ b/tests/wifitests/Android.bp
@@ -86,7 +86,7 @@
"jsr305",
"services",
// load the resources from the resources APK.
- "wifi-service-resources",
+ "ServiceWifiResources",
"unsupportedappusage",
],
diff --git a/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java b/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java
index 00afa91..2567faa 100644
--- a/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java
@@ -628,14 +628,15 @@
when(mClock.getWallClockMillis()).thenReturn(0L);
long testDuration = 5500L;
mBssidBlocklistMonitor.blockBssidForDurationMs(TEST_BSSID_1, TEST_SSID_1, testDuration);
+ assertEquals(1, mBssidBlocklistMonitor.updateAndGetBssidBlocklist().size());
- // Verify that the BSSID is not removed from blocklist dispite of regular "clear" calls.
- when(mClock.getWallClockMillis()).thenReturn(testDuration);
- mBssidBlocklistMonitor.clearBssidBlocklist();
+ // Verify that the BSSID is removed from blocklist by clearBssidBlocklistForSsid
mBssidBlocklistMonitor.clearBssidBlocklistForSsid(TEST_SSID_1);
- Set<String> bssidList = mBssidBlocklistMonitor.updateAndGetBssidBlocklist();
- assertEquals(1, bssidList.size());
- assertTrue(bssidList.contains(TEST_BSSID_1));
+ assertEquals(0, mBssidBlocklistMonitor.updateAndGetBssidBlocklist().size());
+
+ // Add the BSSID to blocklist again.
+ mBssidBlocklistMonitor.blockBssidForDurationMs(TEST_BSSID_1, TEST_SSID_1, testDuration);
+ assertEquals(1, mBssidBlocklistMonitor.updateAndGetBssidBlocklist().size());
// Verify that the BSSID is removed from blocklist once the specified duration is over.
when(mClock.getWallClockMillis()).thenReturn(testDuration + 1);
diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index 6028497..d912020 100644
--- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -3324,6 +3324,7 @@
mLooper.dispatchAll();
verify(mIpClient).shutdown();
verify(mWifiConfigManager).removeAllEphemeralOrPasspointConfiguredNetworks();
+ verify(mWifiConfigManager).clearUserTemporarilyDisabledList();
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java b/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java
index 19d17c9..e274d68 100644
--- a/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/DppManagerTest.java
@@ -481,6 +481,7 @@
dppEventCallback.onSuccess(CONFIGURATION_SENT);
mLooper.dispatchAll();
verify(mDppCallback).onSuccess(eq(EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT));
+ verify(mDppMetrics, times(1)).updateDppR1CapableEnrolleeResponderDevices();
verify(mDppCallback, never()).onSuccessConfigReceived(anyInt());
verify(mDppCallback, never()).onFailure(anyInt(), anyString(), anyString(), any());
verify(mDppMetrics).updateDppConfiguratorInitiatorRequests();
@@ -861,6 +862,7 @@
mLooper.dispatchAll();
verify(mDppCallback)
.onProgress(eq(EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE));
+ verify(mDppMetrics, times(1)).updateDppR2CapableEnrolleeResponderDevices();
// Generate an onSuccess callback
dppEventCallback.onSuccess(CONFIGURATION_APPLIED);
@@ -912,6 +914,10 @@
verify(mDppMetrics).updateDppConfiguratorInitiatorRequests();
verify(mDppMetrics).updateDppFailure(eq(appFailure));
verify(mDppMetrics).updateDppOperationTime(anyInt());
+ if ((internalFailure == CANNOT_FIND_NETWORK)
+ && (appFailure == EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE)) {
+ verify(mDppMetrics, times(1)).updateDppR2EnrolleeResponderIncompatibleConfiguration();
+ }
verifyNoMoreInteractions(mDppMetrics);
verifyCleanUpResources();
}
diff --git a/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java
index fd43578..e43da8f 100644
--- a/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/DppMetricsTest.java
@@ -18,13 +18,17 @@
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_BUSY;
+import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CONFIGURATION;
+import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION;
+import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_GENERIC;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_INVALID_URI;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_TIMEOUT;
+import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED;
import static android.net.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT;
import static com.android.server.wifi.DppMetrics.DPP_OPERATION_TIME;
@@ -185,10 +189,16 @@
for (int i = 0; i < value; i++) {
mDppMetrics.updateDppConfiguratorSuccess(EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT);
}
+ for (int i = 0; i < value; i++) {
+ mDppMetrics.updateDppConfiguratorSuccess(
+ EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED);
+ }
// Confirm that the consolidated log has the expected value
checkDppSuccesses(WifiMetricsProto.WifiDppLog.EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT,
value);
+ checkDppSuccesses(WifiMetricsProto.WifiDppLog
+ .EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED, value);
}
/**
@@ -378,6 +388,65 @@
}
/**
+ * Test EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testUpdateDppFailureCannotFindNetwork() throws Exception {
+ // Get a random value and call the update method 'value' times
+ int value = getNumOfTimes(MAX_ITERATIONS) + 1;
+
+ for (int i = 0; i < value; i++) {
+ mDppMetrics.updateDppFailure(EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK);
+ }
+
+ // Confirm that the consolidated log has the expected value
+ checkDppFailures(WifiMetricsProto.WifiDppLog.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK,
+ value);
+ }
+
+ /**
+ * Test EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testUpdateDppFailureEnrolleeAuthentication() throws Exception {
+ // Get a random value and call the update method 'value' times
+ int value = getNumOfTimes(MAX_ITERATIONS) + 1;
+
+ for (int i = 0; i < value; i++) {
+ mDppMetrics.updateDppFailure(EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION);
+ }
+
+ // Confirm that the consolidated log has the expected value
+ checkDppFailures(WifiMetricsProto.WifiDppLog
+ .EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION, value);
+ }
+
+ /**
+ * Test
+ * EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testUpdateDppFailureEnrolleeRejectedConfiguration() throws Exception {
+ // Get a random value and call the update method 'value' times
+ int value = getNumOfTimes(MAX_ITERATIONS) + 1;
+
+ for (int i = 0; i < value; i++) {
+ mDppMetrics.updateDppFailure(
+ EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION);
+ }
+
+ // Confirm that the consolidated log has the expected value
+ checkDppFailures(WifiMetricsProto.WifiDppLog
+ .EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION, value);
+ }
+
+ /**
* Test DPP operation time histogram. Pick a single time value from each bucket by selecting
* the max value minus 1, and call the update method random amount of times with this value.
* Then confirm that the output histogram has the expected value in each target bucket.
@@ -410,4 +479,61 @@
checkOperationBucketEqualsTo(i, value);
}
}
+
+ /**
+ * Test numDppR1CapableEnrolleeResponderDevices
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testUpdateDppR1CapableEnrolleeResponderDevices() throws Exception {
+ // Get a random value and call the update method 'value' times
+ int value = getNumOfTimes(MAX_ITERATIONS) + 1;
+
+ for (int i = 0; i < value; i++) {
+ mDppMetrics.updateDppR1CapableEnrolleeResponderDevices();
+ }
+
+ // Confirm that the consolidated log has the expected value
+ WifiMetricsProto.WifiDppLog mWifiDppLogProto = mDppMetrics.consolidateProto();
+ assertEquals(mWifiDppLogProto.numDppR1CapableEnrolleeResponderDevices, value);
+ }
+
+ /**
+ * Test numDppR2CapableEnrolleeResponderDevices
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testUpdateDppR2CapableEnrolleeResponderDevices() throws Exception {
+ // Get a random value and call the update method 'value' times
+ int value = getNumOfTimes(MAX_ITERATIONS) + 1;
+
+ for (int i = 0; i < value; i++) {
+ mDppMetrics.updateDppR2CapableEnrolleeResponderDevices();
+ }
+
+ // Confirm that the consolidated log has the expected value
+ WifiMetricsProto.WifiDppLog mWifiDppLogProto = mDppMetrics.consolidateProto();
+ assertEquals(mWifiDppLogProto.numDppR2CapableEnrolleeResponderDevices, value);
+ }
+
+ /**
+ * Test numDppR2EnrolleeResponderIncompatibleConfiguration
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testUpdateDppR2EnrolleeResponderIncompatibleConfiguration() throws Exception {
+ // Get a random value and call the update method 'value' times
+ int value = getNumOfTimes(MAX_ITERATIONS) + 1;
+
+ for (int i = 0; i < value; i++) {
+ mDppMetrics.updateDppR2EnrolleeResponderIncompatibleConfiguration();
+ }
+
+ // Confirm that the consolidated log has the expected value
+ WifiMetricsProto.WifiDppLog mWifiDppLogProto = mDppMetrics.consolidateProto();
+ assertEquals(mWifiDppLogProto.numDppR2EnrolleeResponderIncompatibleConfiguration, value);
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/EapFailureNotifierTest.java b/tests/wifitests/src/com/android/server/wifi/EapFailureNotifierTest.java
index ea030a4..08076dd 100644
--- a/tests/wifitests/src/com/android/server/wifi/EapFailureNotifierTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/EapFailureNotifierTest.java
@@ -16,13 +16,14 @@
package com.android.server.wifi;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.wifi.WifiConfiguration;
@@ -32,10 +33,6 @@
import androidx.test.filters.SmallTest;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-
-import static org.mockito.Mockito.lenient;
-
import com.android.server.wifi.util.TelephonyUtil;
import org.junit.After;
@@ -52,7 +49,7 @@
*/
@SmallTest
public class EapFailureNotifierTest extends WifiBaseTest {
- @Mock Context mContext;
+ @Mock WifiContext mContext;
@Mock Resources mResources;
@Mock NotificationManager mNotificationManager;
@Mock FrameworkFacade mFrameworkFacade;
@@ -93,6 +90,7 @@
when(mResources.getString(eq(0), anyString())).thenReturn(null);
when(mResources.getString(eq(1), anyString())).thenReturn("Error Message");
when(mContext.createPackageContext(anyString(), eq(0))).thenReturn(mContext);
+ when(mContext.getWifiOverlayApkPkgName()).thenReturn("test.com.android.wifi.resources");
mEapFailureNotifier =
new EapFailureNotifier(mContext, mFrameworkFacade, mTelephonyUtil);
}
diff --git a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
index 0e63b51..a7e21c9 100644
--- a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -117,7 +117,7 @@
private SoftApInfo mTestSoftApInfo;
private SoftApCapability mTestSoftApCapability;
- @Mock Context mContext;
+ @Mock WifiContext mContext;
@Mock Resources mResources;
@Mock WifiNative mWifiNative;
@Mock WifiManager.SoftApCallback mCallback;
@@ -153,6 +153,7 @@
when(mContext.getResources()).thenReturn(mResources);
when(mContext.getSystemService(NotificationManager.class))
.thenReturn(mNotificationManager);
+ when(mContext.getWifiOverlayApkPkgName()).thenReturn("test.com.android.wifi.resources");
when(mResources.getInteger(R.integer.config_wifiFrameworkSoftApShutDownTimeoutMilliseconds))
.thenReturn((int) TEST_DEFAULT_SHUTDOWN_TIMEOUT_MILLS);
diff --git a/tests/wifitests/src/com/android/server/wifi/SoftApNotifierTest.java b/tests/wifitests/src/com/android/server/wifi/SoftApNotifierTest.java
index 9ff8934..3d4d239 100644
--- a/tests/wifitests/src/com/android/server/wifi/SoftApNotifierTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SoftApNotifierTest.java
@@ -45,7 +45,7 @@
public class SoftApNotifierTest extends WifiBaseTest {
private static final String TEST_SSID = "Test SSID";
- @Mock Context mContext;
+ @Mock WifiContext mContext;
@Mock Resources mResources;
@Mock NotificationManager mNotificationManager;
@Mock FrameworkFacade mFrameworkFacade;
@@ -61,8 +61,8 @@
when(mContext.getSystemService(NotificationManager.class))
.thenReturn(mNotificationManager);
when(mContext.getResources()).thenReturn(mResources);
- mSoftApNotifier =
- new SoftApNotifier(mContext, mFrameworkFacade);
+ when(mContext.getWifiOverlayApkPkgName()).thenReturn("test.com.android.wifi.resources");
+ mSoftApNotifier = new SoftApNotifier(mContext, mFrameworkFacade);
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
index 3abdb06..3a5ce52 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
@@ -23,6 +23,8 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.never;
@@ -35,6 +37,7 @@
import android.net.MacAddress;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApConfiguration.Builder;
+import android.net.wifi.WifiInfo;
import android.os.Build;
import android.os.Handler;
import android.os.test.TestLooper;
@@ -492,6 +495,21 @@
}
@Test
+ public void randomizeBssid_fallbackPathWhenMacCalculationFails() throws Exception {
+ mResources.setBoolean(R.bool.config_wifi_ap_mac_randomization_supported, true);
+ // Setup the MAC calculation to fail.
+ when(mMacAddressUtil.calculatePersistentMac(any(), any())).thenReturn(null);
+ SoftApConfiguration baseConfig = new SoftApConfiguration.Builder().build();
+
+ WifiApConfigStore store = createWifiApConfigStore();
+ SoftApConfiguration config = store.randomizeBssidIfUnset(mContext, baseConfig);
+
+ // Verify that some randomized MAC address is still generated
+ assertNotNull(config.getBssid());
+ assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS, config.getBssid().toString());
+ }
+
+ @Test
public void randomizeBssid_usesFactoryMacWhenRandomizationOff() throws Exception {
mResources.setBoolean(R.bool.config_wifi_ap_mac_randomization_supported, false);
SoftApConfiguration baseConfig = new SoftApConfiguration.Builder().build();
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
index 878d3f5..30c171f 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
@@ -54,135 +54,178 @@
public class WifiBackupRestoreTest extends WifiBaseTest {
private static final String WIFI_BACKUP_DATA_WITH_UNSUPPORTED_TAG =
- "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
- + "<WifiBackupData>"
- + "<int name=\"Version\" value=\"1\" />"
- + "<NetworkList>"
- + "<Network>"
- + "<WifiConfiguration>"
- + "<string name=\"ConfigKey\">"GoogleGuest-Legacy"NONE</string>"
- + "<string name=\"SSID\">"GoogleGuest-Legacy"</string>"
- + "<null name=\"BSSID\" />"
- + "<null name=\"PreSharedKey\" />"
- + "<null name=\"WEPKeys\" />"
- + "<int name=\"WEPTxKeyIndex\" value=\"0\" />"
- + "<boolean name=\"HiddenSSID\" value=\"false\" />"
- + "<boolean name=\"RequirePMF\" value=\"false\" />"
- + "<byte-array name=\"AllowedKeyMgmt\" num=\"1\">01</byte-array>"
- + "<byte-array name=\"AllowedProtocols\" num=\"1\">03</byte-array>"
- + "<byte-array name=\"AllowedAuthAlgos\" num=\"1\">01</byte-array>"
- + "<byte-array name=\"AllowedGroupCiphers\" num=\"1\">0f</byte-array>"
- + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"1\">06</byte-array>"
- + "<boolean name=\"Shared\" value=\"true\" />"
- + "<null name=\"SimSlot\" />"
- + "</WifiConfiguration>"
- + "<IpConfiguration>"
- + "<string name=\"IpAssignment\">DHCP</string>"
- + "<string name=\"ProxySettings\">NONE</string>"
- + "</IpConfiguration>"
- + "</Network>"
- + "</NetworkList>"
- + "</WifiBackupData>";
+ "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<WifiBackupData>\n"
+ + "<int name=\"Version\" value=\"1\" />\n"
+ + "<NetworkList>\n"
+ + "<Network>\n"
+ + "<WifiConfiguration>\n"
+ + "<string name=\"ConfigKey\">"" + WifiConfigurationTestUtil.TEST_SSID
+ + ""NONE</string>\n"
+ + "<string name=\"SSID\">"" + WifiConfigurationTestUtil.TEST_SSID
+ + ""</string>\n"
+ + "<null name=\"BSSID\" />\n"
+ + "<null name=\"PreSharedKey\" />\n"
+ + "<null name=\"WEPKeys\" />\n"
+ + "<int name=\"WEPTxKeyIndex\" value=\"0\" />\n"
+ + "<boolean name=\"HiddenSSID\" value=\"false\" />\n"
+ + "<boolean name=\"RequirePMF\" value=\"false\" />\n"
+ + "<byte-array name=\"AllowedKeyMgmt\" num=\"1\">01</byte-array>\n"
+ + "<byte-array name=\"AllowedProtocols\" num=\"1\">03</byte-array>\n"
+ + "<byte-array name=\"AllowedAuthAlgos\" num=\"1\">01</byte-array>\n"
+ + "<byte-array name=\"AllowedGroupCiphers\" num=\"1\">0f</byte-array>\n"
+ + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"1\">06</byte-array>\n"
+ + "<boolean name=\"Shared\" value=\"true\" />\n"
+ + "<null name=\"SimSlot\" />\n"
+ + "</WifiConfiguration>\n"
+ + "<IpConfiguration>\n"
+ + "<string name=\"IpAssignment\">DHCP</string>\n"
+ + "<string name=\"ProxySettings\">NONE</string>\n"
+ + "</IpConfiguration>\n"
+ + "</Network>\n"
+ + "</NetworkList>\n"
+ + "</WifiBackupData>\n";
// |AllowedKeyMgmt|, |AllowedProtocols|, |AllowedAuthAlgorithms|, |AllowedGroupCiphers| and
// |AllowedPairwiseCiphers| fields have invalid values in them.
// NOTE: The byte values are encoded in little endian
private static final String WIFI_BACKUP_DATA_WITH_UNSUPPORTED_VALUES_IN_BITSETS =
- "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
- + "<WifiBackupData>"
- + "<int name=\"Version\" value=\"1\" />"
- + "<NetworkList>"
- + "<Network>"
- + "<WifiConfiguration>"
- + "<string name=\"ConfigKey\">"GoogleGuest-Legacy"NONE</string>"
- + "<string name=\"SSID\">"GoogleGuest-Legacy"</string>"
- + "<null name=\"BSSID\" />"
- + "<null name=\"PreSharedKey\" />"
- + "<null name=\"WEPKeys\" />"
- + "<int name=\"WEPTxKeyIndex\" value=\"0\" />"
- + "<boolean name=\"HiddenSSID\" value=\"false\" />"
- + "<boolean name=\"RequirePMF\" value=\"false\" />"
+ "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<WifiBackupData>\n"
+ + "<int name=\"Version\" value=\"1\" />\n"
+ + "<NetworkList>\n"
+ + "<Network>\n"
+ + "<WifiConfiguration>\n"
+ + "<string name=\"ConfigKey\">"" + WifiConfigurationTestUtil.TEST_SSID
+ + ""NONE</string>\n"
+ + "<string name=\"SSID\">"" + WifiConfigurationTestUtil.TEST_SSID
+ + ""</string>\n"
+ + "<null name=\"BSSID\" />\n"
+ + "<null name=\"PreSharedKey\" />\n"
+ + "<null name=\"WEPKeys\" />\n"
+ + "<int name=\"WEPTxKeyIndex\" value=\"0\" />\n"
+ + "<boolean name=\"HiddenSSID\" value=\"false\" />\n"
+ + "<boolean name=\"RequirePMF\" value=\"false\" />\n"
// Valid Value: 01
- + "<byte-array name=\"AllowedKeyMgmt\" num=\"3\">010002</byte-array>"
+ + "<byte-array name=\"AllowedKeyMgmt\" num=\"3\">010002</byte-array>\n"
// Valid Value: 03
- + "<byte-array name=\"AllowedProtocols\" num=\"1\">13</byte-array>"
+ + "<byte-array name=\"AllowedProtocols\" num=\"1\">13</byte-array>\n"
// Valid Value: 01
- + "<byte-array name=\"AllowedAuthAlgos\" num=\"1\">11</byte-array>"
+ + "<byte-array name=\"AllowedAuthAlgos\" num=\"1\">11</byte-array>\n"
// Valid Value: 0f
- + "<byte-array name=\"AllowedGroupCiphers\" num=\"1\">8f</byte-array>"
+ + "<byte-array name=\"AllowedGroupCiphers\" num=\"1\">8f</byte-array>\n"
// Valid Value: 06
- + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"1\">26</byte-array>"
- + "<boolean name=\"Shared\" value=\"true\" />"
- + "<null name=\"SimSlot\" />"
- + "</WifiConfiguration>"
- + "<IpConfiguration>"
- + "<string name=\"IpAssignment\">DHCP</string>"
- + "<string name=\"ProxySettings\">NONE</string>"
- + "</IpConfiguration>"
- + "</Network>"
- + "</NetworkList>"
- + "</WifiBackupData>";
+ + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"1\">26</byte-array>\n"
+ + "<boolean name=\"Shared\" value=\"true\" />\n"
+ + "<null name=\"SimSlot\" />\n"
+ + "</WifiConfiguration>\n"
+ + "<IpConfiguration>\n"
+ + "<string name=\"IpAssignment\">DHCP</string>\n"
+ + "<string name=\"ProxySettings\">NONE</string>\n"
+ + "</IpConfiguration>\n"
+ + "</Network>\n"
+ + "</NetworkList>\n"
+ + "</WifiBackupData>\n";
private static final String WIFI_BACKUP_DATA_V1_0 =
- "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
- + "<WifiBackupData>"
- + "<float name=\"Version\" value=\"1.0\" />"
- + "<NetworkList>"
- + "<Network>"
- + "<WifiConfiguration>"
- + "<string name=\"ConfigKey\">"GoogleGuest-Legacy"NONE</string>"
- + "<string name=\"SSID\">"GoogleGuest-Legacy"</string>"
- + "<null name=\"BSSID\" />"
- + "<null name=\"PreSharedKey\" />"
- + "<null name=\"WEPKeys\" />"
- + "<int name=\"WEPTxKeyIndex\" value=\"0\" />"
- + "<boolean name=\"HiddenSSID\" value=\"false\" />"
- + "<boolean name=\"RequirePMF\" value=\"false\" />"
- + "<byte-array name=\"AllowedKeyMgmt\" num=\"1\">01</byte-array>"
- + "<byte-array name=\"AllowedProtocols\" num=\"1\">03</byte-array>"
- + "<byte-array name=\"AllowedAuthAlgos\" num=\"1\">01</byte-array>"
- + "<byte-array name=\"AllowedGroupCiphers\" num=\"1\">0f</byte-array>"
- + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"1\">06</byte-array>"
- + "<boolean name=\"Shared\" value=\"true\" />"
- + "</WifiConfiguration>"
- + "<IpConfiguration>"
- + "<string name=\"IpAssignment\">DHCP</string>"
- + "<string name=\"ProxySettings\">NONE</string>"
- + "</IpConfiguration>"
- + "</Network>"
- + "</NetworkList>"
- + "</WifiBackupData>";
+ "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<WifiBackupData>\n"
+ + "<float name=\"Version\" value=\"1.0\" />\n"
+ + "<NetworkList>\n"
+ + "<Network>\n"
+ + "<WifiConfiguration>\n"
+ + "<string name=\"ConfigKey\">"" + WifiConfigurationTestUtil.TEST_SSID
+ + ""NONE</string>\n"
+ + "<string name=\"SSID\">"" + WifiConfigurationTestUtil.TEST_SSID
+ + ""</string>\n"
+ + "<null name=\"BSSID\" />\n"
+ + "<null name=\"PreSharedKey\" />\n"
+ + "<null name=\"WEPKeys\" />\n"
+ + "<int name=\"WEPTxKeyIndex\" value=\"0\" />\n"
+ + "<boolean name=\"HiddenSSID\" value=\"false\" />\n"
+ + "<boolean name=\"RequirePMF\" value=\"false\" />\n"
+ + "<byte-array name=\"AllowedKeyMgmt\" num=\"1\">01</byte-array>\n"
+ + "<byte-array name=\"AllowedProtocols\" num=\"1\">03</byte-array>\n"
+ + "<byte-array name=\"AllowedAuthAlgos\" num=\"1\">01</byte-array>\n"
+ + "<byte-array name=\"AllowedGroupCiphers\" num=\"1\">0f</byte-array>\n"
+ + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"1\">06</byte-array>\n"
+ + "<boolean name=\"Shared\" value=\"true\" />\n"
+ + "</WifiConfiguration>\n"
+ + "<IpConfiguration>\n"
+ + "<string name=\"IpAssignment\">DHCP</string>\n"
+ + "<string name=\"ProxySettings\">NONE</string>\n"
+ + "</IpConfiguration>\n"
+ + "</Network>\n"
+ + "</NetworkList>\n"
+ + "</WifiBackupData>\n";
private static final String WIFI_BACKUP_DATA_V1_1 =
- "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
- + "<WifiBackupData>"
- + "<float name=\"Version\" value=\"1.1\" />"
- + "<NetworkList>"
- + "<Network>"
- + "<WifiConfiguration>"
- + "<string name=\"ConfigKey\">"GoogleGuest-Legacy"NONE</string>"
- + "<string name=\"SSID\">"GoogleGuest-Legacy"</string>"
- + "<null name=\"BSSID\" />"
- + "<null name=\"PreSharedKey\" />"
- + "<null name=\"WEPKeys\" />"
- + "<int name=\"WEPTxKeyIndex\" value=\"0\" />"
- + "<boolean name=\"HiddenSSID\" value=\"false\" />"
- + "<boolean name=\"RequirePMF\" value=\"false\" />"
- + "<byte-array name=\"AllowedKeyMgmt\" num=\"1\">01</byte-array>"
- + "<byte-array name=\"AllowedProtocols\" num=\"1\">03</byte-array>"
- + "<byte-array name=\"AllowedAuthAlgos\" num=\"1\">01</byte-array>"
- + "<byte-array name=\"AllowedGroupCiphers\" num=\"1\">0f</byte-array>"
- + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"1\">06</byte-array>"
- + "<boolean name=\"Shared\" value=\"true\" />"
- + "<int name=\"MeteredOverride\" value=\"1\" />"
- + "</WifiConfiguration>"
- + "<IpConfiguration>"
- + "<string name=\"IpAssignment\">DHCP</string>"
- + "<string name=\"ProxySettings\">NONE</string>"
- + "</IpConfiguration>"
- + "</Network>"
- + "</NetworkList>"
- + "</WifiBackupData>";
+ "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<WifiBackupData>\n"
+ + "<float name=\"Version\" value=\"1.1\" />\n"
+ + "<NetworkList>\n"
+ + "<Network>\n"
+ + "<WifiConfiguration>\n"
+ + "<string name=\"ConfigKey\">"" + WifiConfigurationTestUtil.TEST_SSID
+ + ""NONE</string>\n"
+ + "<string name=\"SSID\">"" + WifiConfigurationTestUtil.TEST_SSID
+ + ""</string>\n"
+ + "<null name=\"BSSID\" />\n"
+ + "<null name=\"PreSharedKey\" />\n"
+ + "<null name=\"WEPKeys\" />\n"
+ + "<int name=\"WEPTxKeyIndex\" value=\"0\" />\n"
+ + "<boolean name=\"HiddenSSID\" value=\"false\" />\n"
+ + "<boolean name=\"RequirePMF\" value=\"false\" />\n"
+ + "<byte-array name=\"AllowedKeyMgmt\" num=\"1\">01</byte-array>\n"
+ + "<byte-array name=\"AllowedProtocols\" num=\"1\">03</byte-array>\n"
+ + "<byte-array name=\"AllowedAuthAlgos\" num=\"1\">01</byte-array>\n"
+ + "<byte-array name=\"AllowedGroupCiphers\" num=\"1\">0f</byte-array>\n"
+ + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"1\">06</byte-array>\n"
+ + "<boolean name=\"Shared\" value=\"true\" />\n"
+ + "<int name=\"MeteredOverride\" value=\"1\" />\n"
+ + "</WifiConfiguration>\n"
+ + "<IpConfiguration>\n"
+ + "<string name=\"IpAssignment\">DHCP</string>\n"
+ + "<string name=\"ProxySettings\">NONE</string>\n"
+ + "</IpConfiguration>\n"
+ + "</Network>\n"
+ + "</NetworkList>\n"
+ + "</WifiBackupData>\n";
+
+ private static final String WIFI_BACKUP_DATA_V1_2 =
+ "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<WifiBackupData>\n"
+ + "<float name=\"Version\" value=\"1.2\" />\n"
+ + "<NetworkList>\n"
+ + "<Network>\n"
+ + "<WifiConfiguration>\n"
+ + "<string name=\"ConfigKey\">"" + WifiConfigurationTestUtil.TEST_SSID
+ + ""NONE</string>\n"
+ + "<string name=\"SSID\">"" + WifiConfigurationTestUtil.TEST_SSID
+ + ""</string>\n"
+ + "<null name=\"PreSharedKey\" />\n"
+ + "<null name=\"WEPKeys\" />\n"
+ + "<int name=\"WEPTxKeyIndex\" value=\"0\" />\n"
+ + "<boolean name=\"HiddenSSID\" value=\"false\" />\n"
+ + "<boolean name=\"RequirePMF\" value=\"false\" />\n"
+ + "<byte-array name=\"AllowedKeyMgmt\" num=\"1\">01</byte-array>\n"
+ + "<byte-array name=\"AllowedProtocols\" num=\"1\">03</byte-array>\n"
+ + "<byte-array name=\"AllowedAuthAlgos\" num=\"1\">01</byte-array>\n"
+ + "<byte-array name=\"AllowedGroupCiphers\" num=\"1\">0f</byte-array>\n"
+ + "<byte-array name=\"AllowedPairwiseCiphers\" num=\"1\">06</byte-array>\n"
+ + "<byte-array name=\"AllowedGroupMgmtCiphers\" num=\"0\"></byte-array>\n"
+ + "<byte-array name=\"AllowedSuiteBCiphers\" num=\"0\"></byte-array>\n"
+ + "<boolean name=\"Shared\" value=\"true\" />\n"
+ + "<boolean name=\"AutoJoinEnabled\" value=\"false\" />\n"
+ + "<int name=\"MeteredOverride\" value=\"1\" />\n"
+ + "</WifiConfiguration>\n"
+ + "<IpConfiguration>\n"
+ + "<string name=\"IpAssignment\">DHCP</string>\n"
+ + "<string name=\"ProxySettings\">NONE</string>\n"
+ + "</IpConfiguration>\n"
+ + "</Network>\n"
+ + "</NetworkList>\n"
+ + "</WifiBackupData>\n";
@Mock WifiPermissionsUtil mWifiPermissionsUtil;
private WifiBackupRestore mWifiBackupRestore;
@@ -334,7 +377,7 @@
*/
private static WifiConfiguration createNetworkForConfigurationWithUnsupportedTag() {
final WifiConfiguration config = new WifiConfiguration();
- config.SSID = "\"GoogleGuest-Legacy\"";
+ config.SSID = "\"" + WifiConfigurationTestUtil.TEST_SSID + "\"";
config.wepTxKeyIndex = 0;
config.hiddenSSID = false;
config.requirePmf = false;
@@ -387,7 +430,7 @@
private static WifiConfiguration
createNetworkForConfigurationWithUnsupportedValuesInBitsetsInRestore() {
final WifiConfiguration config = new WifiConfiguration();
- config.SSID = "\"GoogleGuest-Legacy\"";
+ config.SSID = "\"" + WifiConfigurationTestUtil.TEST_SSID + "\"";
config.wepTxKeyIndex = 0;
config.hiddenSSID = false;
config.requirePmf = false;
@@ -954,9 +997,43 @@
mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
configurations, retrievedConfigurations);
+ }
- // No valid data to check in dump.
- mCheckDump = false;
+ /**
+ * Verify that restoring of configuration from a 1.1 version backup data.
+ */
+ @Test
+ public void testRestoreFromV1_1BackupData() {
+ List<WifiConfiguration> configurations = new ArrayList<>();
+ configurations.add(createNetworkForConfigurationWithV1_1Data());
+
+ byte[] backupData = WIFI_BACKUP_DATA_V1_1.getBytes();
+ List<WifiConfiguration> retrievedConfigurations =
+ mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+ WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+ configurations, retrievedConfigurations);
+ }
+
+ /**
+ * Verify that restoring of configuration from a 1.2 version backup data.
+ */
+ @Test
+ public void testRestoreFromV1_2BackupData() {
+ List<WifiConfiguration> configurations = new ArrayList<>();
+ configurations.add(createNetworkForConfigurationWithV1_1Data());
+
+ byte[] backupData = WIFI_BACKUP_DATA_V1_2.getBytes();
+ List<WifiConfiguration> retrievedConfigurations =
+ mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+ WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+ configurations, retrievedConfigurations);
+
+ // Also, assert in the reverse direction to ensure the serialization logic matches.
+ // Note: This will stop working when we bump up the version. Then we'll need to copy
+ // the below assert to the test for the latest version.
+ assertEquals(WIFI_BACKUP_DATA_V1_2,
+ new String(mWifiBackupRestore.retrieveBackupDataFromConfigurations(
+ retrievedConfigurations)));
}
/**
@@ -965,7 +1042,7 @@
*/
private static WifiConfiguration createNetworkForConfigurationWithV1_0Data() {
final WifiConfiguration config = new WifiConfiguration();
- config.SSID = "\"GoogleGuest-Legacy\"";
+ config.SSID = "\"" + WifiConfigurationTestUtil.TEST_SSID + "\"";
config.wepTxKeyIndex = 0;
config.hiddenSSID = false;
config.requirePmf = false;
@@ -990,34 +1067,24 @@
}
/**
- * Verify that restoring of configuration from a 1.1 version backup data.
- */
- @Test
- public void testRestoreFromV1_1BackupData() {
- List<WifiConfiguration> configurations = new ArrayList<>();
- configurations.add(createNetworkForConfigurationWithV1_1Data());
-
- byte[] backupData = WIFI_BACKUP_DATA_V1_1.getBytes();
- List<WifiConfiguration> retrievedConfigurations =
- mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
- WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
- configurations, retrievedConfigurations);
-
- // No valid data to check in dump.
- mCheckDump = false;
- }
-
- /**
* Creates correct WiFiConfiguration that should be parsed out of
* {@link #WIFI_BACKUP_DATA_V1_1} configuration which contains 1.1 version backup.
*/
private static WifiConfiguration createNetworkForConfigurationWithV1_1Data() {
final WifiConfiguration config = createNetworkForConfigurationWithV1_0Data();
config.meteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED;
-
return config;
}
+ /**
+ * Creates correct WiFiConfiguration that should be parsed out of
+ * {@link #WIFI_BACKUP_DATA_V1_1} configuration which contains 1.2 version backup.
+ */
+ private static WifiConfiguration createNetworkForConfigurationWithV1_2Data() {
+ final WifiConfiguration config = createNetworkForConfigurationWithV1_1Data();
+ config.allowAutojoin = false;
+ return config;
+ }
/**
* Helper method to write a list of networks in wpa_supplicant.conf format to the output stream.
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index 1147dd9..a892831 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -71,6 +71,7 @@
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -141,7 +142,7 @@
@Mock private WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager;
@Mock private WifiScoreCard mWifiScoreCard;
@Mock private PerNetwork mPerNetwork;
- @Mock private LruConnectionTracker mLruConnectionTracker;
+ private LruConnectionTracker mLruConnectionTracker;
private MockResources mResources;
private InOrder mContextConfigStoreMockOrder;
@@ -175,6 +176,7 @@
R.integer.config_wifi_framework_associated_partial_scan_max_num_active_channels,
TEST_MAX_NUM_ACTIVE_CHANNELS_FOR_PARTIAL_SCAN);
mResources.setBoolean(R.bool.config_wifi_connected_mac_randomization_supported, true);
+ mResources.setInteger(R.integer.config_wifiMaxPnoSsidCount, 16);
when(mContext.getResources()).thenReturn(mResources);
// Setup UserManager profiles for the default user.
@@ -225,6 +227,7 @@
mTelephonyUtil = new TelephonyUtil(mTelephonyManager, mSubscriptionManager,
mock(FrameworkFacade.class), mock(Context.class), mock(Handler.class));
+ mLruConnectionTracker = new LruConnectionTracker(100, mContext);
createWifiConfigManager();
mWifiConfigManager.addOnNetworkUpdateListener(mWcmListener);
// static mocking
@@ -3992,25 +3995,20 @@
verifyAddNetworkToWifiConfigManager(network1);
verifyAddNetworkToWifiConfigManager(network2);
verifyAddNetworkToWifiConfigManager(network3);
+ mWifiConfigManager.updateNetworkAfterConnect(network3.networkId);
- // Now set scan results in 2 of them to set the corresponding
+ // Now set scan results of network2 to set the corresponding
// {@link NetworkSelectionStatus#mSeenInLastQualifiedNetworkSelection} field.
- assertTrue(mWifiConfigManager.setNetworkCandidateScanResult(
- network1.networkId, createScanDetailForNetwork(network1).getScanResult(), 54));
- assertTrue(mWifiConfigManager.setNetworkCandidateScanResult(
- network3.networkId, createScanDetailForNetwork(network3).getScanResult(), 54));
-
- // Now increment |network3|'s association count. This should ensure that this network
- // is preferred over |network1|.
- assertTrue(mWifiConfigManager.updateNetworkAfterConnect(network3.networkId));
+ assertTrue(mWifiConfigManager.setNetworkCandidateScanResult(network2.networkId,
+ createScanDetailForNetwork(network2).getScanResult(), 54));
// Retrieve the hidden network list & verify the order of the networks returned.
List<WifiScanner.ScanSettings.HiddenNetwork> hiddenNetworks =
mWifiConfigManager.retrieveHiddenNetworkList();
assertEquals(3, hiddenNetworks.size());
assertEquals(network3.SSID, hiddenNetworks.get(0).ssid);
- assertEquals(network1.SSID, hiddenNetworks.get(1).ssid);
- assertEquals(network2.SSID, hiddenNetworks.get(2).ssid);
+ assertEquals(network2.SSID, hiddenNetworks.get(1).ssid);
+ assertEquals(network1.SSID, hiddenNetworks.get(2).ssid);
}
/**
@@ -5316,10 +5314,6 @@
// Verify if the config store write was triggered without this new configuration.
verifyNetworkNotInConfigStoreData(configuration);
verify(mBssidBlocklistMonitor, atLeastOnce()).handleNetworkRemoved(configuration.SSID);
- ArgumentCaptor<WifiConfiguration> captor = ArgumentCaptor.forClass(WifiConfiguration.class);
- verify(mLruConnectionTracker).removeNetwork(captor.capture());
- assertEquals(configuration.networkId, captor.getValue().networkId);
- reset(mLruConnectionTracker);
}
/**
@@ -5515,9 +5509,7 @@
WifiConfiguration retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(networkId);
assertTrue("hasEverConnected expected to be true after connection.",
retrievedNetwork.getNetworkSelectionStatus().hasEverConnected());
- ArgumentCaptor<WifiConfiguration> captor = ArgumentCaptor.forClass(WifiConfiguration.class);
- verify(mLruConnectionTracker).addNetwork(captor.capture());
- assertEquals(networkId, captor.getValue().networkId);
+ assertEquals(0, mLruConnectionTracker.getAgeIndexOfNetwork(retrievedNetwork));
}
/**
@@ -5652,8 +5644,7 @@
verifyAddNetworkToWifiConfigManager(testNetwork1);
WifiConfiguration testNetwork2 = WifiConfigurationTestUtil.createOpenNetwork();
verifyAddNetworkToWifiConfigManager(testNetwork2);
- when(mLruConnectionTracker.isMostRecentlyConnected(any()))
- .thenReturn(false).thenReturn(true);
+ mWifiConfigManager.updateNetworkAfterConnect(testNetwork2.networkId);
mWifiConfigManager.saveToStore(true);
Pair<List<WifiConfiguration>, List<WifiConfiguration>> networkStoreData =
captureWriteNetworksListStoreData();
@@ -5661,4 +5652,39 @@
assertFalse(sharedNetwork.get(0).isMostRecentlyConnected);
assertTrue(sharedNetwork.get(1).isMostRecentlyConnected);
}
+
+ /**
+ * Verify scan comparator gives the most recently connected network highest priority
+ */
+ @Test
+ public void testScanComparator() {
+ WifiConfiguration network1 = WifiConfigurationTestUtil.createOpenNetwork();
+ verifyAddNetworkToWifiConfigManager(network1);
+ WifiConfiguration network2 = WifiConfigurationTestUtil.createOpenNetwork();
+ verifyAddNetworkToWifiConfigManager(network2);
+ WifiConfiguration network3 = WifiConfigurationTestUtil.createOpenNetwork();
+ verifyAddNetworkToWifiConfigManager(network3);
+ WifiConfiguration network4 = WifiConfigurationTestUtil.createOpenNetwork();
+ verifyAddNetworkToWifiConfigManager(network4);
+
+ // Connect two network in order, network3 --> network2
+ verifyUpdateNetworkAfterConnectHasEverConnectedTrue(network3.networkId);
+ verifyUpdateNetworkAfterConnectHasEverConnectedTrue(network2.networkId);
+ // Set network4 {@link NetworkSelectionStatus#mSeenInLastQualifiedNetworkSelection} to true.
+ assertTrue(mWifiConfigManager.setNetworkCandidateScanResult(network4.networkId,
+ createScanDetailForNetwork(network4).getScanResult(), 54));
+ List<WifiConfiguration> networkList = mWifiConfigManager.getConfiguredNetworks();
+ // Expected order should be based on connection order and last qualified selection.
+ Collections.sort(networkList, mWifiConfigManager.getScanListComparator());
+ assertEquals(network2.SSID, networkList.get(0).SSID);
+ assertEquals(network3.SSID, networkList.get(1).SSID);
+ assertEquals(network4.SSID, networkList.get(2).SSID);
+ assertEquals(network1.SSID, networkList.get(3).SSID);
+ // Remove network to check the age index changes.
+ mWifiConfigManager.removeNetwork(network3.networkId, TEST_CREATOR_UID, TEST_CREATOR_NAME);
+ assertEquals(Integer.MAX_VALUE, mLruConnectionTracker.getAgeIndexOfNetwork(network3));
+ assertEquals(0, mLruConnectionTracker.getAgeIndexOfNetwork(network2));
+ mWifiConfigManager.removeNetwork(network2.networkId, TEST_CREATOR_UID, TEST_CREATOR_NAME);
+ assertEquals(Integer.MAX_VALUE, mLruConnectionTracker.getAgeIndexOfNetwork(network2));
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
index 028bf02..ede5c8b 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
@@ -54,6 +54,7 @@
import androidx.test.filters.SmallTest;
import com.android.server.wifi.hotspot2.PasspointManager;
+import com.android.server.wifi.util.LruConnectionTracker;
import com.android.server.wifi.util.ScanResultUtil;
import com.android.wifi.resources.R;
@@ -73,6 +74,7 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -127,6 +129,10 @@
mMinPacketRateActiveTraffic = mResources.getInteger(
R.integer.config_wifiFrameworkMinPacketPerSecondActiveTraffic);
when(mWifiLastResortWatchdog.shouldIgnoreBssidUpdate(anyString())).thenReturn(false);
+ mLruConnectionTracker = new LruConnectionTracker(100, mContext);
+ Comparator<WifiConfiguration> comparator =
+ Comparator.comparingInt(mLruConnectionTracker::getAgeIndexOfNetwork);
+ when(mWifiConfigManager.getScanListComparator()).thenReturn(comparator);
}
private void setUpResources(MockResources resources) {
@@ -175,6 +181,7 @@
private WifiConfigManager mWifiConfigManager;
private WifiInfo mWifiInfo;
private LocalLog mLocalLog;
+ private LruConnectionTracker mLruConnectionTracker;
@Mock private WifiInjector mWifiInjector;
@Mock private NetworkScoreManager mNetworkScoreManager;
@Mock private Clock mClock;
@@ -2910,6 +2917,9 @@
networkList.add(network1);
networkList.add(network2);
networkList.add(network3);
+ mLruConnectionTracker.addNetwork(network3);
+ mLruConnectionTracker.addNetwork(network2);
+ mLruConnectionTracker.addNetwork(network1);
when(mWifiConfigManager.getSavedNetworks(anyInt())).thenReturn(networkList);
// Retrieve the Pno network list & verify.
List<WifiScanner.PnoSettings.PnoNetwork> pnoNetworks =
@@ -2950,8 +2960,9 @@
List<WifiConfiguration> networkList = new ArrayList<>();
networkList.add(network1);
networkList.add(network2);
+ mLruConnectionTracker.addNetwork(network2);
+ mLruConnectionTracker.addNetwork(network1);
when(mWifiConfigManager.getSavedNetworks(anyInt())).thenReturn(networkList);
-
// Retrieve the Pno network list and verify.
// Frequencies should be empty since no scan results have been received yet.
List<WifiScanner.PnoSettings.PnoNetwork> pnoNetworks =
@@ -3006,37 +3017,17 @@
WifiConfiguration network1 = WifiConfigurationTestUtil.createEapNetwork();
WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
WifiConfiguration network3 = WifiConfigurationTestUtil.createOpenHiddenNetwork();
+ mLruConnectionTracker.addNetwork(network1);
+ mLruConnectionTracker.addNetwork(network2);
+ mLruConnectionTracker.addNetwork(network3);
List<WifiConfiguration> networkList = new ArrayList<>();
networkList.add(network1);
networkList.add(network2);
networkList.add(network3);
when(mWifiConfigManager.getSavedNetworks(anyInt())).thenReturn(networkList);
- // Set up network as:
- // Network2 has the highest association number.
- // Network3 is most recently connected.
- // Network1 the second for both association number and most recently.
- long firstConnectionTimeMillis = 45677;
- long secondConnectionTimeMillis = firstConnectionTimeMillis + 45;
- network1.numAssociation = 2;
- network2.numAssociation = 3;
- network3.numAssociation = 1;
- network1.lastConnected = firstConnectionTimeMillis;
- network3.lastConnected = secondConnectionTimeMillis;
- //When config_wifiPnoRecencySortingEnabled is false, will prefer most connected network.
- mResources.setBoolean(R.bool.config_wifiPnoRecencySortingEnabled, false);
List<WifiScanner.PnoSettings.PnoNetwork> pnoNetworks =
mWifiConnectivityManager.retrievePnoNetworkList();
assertEquals(3, pnoNetworks.size());
- assertEquals(network2.SSID, pnoNetworks.get(0).ssid);
- assertEquals(network1.SSID, pnoNetworks.get(1).ssid);
- assertEquals(network3.SSID, pnoNetworks.get(2).ssid);
-
- //When config_wifiPnoRecencySortingEnabled is true, after prefer most connected network.
- //The most recently connected network will move the first.
- mResources.setBoolean(R.bool.config_wifiPnoRecencySortingEnabled, true);
- pnoNetworks =
- mWifiConnectivityManager.retrievePnoNetworkList();
- assertEquals(3, pnoNetworks.size());
assertEquals(network3.SSID, pnoNetworks.get(0).ssid);
assertEquals(network2.SSID, pnoNetworks.get(1).ssid);
assertEquals(network1.SSID, pnoNetworks.get(2).ssid);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java b/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
index bb8c74d..cfe1ee8 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
@@ -204,17 +204,21 @@
}
/**
- * Verify throughtput when Rx link speed is unavailable
+ * Verify throughtput when Rx link speed is unavailable.
+ * Also verify the logging of channel utilization and throughput.
*/
@Test
public void verifyThroughputNoRxLinkSpeed() throws Exception {
mWifiDataStall.checkDataStallAndThroughputSufficiency(null, mNewLlStats, mWifiInfo);
+ verify(mWifiMetrics).incrementChannelUtilizationCount(10, 5850);
+ verify(mWifiMetrics).incrementThroughputKbpsCount(50_000, 150_000, 5850);
assertEquals(50_000, mWifiDataStall.getTxThroughputKbps());
assertEquals(150_000, mWifiDataStall.getRxThroughputKbps());
when(mWifiInfo.getRxLinkSpeedMbps()).thenReturn(-1);
mWifiDataStall.checkDataStallAndThroughputSufficiency(mOldLlStats, mNewLlStats, mWifiInfo);
assertEquals(960, mWifiDataStall.getTxThroughputKbps());
assertEquals(-1, mWifiDataStall.getRxThroughputKbps());
+ verify(mWifiMetrics).incrementThroughputKbpsCount(960, -1, 5850);
}
/**
@@ -226,6 +230,7 @@
assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN, mWifiDataStall
.checkDataStallAndThroughputSufficiency(mOldLlStats, mNewLlStats, mWifiInfo));
+ verify(mWifiMetrics).incrementThroughputKbpsCount(960, 9609, 5850);
verifyUpdateWifiIsUnusableLinkLayerStats();
when(mClock.getElapsedSinceBootMillis()).thenReturn(
10L + DeviceConfigFacade.DEFAULT_DATA_STALL_DURATION_MS);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiInjectorTest.java b/tests/wifitests/src/com/android/server/wifi/WifiInjectorTest.java
index 2c73d09..6af10d0 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiInjectorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiInjectorTest.java
@@ -16,10 +16,6 @@
package com.android.server.wifi;
-import static org.mockito.Mockito.*;
-
-import android.content.Context;
-
import androidx.test.filters.SmallTest;
import org.junit.Before;
@@ -31,7 +27,7 @@
@SmallTest
public class WifiInjectorTest extends WifiBaseTest {
- @Mock private Context mContext;
+ @Mock private WifiContext mContext;
private WifiInjector mInjector;
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
index 315a17b..841a132 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -4564,4 +4564,82 @@
mDecodedProto.softApConfigLimitationMetrics.maxClientSettingWhenReachHistogram);
}
+ /**
+ * Test the logging of channel utilization
+ */
+ @Test
+ public void testChannelUtilization() throws Exception {
+ mWifiMetrics.incrementChannelUtilizationCount(180, 2412);
+ mWifiMetrics.incrementChannelUtilizationCount(150, 2412);
+ mWifiMetrics.incrementChannelUtilizationCount(230, 2412);
+ mWifiMetrics.incrementChannelUtilizationCount(20, 5510);
+ mWifiMetrics.incrementChannelUtilizationCount(50, 5510);
+
+ dumpProtoAndDeserialize();
+
+ HistogramBucketInt32[] expected2GHistogram = {
+ buildHistogramBucketInt32(150, 175, 1),
+ buildHistogramBucketInt32(175, 200, 1),
+ buildHistogramBucketInt32(225, Integer.MAX_VALUE, 1),
+ };
+
+ HistogramBucketInt32[] expectedAbove2GHistogram = {
+ buildHistogramBucketInt32(Integer.MIN_VALUE, 25, 1),
+ buildHistogramBucketInt32(50, 75, 1),
+ };
+
+ assertHistogramBucketsEqual(expected2GHistogram,
+ mDecodedProto.channelUtilizationHistogram.utilization2G);
+ assertHistogramBucketsEqual(expectedAbove2GHistogram,
+ mDecodedProto.channelUtilizationHistogram.utilizationAbove2G);
+ }
+
+ /**
+ * Test the logging of Tx and Rx throughput
+ */
+ @Test
+ public void testThroughput() throws Exception {
+ mWifiMetrics.incrementThroughputKbpsCount(500, 800, 2412);
+ mWifiMetrics.incrementThroughputKbpsCount(5_000, 4_000, 2412);
+ mWifiMetrics.incrementThroughputKbpsCount(54_000, 48_000, 2412);
+ mWifiMetrics.incrementThroughputKbpsCount(50_000, 49_000, 5510);
+ mWifiMetrics.incrementThroughputKbpsCount(801_000, 790_000, 5510);
+ mWifiMetrics.incrementThroughputKbpsCount(1100_000, 1200_000, 5510);
+ mWifiMetrics.incrementThroughputKbpsCount(1599_000, 1800_000, 6120);
+ dumpProtoAndDeserialize();
+
+ HistogramBucketInt32[] expectedTx2GHistogramMbps = {
+ buildHistogramBucketInt32(Integer.MIN_VALUE, 1, 1),
+ buildHistogramBucketInt32(5, 10, 1),
+ buildHistogramBucketInt32(50, 100, 1),
+ };
+
+ HistogramBucketInt32[] expectedRx2GHistogramMbps = {
+ buildHistogramBucketInt32(Integer.MIN_VALUE, 1, 1),
+ buildHistogramBucketInt32(1, 5, 1),
+ buildHistogramBucketInt32(25, 50, 1),
+ };
+
+ HistogramBucketInt32[] expectedTxAbove2GHistogramMbps = {
+ buildHistogramBucketInt32(50, 100, 1),
+ buildHistogramBucketInt32(800, 1200, 2),
+ buildHistogramBucketInt32(1200, 1600, 1),
+ };
+
+ HistogramBucketInt32[] expectedRxAbove2GHistogramMbps = {
+ buildHistogramBucketInt32(25, 50, 1),
+ buildHistogramBucketInt32(600, 800, 1),
+ buildHistogramBucketInt32(1200, 1600, 1),
+ buildHistogramBucketInt32(1600, Integer.MAX_VALUE, 1),
+ };
+
+ assertHistogramBucketsEqual(expectedTx2GHistogramMbps,
+ mDecodedProto.throughputMbpsHistogram.tx2G);
+ assertHistogramBucketsEqual(expectedTxAbove2GHistogramMbps,
+ mDecodedProto.throughputMbpsHistogram.txAbove2G);
+ assertHistogramBucketsEqual(expectedRx2GHistogramMbps,
+ mDecodedProto.throughputMbpsHistogram.rx2G);
+ assertHistogramBucketsEqual(expectedRxAbove2GHistogramMbps,
+ mDecodedProto.throughputMbpsHistogram.rxAbove2G);
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
index f26ceb6..bb090ca 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
@@ -124,7 +124,7 @@
private static final int TEST_NETWORK_ID = 110;
private static final int TEST_CARRIER_ID = 1911;
- private @Mock Context mContext;
+ private @Mock WifiContext mContext;
private @Mock Resources mResources;
private @Mock AppOpsManager mAppOpsManager;
private @Mock NotificationManager mNotificationManger;
@@ -210,6 +210,7 @@
when(mContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager);
when(mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.thenReturn(mock(LayoutInflater.class));
+ when(mContext.getWifiOverlayApkPkgName()).thenReturn("test.com.android.wifi.resources");
when(mActivityManager.isLowRamDevice()).thenReturn(false);
when(mActivityManager.getPackageImportance(any())).thenReturn(
IMPORTANCE_FOREGROUND_SERVICE);
@@ -649,6 +650,24 @@
}
/**
+ * Verify add or remove suggestion list with null object will result error code.
+ */
+ @Test
+ public void testAddRemoveNetworkSuggestionWithNullObject() {
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID,
+ mWifiNetworkSuggestionsManager.add(Collections.singletonList(null),
+ TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE));
+ WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion(
+ WifiConfigurationTestUtil.createOpenNetwork(), null, false, false, true, true);
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
+ mWifiNetworkSuggestionsManager.add(Collections.singletonList(networkSuggestion),
+ TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE));
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID,
+ mWifiNetworkSuggestionsManager.remove(Collections.singletonList(null),
+ TEST_UID_1, TEST_PACKAGE_1));
+ }
+
+ /**
* Verify a successful lookup of a single network suggestion matching the provided scan detail.
*/
@Test
@@ -3292,6 +3311,7 @@
List<ScanResult> allSrList = new ArrayList<>() {{
add(passpointScanResult);
add(nonPasspointScanResult);
+ add(null);
}};
when(mPasspointManager.getMatchingScanResults(eq(mockPasspoint), eq(allSrList)))
.thenReturn(ppSrList);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index 8286f1d..ca8c9db 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -174,6 +174,7 @@
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -225,6 +226,12 @@
private static final int TEST_AP_FREQUENCY = 2412;
private static final int TEST_AP_BANDWIDTH = SoftApInfo.CHANNEL_WIDTH_20MHZ;
private static final int NETWORK_CALLBACK_ID = 1100;
+ private static final String TEST_CAP = "[RSN-PSK-CCMP]";
+ private static final String TEST_SSID = "Sid's Place";
+ private static final String TEST_SSID_WITH_QUOTES = "\"" + TEST_SSID + "\"";
+ private static final String TEST_BSSID = "01:02:03:04:05:06";
+ private static final String TEST_PACKAGE = "package";
+ private static final int TEST_NETWORK_ID = 567;
private SoftApInfo mTestSoftApInfo;
private AsyncChannel mAsyncChannel;
@@ -1558,12 +1565,6 @@
verify(mScanRequestProxy).startScan(Binder.getCallingUid(), SCAN_PACKAGE_NAME);
}
- static final String TEST_SSID = "Sid's Place";
- static final String TEST_SSID_WITH_QUOTES = "\"" + TEST_SSID + "\"";
- static final String TEST_BSSID = "01:02:03:04:05:06";
- static final String TEST_PACKAGE = "package";
- static final int TEST_NETWORK_ID = 567;
-
private void setupForGetConnectionInfo() {
WifiInfo wifiInfo = new WifiInfo();
wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID));
@@ -3138,9 +3139,9 @@
}
/**
- * Verify that the call to getAllMatchingFqdnsForScanResults is not redirected to specific API
- * syncGetAllMatchingFqdnsForScanResults when the caller doesn't have NETWORK_SETTINGS
- * permissions and NETWORK_SETUP_WIZARD.
+ * Verify that the call to getAllMatchingPasspointProfilesForScanResults is not redirected to
+ * specific API getAllMatchingPasspointProfilesForScanResults when the caller doesn't have
+ * NETWORK_SETTINGS permissions and NETWORK_SETUP_WIZARD.
*/
@Test(expected = SecurityException.class)
public void testGetAllMatchingPasspointProfilesForScanResultsWithoutPermissions() {
@@ -3148,6 +3149,34 @@
}
/**
+ * Verify that the call to getAllMatchingPasspointProfilesForScanResults is redirected to
+ * specific API getAllMatchingPasspointProfilesForScanResults when the caller have
+ * NETWORK_SETTINGS permissions and NETWORK_SETUP_WIZARD.
+ */
+ @Test
+ public void testGetAllMatchingPasspointProfilesForScanResultsWithPermissions() {
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ mWifiServiceImpl.getAllMatchingPasspointProfilesForScanResults(createScanResultList());
+ mLooper.dispatchAll();
+ verify(mPasspointManager).getAllMatchingPasspointProfilesForScanResults(any());
+ }
+
+ /**
+ * Verify that the call to getAllMatchingPasspointProfilesForScanResults is not redirected to
+ * specific API getAllMatchingPasspointProfilesForScanResults when the caller provider invalid
+ * ScanResult.
+ */
+ @Test
+ public void testGetAllMatchingPasspointProfilesForScanResultsWithInvalidScanResult() {
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ mWifiServiceImpl.getAllMatchingPasspointProfilesForScanResults(new ArrayList<>());
+ mLooper.dispatchAll();
+ verify(mPasspointManager, never()).getAllMatchingPasspointProfilesForScanResults(any());
+ }
+
+ /**
* Verify that the call to getWifiConfigsForPasspointProfiles is not redirected to specific API
* syncGetWifiConfigsForPasspointProfiles when the caller doesn't have NETWORK_SETTINGS
* permissions and NETWORK_SETUP_WIZARD.
@@ -3168,6 +3197,33 @@
}
/**
+ * Verify that the call to getMatchingOsuProviders is redirected to specific API
+ * syncGetMatchingOsuProviders when the caller have NETWORK_SETTINGS
+ * permissions and NETWORK_SETUP_WIZARD.
+ */
+ @Test
+ public void testGetMatchingOsuProvidersWithPermissions() {
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ mWifiServiceImpl.getMatchingOsuProviders(createScanResultList());
+ mLooper.dispatchAll();
+ verify(mPasspointManager).getMatchingOsuProviders(any());
+ }
+
+ /**
+ * Verify that the call to getMatchingOsuProviders is not redirected to specific API
+ * syncGetMatchingOsuProviders when the caller provider invalid ScanResult
+ */
+ @Test
+ public void testGetMatchingOsuProvidersWithInvalidScanResult() {
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ mWifiServiceImpl.getMatchingOsuProviders(new ArrayList<>());
+ mLooper.dispatchAll();
+ verify(mPasspointManager, never()).getMatchingOsuProviders(any());
+ }
+
+ /**
* Verify that the call to getMatchingPasspointConfigsForOsuProviders is not redirected to
* specific API syncGetMatchingPasspointConfigsForOsuProviders when the caller doesn't have
* NETWORK_SETTINGS permissions and NETWORK_SETUP_WIZARD.
@@ -5372,7 +5428,8 @@
public void testGetWifiConfigsForMatchedNetworkSuggestionsWithSettingPermissions() {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
- mWifiServiceImpl.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>());
+ mWifiServiceImpl
+ .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(createScanResultList());
mLooper.dispatchAll();
verify(mWifiNetworkSuggestionsManager)
.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any());
@@ -5387,12 +5444,24 @@
public void testGetWifiConfigsForMatchedNetworkSuggestionsWithSetupWizardPermissions() {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETUP_WIZARD),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
- mWifiServiceImpl.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>());
+ mWifiServiceImpl
+ .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(createScanResultList());
mLooper.dispatchAll();
verify(mWifiNetworkSuggestionsManager)
.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any());
}
+ @Test
+ public void testGetWifiConfigsForMatchedNetworkSuggestionsWithInvalidScanResults() {
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ mWifiServiceImpl
+ .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>());
+ mLooper.dispatchAll();
+ verify(mWifiNetworkSuggestionsManager, never())
+ .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any());
+ }
+
/**
* Verify that a call to setWifiConnectedNetworkScorer throws a SecurityException if
* the caller does not have WIFI_UPDATE_USABILITY_STATS_SCORE permission.
@@ -5670,4 +5739,9 @@
verify(mSettingsStore, never()).handleWifiScanAlwaysAvailableToggled(anyBoolean());
verify(mActiveModeWarden, never()).scanAlwaysModeChanged();
}
+
+ private List<ScanResult> createScanResultList() {
+ return Collections.singletonList(new ScanResult(WifiSsid.createFromAsciiEncoded(TEST_SSID),
+ TEST_SSID, TEST_BSSID, 1245, 0, TEST_CAP, -78, 2450, 1025, 22, 33, 20, 0, 0, true));
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WrongPasswordNotifierTest.java b/tests/wifitests/src/com/android/server/wifi/WrongPasswordNotifierTest.java
index 3b4bdfd..4afcfba 100644
--- a/tests/wifitests/src/com/android/server/wifi/WrongPasswordNotifierTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WrongPasswordNotifierTest.java
@@ -42,7 +42,7 @@
public class WrongPasswordNotifierTest extends WifiBaseTest {
private static final String TEST_SSID = "Test SSID";
- @Mock Context mContext;
+ @Mock WifiContext mContext;
@Mock Resources mResources;
@Mock NotificationManager mNotificationManager;
@Mock FrameworkFacade mFrameworkFacade;
@@ -58,8 +58,8 @@
when(mContext.getSystemService(Context.NOTIFICATION_SERVICE))
.thenReturn(mNotificationManager);
when(mContext.getResources()).thenReturn(mResources);
- mWrongPassNotifier =
- new WrongPasswordNotifier(mContext, mFrameworkFacade);
+ when(mContext.getWifiOverlayApkPkgName()).thenReturn("test.com.android.wifi.resources");
+ mWrongPassNotifier = new WrongPasswordNotifier(mContext, mFrameworkFacade);
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java
index f234a1e..6423f95 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java
@@ -62,7 +62,6 @@
import androidx.test.filters.SmallTest;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
-import com.android.server.wifi.MockResources;
import com.android.server.wifi.WifiBaseTest;
import com.android.server.wifi.WifiMetrics;
import com.android.server.wifi.WifiNative;
@@ -80,7 +79,6 @@
import com.android.server.wifi.hotspot2.soap.command.BrowserUri;
import com.android.server.wifi.hotspot2.soap.command.PpsMoData;
import com.android.server.wifi.hotspot2.soap.command.SppCommand;
-import com.android.wifi.resources.R;
import org.junit.After;
import org.junit.Before;
@@ -258,16 +256,13 @@
when(mOsuServerConnection.exchangeSoapMessage(
any(SoapSerializationEnvelope.class))).thenReturn(true);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
- MockResources mockResources = new MockResources();
- mockResources.setString(R.string.config_wifiOsuLoginPackage, OSU_APP_PACKAGE);
- when(mContext.getResources()).thenReturn(mockResources);
ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.activityInfo = new ActivityInfo();
resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
resolveInfo.activityInfo.name = OSU_APP_NAME;
resolveInfo.activityInfo.applicationInfo.packageName = OSU_APP_PACKAGE;
- when(mPackageManager.resolveActivity(any(Intent.class),
- eq(PackageManager.MATCH_DEFAULT_ONLY))).thenReturn(resolveInfo);
+ when(mPackageManager.queryIntentActivities(any(Intent.class), anyInt()))
+ .thenReturn(Arrays.asList(resolveInfo));
Map<String, byte[]> trustCertInfo = new HashMap<>();
trustCertInfo.put("https://testurl.com", "testData".getBytes());
@@ -632,7 +627,7 @@
verifyNoMoreInteractions(mCallback);
}
- /**
+ /**
* Verifies that the right provisioning callbacks are invoked as the provisioner connects
* to OSU AP and OSU server and that invalid server URL generates the right error callback.
*/
@@ -782,8 +777,7 @@
@Test
public void verifyNoOsuActivityFoundFailure() throws RemoteException {
// There is no activity found for the intent
- when(mPackageManager.resolveActivity(any(Intent.class),
- eq(PackageManager.MATCH_DEFAULT_ONLY))).thenReturn(null);
+ when(mPackageManager.queryIntentActivities(any(Intent.class), anyInt())).thenReturn(null);
stopAfterStep(STEP_SERVER_CONNECT);
// Server validation passed
diff --git a/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java
index 0f69316..e58d083 100644
--- a/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java
@@ -31,7 +31,9 @@
import org.junit.Test;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
/**
* Unit tests for {@link com.android.server.wifi.util.ScanResultUtil}.
@@ -243,6 +245,26 @@
assertTrue(ScanResultUtil.isScanResultForFilsSha384Network(input));
}
+ /**
+ * Verify ScanResultList validation.
+ */
+ @Test
+ public void testValidateScanResultList() {
+ List<ScanResult> scanResults = new ArrayList<>();
+ assertFalse(ScanResultUtil.validateScanResultList(null));
+ assertFalse(ScanResultUtil.validateScanResultList(scanResults));
+ scanResults.add(null);
+ assertFalse(ScanResultUtil.validateScanResultList(scanResults));
+ ScanResult scanResult = new ScanResult();
+ scanResults.clear();
+ scanResults.add(scanResult);
+ assertFalse(ScanResultUtil.validateScanResultList(scanResults));
+ scanResult.SSID = "test";
+ scanResult.capabilities = "[RSN-PSK-CCMP]";
+ scanResult.BSSID = "ab:cd:01:ef:45:89";
+ assertTrue(ScanResultUtil.validateScanResultList(scanResults));
+ }
+
private static InformationElement createIE(int id, byte[] bytes) {
InformationElement ie = new InformationElement();
ie.id = id;