summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Xin Li <delphij@google.com> 2024-11-10 18:14:36 -0800
committer Xin Li <delphij@google.com> 2024-11-10 18:14:36 -0800
commit76d9f212eed591a618842fa4e86211e2626aa188 (patch)
tree18c05a643886bea7e6a30533f807c39ae65d1cbf
parent110babf640671bceab0dceb45fa26ea5783f2d14 (diff)
parent0787ad6eb52b956c262cf16efb0f708e8cd8a426 (diff)
Merge 24Q4 (ab/12406339) into aosp-main-future
Bug: 370570306 Merged-In: I0f642c1c489d444462f6131b72129beb7da6f505 Change-Id: I232066bcbb084c1086d1d0a549938435f3505071
-rw-r--r--flags/wifi_flags.aconfig86
-rw-r--r--framework/api/current.txt3
-rw-r--r--framework/jarjar-rules.txt10
-rw-r--r--framework/java/android/net/wifi/BaseWifiService.java42
-rw-r--r--framework/java/android/net/wifi/IWifiManager.aidl31
-rw-r--r--framework/java/android/net/wifi/IWifiScannerListener.aidl4
-rw-r--r--framework/java/android/net/wifi/WifiManager.java81
-rw-r--r--framework/java/android/net/wifi/WifiNetworkSpecifier.java1
-rw-r--r--framework/java/android/net/wifi/WifiScanner.java63
-rw-r--r--framework/java/android/net/wifi/WifiUriParser.java140
-rw-r--r--framework/java/android/net/wifi/aware/AwarePairingConfig.java61
-rw-r--r--framework/java/android/net/wifi/aware/PublishConfig.java3
-rw-r--r--framework/java/android/net/wifi/rtt/RangingResult.java14
-rw-r--r--framework/java/android/net/wifi/util/ScanResultUtil.java5
-rw-r--r--framework/java/android/net/wifi/util/WifiResourceCache.java251
-rw-r--r--framework/lint-baseline.xml70
-rw-r--r--framework/tests/Android.bp1
-rw-r--r--framework/tests/src/android/net/wifi/MscsParamsTest.java9
-rw-r--r--framework/tests/src/android/net/wifi/OuiKeyedDataTest.java4
-rw-r--r--framework/tests/src/android/net/wifi/QosCharacteristicsTest.java8
-rw-r--r--framework/tests/src/android/net/wifi/QosPolicyParamsTest.java7
-rw-r--r--framework/tests/src/android/net/wifi/WifiManagerTest.java46
-rw-r--r--framework/tests/src/android/net/wifi/WifiUriParserTest.java88
-rw-r--r--framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java27
-rw-r--r--framework/tests/src/android/net/wifi/util/WifiResourceCacheTest.java125
-rw-r--r--service/Android.bp2
-rw-r--r--service/ServiceWifiResources/res/values-fr-rCA-feminine/strings.xml23
-rw-r--r--service/ServiceWifiResources/res/values-fr-rCA-masculine/strings.xml23
-rw-r--r--service/ServiceWifiResources/res/values-fr-rCA-neuter/strings.xml23
-rw-r--r--service/ServiceWifiResources/res/values/config.xml36
-rw-r--r--service/ServiceWifiResources/res/values/overlayable.xml6
-rw-r--r--service/java/com/android/server/wifi/ActiveModeWarden.java53
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java81
-rw-r--r--service/java/com/android/server/wifi/ConcreteClientModeManager.java2
-rw-r--r--service/java/com/android/server/wifi/DeviceConfigFacade.java25
-rw-r--r--service/java/com/android/server/wifi/HalDeviceManager.java95
-rw-r--r--service/java/com/android/server/wifi/HostapdHal.java6
-rw-r--r--service/java/com/android/server/wifi/HostapdHalAidlImp.java48
-rw-r--r--service/java/com/android/server/wifi/HostapdHalHidlImp.java31
-rw-r--r--service/java/com/android/server/wifi/ISupplicantStaIfaceHal.java11
-rw-r--r--service/java/com/android/server/wifi/PmkCacheManager.java3
-rw-r--r--service/java/com/android/server/wifi/RssiMonitor.java13
-rw-r--r--service/java/com/android/server/wifi/ScanRequestProxy.java2
-rw-r--r--service/java/com/android/server/wifi/SoftApManager.java178
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java22
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java19
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlV1_4Impl.java3
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceHal.java24
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java145
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java120
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java22
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaNetworkHalHidlImpl.java15
-rw-r--r--service/java/com/android/server/wifi/WifiApConfigStore.java44
-rw-r--r--service/java/com/android/server/wifi/WifiCarrierInfoManager.java25
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java11
-rw-r--r--service/java/com/android/server/wifi/WifiConfigurationUtil.java112
-rw-r--r--service/java/com/android/server/wifi/WifiConnectivityManager.java239
-rw-r--r--service/java/com/android/server/wifi/WifiCountryCode.java30
-rw-r--r--service/java/com/android/server/wifi/WifiDataStall.java37
-rw-r--r--service/java/com/android/server/wifi/WifiGlobals.java285
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java11
-rw-r--r--service/java/com/android/server/wifi/WifiMetrics.java313
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java51
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkFactory.java47
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSelector.java2
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java17
-rw-r--r--service/java/com/android/server/wifi/WifiScoreReport.java118
-rw-r--r--service/java/com/android/server/wifi/WifiServiceImpl.java311
-rw-r--r--service/java/com/android/server/wifi/WifiSettingsConfigStore.java9
-rw-r--r--service/java/com/android/server/wifi/WifiShellCommand.java174
-rw-r--r--service/java/com/android/server/wifi/WifiVendorHal.java35
-rw-r--r--service/java/com/android/server/wifi/aware/PairingConfigManager.java19
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareStateManager.java110
-rw-r--r--service/java/com/android/server/wifi/hal/IWifiChip.java9
-rw-r--r--service/java/com/android/server/wifi/hal/IWifiStaIface.java5
-rw-r--r--service/java/com/android/server/wifi/hal/WifiChip.java9
-rw-r--r--service/java/com/android/server/wifi/hal/WifiChipAidlImpl.java29
-rw-r--r--service/java/com/android/server/wifi/hal/WifiChipHidlImpl.java39
-rw-r--r--service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java59
-rw-r--r--service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java13
-rw-r--r--service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java16
-rw-r--r--service/java/com/android/server/wifi/hal/WifiStaIface.java5
-rw-r--r--service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java39
-rw-r--r--service/java/com/android/server/wifi/hal/WifiStaIfaceHidlImpl.java39
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java2
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pNative.java13
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java880
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScannerInternal.java6
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java163
-rw-r--r--service/java/com/android/server/wifi/scanner/WificondScannerImpl.java8
-rw-r--r--service/java/com/android/server/wifi/util/ApConfigUtil.java188
-rw-r--r--service/java/com/android/server/wifi/util/GeneralUtil.java35
-rw-r--r--service/java/com/android/server/wifi/util/InformationElementUtil.java54
-rw-r--r--service/java/com/android/server/wifi/util/NativeUtil.java27
-rw-r--r--service/java/com/android/server/wifi/util/XmlUtil.java13
-rw-r--r--service/tests/wifitests/Android.bp3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java126
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java76
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java15
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java169
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/HostapdHalAidlImpTest.java45
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/HostapdHalHidlImpTest.java29
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/MockResourceCache.java85
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/MockResources.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/RssiMonitorTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java280
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SoftApStoreDataTest.java55
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java184
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java149
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java11
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalAidlImplTest.java17
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalHidlImplTest.java14
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java10
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java63
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java37
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java75
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java222
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java91
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java17
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java20
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java519
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java20
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java64
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java36
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java81
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiRoamingConfigStoreTest.java6
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java152
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java309
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java142
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java20
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/PairingConfigManagerTest.java132
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java123
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/b2b/WifiRoamingModeManagerTest.java5
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipAidlImplTest.java6
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipHidlImplTest.java11
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceAidlImplTest.java23
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerAidlImplTest.java78
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceAidlImplTest.java8
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceHidlImplTest.java7
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelperTest.java19
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java476
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/rtt/RttTestUtils.java32
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java9
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java22
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java10
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/HalAidlUtilTest.java9
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java223
148 files changed, 8129 insertions, 2081 deletions
diff --git a/flags/wifi_flags.aconfig b/flags/wifi_flags.aconfig
index 2da04a5284..7b4decfefe 100644
--- a/flags/wifi_flags.aconfig
+++ b/flags/wifi_flags.aconfig
@@ -9,6 +9,22 @@ flag {
}
flag {
+ name: "p2p_ownership"
+ namespace: "wifi"
+ description: "Control the P2P group ownership feature"
+ bug: "215045910"
+ is_fixed_read_only: true
+}
+
+flag {
+ name: "p2p_dual"
+ namespace: "wifi"
+ description: "Control the dual P2P group feature"
+ bug: "296063280"
+ is_fixed_read_only: true
+}
+
+flag {
name: "delay_save_to_store"
namespace: "wifi"
description: "Control the feature delay the save to store in batch to reduce the blocking time"
@@ -71,11 +87,14 @@ flag {
}
flag {
- name: "voip_detection"
+ name: "voip_detection_bugfix"
namespace: "wifi"
description: "Detect VoIP over Wifi and execute optimization"
bug: "295885471"
is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
flag {
@@ -85,4 +104,69 @@ flag {
description: "Add new API to get BSSID blocklist"
bug: "336109216"
is_fixed_read_only: true
+}
+
+flag {
+ name: "delayed_carrier_network_selection"
+ namespace: "wifi"
+ description: "Delay network selection for some carrier networks until a delay period has passed"
+ bug: "329142362"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "local_only_connection_optimization"
+ namespace: "wifi"
+ description: "optimize local-only connection API"
+ bug: "347117408"
+ is_fixed_read_only: true
+}
+
+flag {
+ name: "softap_config_store_max_channel_width"
+ namespace: "wifi"
+ description: "Store MaxChannelBandwidth to SoftAP config"
+ bug: "344450923"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "rsn_overriding"
+ namespace: "wifi"
+ description: "Wi-Fi Alliance RSN Overriding feature"
+ bug: "348669010"
+ is_fixed_read_only: true
+}
+
+flag {
+ name: "new_uri_parsing_for_escape_character"
+ namespace: "wifi"
+ description: "New parsing logic for Zxing uri format which support escape character"
+ bug: "342706482"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "aware_pairing"
+ is_exported: true
+ namespace: "wifi"
+ description: "Add new API for Aware pairing"
+ bug: "354820259"
+ is_fixed_read_only: true
+}
+
+flag {
+ name: "wifi_scorer_new_stats_collection"
+ namespace: "wifi"
+ description: "Gate WiFi Scorer new stats collection"
+ bug: "367362809"
} \ No newline at end of file
diff --git a/framework/api/current.txt b/framework/api/current.txt
index a277bca42c..45ec47ea32 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -584,6 +584,7 @@ package android.net.wifi {
field public static final int STATUS_LOCAL_ONLY_CONNECTION_FAILURE_NOT_FOUND = 4; // 0x4
field public static final int STATUS_LOCAL_ONLY_CONNECTION_FAILURE_NO_RESPONSE = 5; // 0x5
field public static final int STATUS_LOCAL_ONLY_CONNECTION_FAILURE_UNKNOWN = 0; // 0x0
+ field @FlaggedApi("com.android.wifi.flags.local_only_connection_optimization") public static final int STATUS_LOCAL_ONLY_CONNECTION_FAILURE_USER_REJECT = 6; // 0x6
field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE = 3; // 0x3
field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_EXCEEDS_MAX_PER_APP = 4; // 0x4
field public static final int STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_INVALID = 7; // 0x7
@@ -846,6 +847,7 @@ package android.net.wifi.aware {
public final class AwarePairingConfig implements android.os.Parcelable {
method public int describeContents();
method public int getBootstrappingMethods();
+ method @FlaggedApi("com.android.wifi.flags.aware_pairing") public int getSupportedCipherSuites();
method public boolean isPairingCacheEnabled();
method public boolean isPairingSetupEnabled();
method public boolean isPairingVerificationEnabled();
@@ -869,6 +871,7 @@ package android.net.wifi.aware {
method @NonNull public android.net.wifi.aware.AwarePairingConfig.Builder setPairingCacheEnabled(boolean);
method @NonNull public android.net.wifi.aware.AwarePairingConfig.Builder setPairingSetupEnabled(boolean);
method @NonNull public android.net.wifi.aware.AwarePairingConfig.Builder setPairingVerificationEnabled(boolean);
+ method @FlaggedApi("com.android.wifi.flags.aware_pairing") @NonNull public android.net.wifi.aware.AwarePairingConfig.Builder setSupportedCipherSuites(int);
}
public final class AwareResources implements android.os.Parcelable {
diff --git a/framework/jarjar-rules.txt b/framework/jarjar-rules.txt
index f1b4000737..598c014b71 100644
--- a/framework/jarjar-rules.txt
+++ b/framework/jarjar-rules.txt
@@ -86,7 +86,15 @@ rule android.util.BackupUtils* com.android.wifi.x.@0
rule android.util.LocalLog* com.android.wifi.x.@0
rule android.util.Rational* com.android.wifi.x.@0
-rule com.android.wifi.flags.** com.android.wifi.x.@0
+# Repackage generated flag classes.
+# Need to specify the rule on classes to avoid transform the literals
+rule com.android.wifi.flags.*FeatureFlags* com.android.wifi.x.@0
+rule com.android.wifi.flags.FeatureFlags* com.android.wifi.x.@0
+rule com.android.wifi.flags.Flags com.android.wifi.x.@0
+
+rule android.net.wifi.flags.*FeatureFlags* com.android.wifi.x.@0
+rule android.net.wifi.flags.FeatureFlags* com.android.wifi.x.@0
+rule android.net.wifi.flags.Flags com.android.wifi.x.@0
# Use our statically linked bouncy castle library
rule org.bouncycastle.** com.android.wifi.x.@0
diff --git a/framework/java/android/net/wifi/BaseWifiService.java b/framework/java/android/net/wifi/BaseWifiService.java
index 5f58810584..0d3ae0a753 100644
--- a/framework/java/android/net/wifi/BaseWifiService.java
+++ b/framework/java/android/net/wifi/BaseWifiService.java
@@ -32,6 +32,7 @@ import android.os.RemoteException;
import android.os.WorkSource;
import com.android.modules.utils.ParceledListSlice;
+import com.android.modules.utils.StringParceledListSlice;
import java.util.List;
import java.util.Map;
@@ -123,24 +124,24 @@ public class BaseWifiService extends IWifiManager.Stub {
}
@Override
- public void setSsidsAllowlist(String packageName, List<WifiSsid> ssids) {
+ public void setSsidsAllowlist(String packageName, ParceledListSlice<WifiSsid> ssids) {
throw new UnsupportedOperationException();
}
@Override
- public List<WifiSsid> getSsidsAllowlist(String packageName) {
+ public ParceledListSlice<WifiSsid> getSsidsAllowlist(String packageName) {
throw new UnsupportedOperationException();
}
@Override
public Map<OsuProvider, List<ScanResult>> getMatchingOsuProviders(
- List<ScanResult> scanResults) {
+ ParceledListSlice<ScanResult> scanResults) {
throw new UnsupportedOperationException();
}
@Override
public Map<OsuProvider, PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(
- List<OsuProvider> osuProviders) {
+ ParceledListSlice<OsuProvider> osuProviders) {
throw new UnsupportedOperationException();
}
@@ -167,12 +168,14 @@ public class BaseWifiService extends IWifiManager.Stub {
}
@Override
- public List<PasspointConfiguration> getPasspointConfigurations(String packageName) {
+ public ParceledListSlice<PasspointConfiguration> getPasspointConfigurations(
+ String packageName) {
throw new UnsupportedOperationException();
}
@Override
- public List<WifiConfiguration> getWifiConfigsForPasspointProfiles(List<String> fqdnList) {
+ public ParceledListSlice<WifiConfiguration> getWifiConfigsForPasspointProfiles(
+ StringParceledListSlice fqdnList) {
throw new UnsupportedOperationException();
}
@@ -723,19 +726,20 @@ public class BaseWifiService extends IWifiManager.Stub {
@Override
public int addNetworkSuggestions(
- List<WifiNetworkSuggestion> networkSuggestions, String callingPackageName,
+ ParceledListSlice<WifiNetworkSuggestion> networkSuggestions, String callingPackageName,
String callingFeatureId) {
throw new UnsupportedOperationException();
}
@Override
public int removeNetworkSuggestions(
- List<WifiNetworkSuggestion> networkSuggestions, String callingPackageName, int action) {
+ ParceledListSlice<WifiNetworkSuggestion> networkSuggestions, String callingPackageName,
+ int action) {
throw new UnsupportedOperationException();
}
@Override
- public List<WifiNetworkSuggestion> getNetworkSuggestions(String packageName) {
+ public ParceledListSlice<WifiNetworkSuggestion> getNetworkSuggestions(String packageName) {
throw new UnsupportedOperationException();
}
@@ -875,8 +879,9 @@ public class BaseWifiService extends IWifiManager.Stub {
}
@Override
- public List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
- List<ScanResult> scanResults) {
+ public ParceledListSlice<WifiConfiguration>
+ getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
+ ParceledListSlice<ScanResult> scanResults) {
throw new UnsupportedOperationException();
}
@@ -911,8 +916,8 @@ public class BaseWifiService extends IWifiManager.Stub {
@Override
public Map<WifiNetworkSuggestion, List<ScanResult>> getMatchingScanResults(
- List<WifiNetworkSuggestion> networkSuggestions,
- List<ScanResult> scanResults,
+ ParceledListSlice<WifiNetworkSuggestion> networkSuggestions,
+ ParceledListSlice<ScanResult> scanResults,
String callingPackage, String callingFeatureId) {
throw new UnsupportedOperationException();
}
@@ -929,7 +934,8 @@ public class BaseWifiService extends IWifiManager.Stub {
@Override
public Map<String, Map<Integer, List<ScanResult>>>
- getAllMatchingPasspointProfilesForScanResults(List<ScanResult> scanResults) {
+ getAllMatchingPasspointProfilesForScanResults(
+ ParceledListSlice<ScanResult> scanResults) {
throw new UnsupportedOperationException();
}
@@ -1014,7 +1020,8 @@ public class BaseWifiService extends IWifiManager.Stub {
}
@Override
- public void notifyWifiSsidPolicyChanged(int policyType, @NonNull List<WifiSsid> ssids) {
+ public void notifyWifiSsidPolicyChanged(int policyType,
+ @NonNull ParceledListSlice<WifiSsid> ssids) {
throw new UnsupportedOperationException();
}
@@ -1035,7 +1042,8 @@ public class BaseWifiService extends IWifiManager.Stub {
}
@Override
- public void addCustomDhcpOptions(WifiSsid ssid, byte[] oui, @NonNull List<DhcpOption> options) {
+ public void addCustomDhcpOptions(WifiSsid ssid, byte[] oui,
+ @NonNull ParceledListSlice<DhcpOption> options) {
throw new UnsupportedOperationException();
}
@@ -1056,7 +1064,7 @@ public class BaseWifiService extends IWifiManager.Stub {
}
@Override
- public void addQosPolicies(@NonNull List<QosPolicyParams> policyParamsList,
+ public void addQosPolicies(@NonNull ParceledListSlice<QosPolicyParams> policyParamsList,
@NonNull IBinder binder, @NonNull String packageName, @NonNull IListListener listener) {
throw new UnsupportedOperationException();
}
diff --git a/framework/java/android/net/wifi/IWifiManager.aidl b/framework/java/android/net/wifi/IWifiManager.aidl
index 0a6e210249..dc8a44407f 100644
--- a/framework/java/android/net/wifi/IWifiManager.aidl
+++ b/framework/java/android/net/wifi/IWifiManager.aidl
@@ -79,6 +79,7 @@ import android.os.ResultReceiver;
import android.os.WorkSource;
import com.android.modules.utils.ParceledListSlice;
+import com.android.modules.utils.StringParceledListSlice;
/**
* Interface that allows controlling and querying Wi-Fi connectivity.
@@ -111,13 +112,13 @@ interface IWifiManager
Map getAllMatchingFqdnsForScanResults(in List<ScanResult> scanResult);
- void setSsidsAllowlist(String packageName, in List<WifiSsid> ssids);
+ void setSsidsAllowlist(String packageName, in ParceledListSlice<WifiSsid> ssids);
- List getSsidsAllowlist(String packageName);
+ ParceledListSlice getSsidsAllowlist(String packageName);
- Map getMatchingOsuProviders(in List<ScanResult> scanResult);
+ Map getMatchingOsuProviders(in ParceledListSlice<ScanResult> scanResult);
- Map getMatchingPasspointConfigsForOsuProviders(in List<OsuProvider> osuProviders);
+ Map getMatchingPasspointConfigsForOsuProviders(in ParceledListSlice<OsuProvider> osuProviders);
int addOrUpdateNetwork(in WifiConfiguration config, String packageName, in Bundle extras);
@@ -127,9 +128,9 @@ interface IWifiManager
boolean removePasspointConfiguration(in String fqdn, String packageName);
- List<PasspointConfiguration> getPasspointConfigurations(in String packageName);
+ ParceledListSlice<PasspointConfiguration> getPasspointConfigurations(in String packageName);
- List<WifiConfiguration> getWifiConfigsForPasspointProfiles(in List<String> fqdnList);
+ ParceledListSlice<WifiConfiguration> getWifiConfigsForPasspointProfiles(in StringParceledListSlice fqdnList);
void queryPasspointIcon(long bssid, String fileName);
@@ -332,12 +333,12 @@ interface IWifiManager
void unregisterNetworkRequestMatchCallback(in INetworkRequestMatchCallback callback);
- int addNetworkSuggestions(in List<WifiNetworkSuggestion> networkSuggestions, in String packageName,
+ int addNetworkSuggestions(in ParceledListSlice<WifiNetworkSuggestion> networkSuggestions, in String packageName,
in String featureId);
- int removeNetworkSuggestions(in List<WifiNetworkSuggestion> networkSuggestions, in String packageName, int action);
+ int removeNetworkSuggestions(in ParceledListSlice<WifiNetworkSuggestion> networkSuggestions, in String packageName, int action);
- List<WifiNetworkSuggestion> getNetworkSuggestions(in String packageName);
+ ParceledListSlice<WifiNetworkSuggestion> getNetworkSuggestions(in String packageName);
String[] getFactoryMacAddresses();
@@ -376,7 +377,7 @@ interface IWifiManager
int calculateSignalLevel(int rssi);
- List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in List<ScanResult> scanResults);
+ ParceledListSlice<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(in ParceledListSlice<ScanResult> scanResults);
boolean setWifiConnectedNetworkScorer(in IBinder binder, in IWifiConnectedNetworkScorer scorer);
@@ -393,13 +394,13 @@ interface IWifiManager
/**
* Return the Map of {@link WifiNetworkSuggestion} and the list of <ScanResult>
*/
- Map getMatchingScanResults(in List<WifiNetworkSuggestion> networkSuggestions, in List<ScanResult> scanResults, String callingPackage, String callingFeatureId);
+ Map getMatchingScanResults(in ParceledListSlice<WifiNetworkSuggestion> networkSuggestions, in ParceledListSlice<ScanResult> scanResults, String callingPackage, String callingFeatureId);
void setScanThrottleEnabled(boolean enable);
boolean isScanThrottleEnabled();
- Map getAllMatchingPasspointProfilesForScanResults(in List<ScanResult> scanResult);
+ Map getAllMatchingPasspointProfilesForScanResults(in ParceledListSlice<ScanResult> scanResult);
void setAutoWakeupEnabled(boolean enable);
@@ -443,7 +444,7 @@ interface IWifiManager
void notifyMinimumRequiredWifiSecurityLevelChanged(int level);
- void notifyWifiSsidPolicyChanged(int policyType, in List<WifiSsid> ssids);
+ void notifyWifiSsidPolicyChanged(int policyType, in ParceledListSlice<WifiSsid> ssids);
String[] getOemPrivilegedWifiAdminPackages();
@@ -451,7 +452,7 @@ interface IWifiManager
void replyToSimpleDialog(int dialogId, int reply);
- void addCustomDhcpOptions(in WifiSsid ssid, in byte[] oui, in List<DhcpOption> options);
+ void addCustomDhcpOptions(in WifiSsid ssid, in byte[] oui, in ParceledListSlice<DhcpOption> options);
void removeCustomDhcpOptions(in WifiSsid ssid, in byte[] oui);
@@ -459,7 +460,7 @@ interface IWifiManager
int getMaxNumberOfChannelsPerRequest();
- void addQosPolicies(in List<QosPolicyParams> policyParamsList, in IBinder binder, String packageName, in IListListener callback);
+ void addQosPolicies(in ParceledListSlice<QosPolicyParams> policyParamsList, in IBinder binder, String packageName, in IListListener callback);
void removeQosPolicies(in int[] policyIdList, String packageName);
diff --git a/framework/java/android/net/wifi/IWifiScannerListener.aidl b/framework/java/android/net/wifi/IWifiScannerListener.aidl
index 04b5e41cc8..bd19ac2d0f 100644
--- a/framework/java/android/net/wifi/IWifiScannerListener.aidl
+++ b/framework/java/android/net/wifi/IWifiScannerListener.aidl
@@ -43,4 +43,8 @@ oneway interface IWifiScannerListener
* Invoked when one of the PNO networks are found in scan results.
*/
void onPnoNetworkFound(in ScanResult[] results);
+ /**
+ * reports full scan result for all access points found in scan
+ */
+ void onFullResults(in List<ScanResult> scanResult);
} \ No newline at end of file
diff --git a/framework/java/android/net/wifi/WifiManager.java b/framework/java/android/net/wifi/WifiManager.java
index 7bd0c0d591..4ab897e730 100644
--- a/framework/java/android/net/wifi/WifiManager.java
+++ b/framework/java/android/net/wifi/WifiManager.java
@@ -93,6 +93,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.HandlerExecutor;
import com.android.modules.utils.ParceledListSlice;
+import com.android.modules.utils.StringParceledListSlice;
import com.android.modules.utils.build.SdkLevel;
import com.android.wifi.flags.Flags;
@@ -339,9 +340,14 @@ public class WifiManager {
*/
public static final int STATUS_LOCAL_ONLY_CONNECTION_FAILURE_NOT_FOUND = 4;
/**
- * Reason code if local-only network connection attempt failed with AP not responding
+ * Reason code if local-only network connection attempt failed with AP not responding.
*/
public static final int STATUS_LOCAL_ONLY_CONNECTION_FAILURE_NO_RESPONSE = 5;
+ /**
+ * Reason code if local-only network request rejected by the user.
+ */
+ @FlaggedApi(Flags.FLAG_LOCAL_ONLY_CONNECTION_OPTIMIZATION)
+ public static final int STATUS_LOCAL_ONLY_CONNECTION_FAILURE_USER_REJECT = 6;
/** @hide */
@IntDef(prefix = {"STATUS_LOCAL_ONLY_CONNECTION_FAILURE_"},
@@ -350,7 +356,8 @@ public class WifiManager {
STATUS_LOCAL_ONLY_CONNECTION_FAILURE_AUTHENTICATION,
STATUS_LOCAL_ONLY_CONNECTION_FAILURE_IP_PROVISIONING,
STATUS_LOCAL_ONLY_CONNECTION_FAILURE_NOT_FOUND,
- STATUS_LOCAL_ONLY_CONNECTION_FAILURE_NO_RESPONSE
+ STATUS_LOCAL_ONLY_CONNECTION_FAILURE_NO_RESPONSE,
+ STATUS_LOCAL_ONLY_CONNECTION_FAILURE_USER_REJECT
})
@Retention(RetentionPolicy.SOURCE)
public @interface LocalOnlyConnectionStatusCode {}
@@ -2388,13 +2395,15 @@ public class WifiManager {
List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> configs = new ArrayList<>();
try {
Map<String, Map<Integer, List<ScanResult>>> results =
- mService.getAllMatchingPasspointProfilesForScanResults(scanResults);
+ mService.getAllMatchingPasspointProfilesForScanResults(
+ new ParceledListSlice<>(scanResults));
if (results.isEmpty()) {
return configs;
}
List<WifiConfiguration> wifiConfigurations =
mService.getWifiConfigsForPasspointProfiles(
- new ArrayList<>(results.keySet()));
+ new StringParceledListSlice(new ArrayList<>(results.keySet())))
+ .getList();
for (WifiConfiguration configuration : wifiConfigurations) {
Map<Integer, List<ScanResult>> scanResultsPerNetworkType =
results.get(configuration.getProfileKey());
@@ -2695,7 +2704,8 @@ public class WifiManager {
public List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
@NonNull List<ScanResult> scanResults) {
try {
- return mService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(scanResults);
+ return mService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
+ new ParceledListSlice<>(scanResults)).getList();
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -2722,7 +2732,8 @@ public class WifiManager {
throw new IllegalArgumentException(TAG + ": ssids can not be null");
}
try {
- mService.setSsidsAllowlist(mContext.getOpPackageName(), new ArrayList<>(ssids));
+ mService.setSsidsAllowlist(mContext.getOpPackageName(),
+ new ParceledListSlice<>(new ArrayList<>(ssids)));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2743,7 +2754,7 @@ public class WifiManager {
public @NonNull Set<WifiSsid> getSsidsAllowlist() {
try {
return new ArraySet<WifiSsid>(
- mService.getSsidsAllowlist(mContext.getOpPackageName()));
+ mService.getSsidsAllowlist(mContext.getOpPackageName()).getList());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2771,7 +2782,7 @@ public class WifiManager {
return new HashMap<>();
}
try {
- return mService.getMatchingOsuProviders(scanResults);
+ return mService.getMatchingOsuProviders(new ParceledListSlice<>(scanResults));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2799,7 +2810,7 @@ public class WifiManager {
@NonNull Set<OsuProvider> osuProviders) {
try {
return mService.getMatchingPasspointConfigsForOsuProviders(
- new ArrayList<>(osuProviders));
+ new ParceledListSlice<>(new ArrayList<>(osuProviders)));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3402,8 +3413,8 @@ public class WifiManager {
public @NetworkSuggestionsStatusCode int addNetworkSuggestions(
@NonNull List<WifiNetworkSuggestion> networkSuggestions) {
try {
- return mService.addNetworkSuggestions(
- networkSuggestions, mContext.getOpPackageName(), mContext.getAttributionTag());
+ return mService.addNetworkSuggestions(new ParceledListSlice<>(networkSuggestions),
+ mContext.getOpPackageName(), mContext.getAttributionTag());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3455,7 +3466,7 @@ public class WifiManager {
@NonNull List<WifiNetworkSuggestion> networkSuggestions,
@ActionAfterRemovingSuggestion int action) {
try {
- return mService.removeNetworkSuggestions(networkSuggestions,
+ return mService.removeNetworkSuggestions(new ParceledListSlice<>(networkSuggestions),
mContext.getOpPackageName(), action);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -3471,7 +3482,7 @@ public class WifiManager {
@RequiresPermission(ACCESS_WIFI_STATE)
public @NonNull List<WifiNetworkSuggestion> getNetworkSuggestions() {
try {
- return mService.getNetworkSuggestions(mContext.getOpPackageName());
+ return mService.getNetworkSuggestions(mContext.getOpPackageName()).getList();
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -3570,7 +3581,7 @@ public class WifiManager {
@Deprecated
public List<PasspointConfiguration> getPasspointConfigurations() {
try {
- return mService.getPasspointConfigurations(mContext.getOpPackageName());
+ return mService.getPasspointConfigurations(mContext.getOpPackageName()).getList();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4567,7 +4578,8 @@ public class WifiManager {
}
try {
return mService.getMatchingScanResults(
- networkSuggestionsToMatch, scanResults,
+ new ParceledListSlice<>(networkSuggestionsToMatch),
+ new ParceledListSlice<>(scanResults),
mContext.getOpPackageName(), mContext.getAttributionTag());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -5158,8 +5170,9 @@ public class WifiManager {
* <li>Device Owner (DO), Profile Owner (PO) and system apps.
* </ul>
*
- * Starting with {@link android.os.Build.VERSION_CODES#TIRAMISU}, DO/COPE may set
- * a user restriction (DISALLOW_CHANGE_WIFI_STATE) to only allow DO/PO to use this API.
+ * Starting with {@link android.os.Build.VERSION_CODES#TIRAMISU}, DO and a profile owner of
+ * an organization owned device may set a user restriction (DISALLOW_CHANGE_WIFI_STATE)
+ * to only allow DO/PO to use this API.
*/
@Deprecated
public boolean setWifiEnabled(boolean enabled) {
@@ -11320,8 +11333,8 @@ public class WifiManager {
}
try {
if (policy != null) {
- mService.notifyWifiSsidPolicyChanged(
- policy.getPolicyType(), new ArrayList<>(policy.getSsids()));
+ mService.notifyWifiSsidPolicyChanged(policy.getPolicyType(),
+ new ParceledListSlice<>(new ArrayList<>(policy.getSsids())));
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -11634,7 +11647,7 @@ public class WifiManager {
public void addCustomDhcpOptions(@NonNull WifiSsid ssid, @NonNull byte[] oui,
@NonNull List<DhcpOption> options) {
try {
- mService.addCustomDhcpOptions(ssid, oui, options);
+ mService.addCustomDhcpOptions(ssid, oui, new ParceledListSlice<>(options));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -11894,7 +11907,8 @@ public class WifiManager {
Objects.requireNonNull(executor, "executor cannot be null");
Objects.requireNonNull(resultsCallback, "resultsCallback cannot be null");
try {
- mService.addQosPolicies(policyParamsList, new Binder(), mContext.getOpPackageName(),
+ mService.addQosPolicies(new ParceledListSlice<>(policyParamsList),
+ new Binder(), mContext.getOpPackageName(),
new IListListener.Stub() {
@Override
public void onResult(List value) {
@@ -12441,18 +12455,19 @@ public class WifiManager {
/**
* This API allows a privileged application to set roaming mode per SSID.
*
- * Available for DO/COPE apps.
+ * Available for Device Owner (DO) and profile owner of an organization owned device.
* Other apps require {@code android.Manifest.permission#NETWORK_SETTINGS} or
* {@code android.Manifest.permission#MANAGE_WIFI_NETWORK_SELECTION} permission.
*
* @param ssid SSID to be mapped to apply roaming policy
- * @param roamingMode refer {@link RoamingMode} for supported modes.
- * @throws IllegalArgumentException if mode value is not in {@link RoamingMode}.
+ * @param roamingMode One of the {@code ROAMING_MODE_} values.
+ * @throws IllegalArgumentException if input is invalid.
* @throws NullPointerException if the caller provided a null input.
* @throws SecurityException if caller does not have the required permission.
- * @throws UnsupportedOperationException if the set operation is not supported on this SDK or
- * if the feature is not available
- * {@link #isAggressiveRoamingModeSupported()}.
+ * @throws UnsupportedOperationException if the API is not supported on this SDK version or
+ * {@link #isAggressiveRoamingModeSupported()} returns
+ * false, but input roaming mode is
+ * {@code ROAMING_MODE_AGGRESSIVE}.
*/
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@@ -12473,16 +12488,14 @@ public class WifiManager {
* This API allows a privileged application to remove roaming mode policy
* configured using the {@link #setPerSsidRoamingMode(WifiSsid, int)}.
*
- * Available for DO/COPE apps.
+ * Available for Device Owner (DO) and profile owner of an organization owned device.
* Other apps require {@code android.Manifest.permission#NETWORK_SETTINGS} or
* {@code android.Manifest.permission#MANAGE_WIFI_NETWORK_SELECTION} permission.
*
* @param ssid SSID to be removed from the roaming mode policy.
* @throws NullPointerException if the caller provided a null input.
* @throws SecurityException if caller does not have the required permission.
- * @throws UnsupportedOperationException if the set operation is not supported on this SDK or
- * if the feature is not available
- * {@link #isAggressiveRoamingModeSupported()}.
+ * @throws UnsupportedOperationException if the API is not supported on this SDK version.
*/
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@@ -12500,7 +12513,7 @@ public class WifiManager {
* This API allows a privileged application to get roaming mode policies
* configured using the {@link #setPerSsidRoamingMode(WifiSsid, int)}.
*
- * Available for DO/COPE apps.
+ * Available for Device Owner (DO) and profile owner of an organization owned device.
* Other apps require {@code android.Manifest.permission#NETWORK_SETTINGS} or
* {@code android.Manifest.permission#MANAGE_WIFI_NETWORK_SELECTION} permission.
*
@@ -12508,9 +12521,7 @@ public class WifiManager {
* @param resultsCallback An asynchronous callback that will return the corresponding
* roaming policies for the API caller.
* @throws SecurityException if caller does not have the required permission.
- * @throws UnsupportedOperationException if the get operation is not supported on this SDK or
- * if the feature is not available
- * {@link #isAggressiveRoamingModeSupported()}.
+ * @throws UnsupportedOperationException if the API is not supported on this SDK version.
*/
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
diff --git a/framework/java/android/net/wifi/WifiNetworkSpecifier.java b/framework/java/android/net/wifi/WifiNetworkSpecifier.java
index a137b220fb..199969d9c7 100644
--- a/framework/java/android/net/wifi/WifiNetworkSpecifier.java
+++ b/framework/java/android/net/wifi/WifiNetworkSpecifier.java
@@ -829,6 +829,7 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
.append(", BSSID Match pattern=").append(bssidPatternMatcher)
.append(", SSID=").append(wifiConfiguration.SSID)
.append(", BSSID=").append(wifiConfiguration.BSSID)
+ .append(", channels=").append(Arrays.toString(mChannelFreqs))
.append(", band=").append(mBand)
.append("]")
.toString();
diff --git a/framework/java/android/net/wifi/WifiScanner.java b/framework/java/android/net/wifi/WifiScanner.java
index b9c6f428d3..1dffa8a3c7 100644
--- a/framework/java/android/net/wifi/WifiScanner.java
+++ b/framework/java/android/net/wifi/WifiScanner.java
@@ -375,6 +375,7 @@ public class WifiScanner {
*/
@Override
public void onFullResult(ScanResult fullScanResult) {
+ Log.i(TAG, "onFullResult");
if (mActionListener == null) return;
if (!(mActionListener instanceof ScanListener)) return;
ScanListener scanListener = (ScanListener) mActionListener;
@@ -383,6 +384,20 @@ public class WifiScanner {
() -> scanListener.onFullResult(fullScanResult));
}
+ /**
+ * reports full scan result for all access points found in scan
+ */
+ @Override
+ public void onFullResults(List<ScanResult> fullScanResult) {
+ Log.i(TAG, "onFullResults");
+ if (mActionListener == null) return;
+ if (!(mActionListener instanceof ScanListener)) return;
+ ScanListener scanListener = (ScanListener) mActionListener;
+ Binder.clearCallingIdentity();
+ mExecutor.execute(
+ () -> fullScanResult.forEach(scanListener::onFullResult));
+ }
+
@Override
public void onSingleScanCompleted() {
if (DBG) Log.d(TAG, "single scan completed");
@@ -431,6 +446,16 @@ public class WifiScanner {
passive = false;
dwellTimeMS = 0;
}
+
+ /**
+ * @hide
+ * Todo: add it to the sdk
+ */
+ public ChannelSpec(int frequency, boolean passive, int dwellTimeMS) {
+ this.frequency = frequency;
+ this.passive = passive;
+ this.dwellTimeMS = dwellTimeMS;
+ }
}
/**
@@ -732,6 +757,44 @@ public class WifiScanner {
return mVendorIes;
}
+ public ScanSettings() {}
+
+ /**
+ * @hide
+ * Todo: add it to the sdk
+ */
+ public ScanSettings(@NonNull ScanSettings that) {
+ this.band = that.band;
+ this.periodInMs = that.periodInMs;
+ this.reportEvents = that.reportEvents;
+ this.numBssidsPerScan = that.numBssidsPerScan;
+ this.maxScansToCache = that.maxScansToCache;
+ this.maxPeriodInMs = that.maxPeriodInMs;
+ this.stepCount = that.stepCount;
+ this.isPnoScan = that.isPnoScan;
+ this.type = that.type;
+ this.ignoreLocationSettings = that.ignoreLocationSettings;
+ this.hideFromAppOps = that.hideFromAppOps;
+ this.mRnrSetting = that.mRnrSetting;
+ this.mEnable6GhzPsc = that.mEnable6GhzPsc;
+ if (that.channels != null) {
+ this.channels = new ChannelSpec[that.channels.length];
+ for (int i = 0; i < that.channels.length; i++) {
+ ChannelSpec spec = new ChannelSpec(that.channels[i].frequency,
+ that.channels[i].passive, that.channels[i].dwellTimeMS);
+ this.channels[i] = spec;
+ }
+ } else {
+ this.channels = new ChannelSpec[0];
+ }
+ for (HiddenNetwork hiddenNetwork : that.hiddenNetworks) {
+ this.hiddenNetworks.add(new HiddenNetwork(hiddenNetwork.ssid));
+ }
+ for (ScanResult.InformationElement ie : that.mVendorIes) {
+ this.mVendorIes.add(new ScanResult.InformationElement(ie.id, ie.idExt, ie.bytes));
+ }
+ }
+
/** Implement the Parcelable interface {@hide} */
public int describeContents() {
return 0;
diff --git a/framework/java/android/net/wifi/WifiUriParser.java b/framework/java/android/net/wifi/WifiUriParser.java
index ada1fa97ba..1d42ae5ada 100644
--- a/framework/java/android/net/wifi/WifiUriParser.java
+++ b/framework/java/android/net/wifi/WifiUriParser.java
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import androidx.annotation.VisibleForTesting;
@@ -68,6 +69,7 @@ public class WifiUriParser {
static final String PREFIX_ZXING_TRANSITION_DISABLE = "R:";
static final String DELIMITER_QR_CODE = ";";
+ static final char URI_DELIMITER_CHAR = ';';
// Ignores password if security is SECURITY_NO_PASSWORD or absent
static final String SECURITY_NO_PASSWORD = "nopass"; // open network or OWE
@@ -80,6 +82,14 @@ public class WifiUriParser {
private WifiUriParser() {}
/**
+ * @hide
+ */
+ @VisibleForTesting
+ public static boolean mockableIsFlagNewUriParsingForEscapeCharacterEnabled() {
+ return Flags.newUriParsingForEscapeCharacter();
+ }
+
+ /**
* Returns parsed result from given uri.
*
* @param uri URI of the configuration that was obtained out of band(QR code scanning, BLE).
@@ -117,26 +127,73 @@ public class WifiUriParser {
}
/** Parses ZXing reader library's Wi-Fi Network config format */
- private static UriParserResults parseZxingWifiUriParser(String uri)
+ private static UriParserResults parseZxingWifiUriParser(@NonNull String uri)
throws IllegalArgumentException {
- List<String> keyValueList =
- getKeyValueList(uri, PREFIX_ZXING_WIFI_NETWORK_CONFIG, DELIMITER_QR_CODE);
WifiConfiguration config = null;
- String security = getValueOrNull(keyValueList, PREFIX_ZXING_SECURITY);
- String ssid = getValueOrNull(keyValueList, PREFIX_ZXING_SSID);
- String password = getValueOrNull(keyValueList, PREFIX_ZXING_PASSWORD);
- String hiddenSsidString = getValueOrNull(keyValueList, PREFIX_ZXING_HIDDEN_SSID);
- String transitionDisabledValue = getValueOrNull(keyValueList,
- PREFIX_ZXING_TRANSITION_DISABLE);
+ String security = null;
+ String ssid = null;
+ String password = null;
+ String hiddenSsidString = null;
+ String transitionDisabledValue = null;
+ if (mockableIsFlagNewUriParsingForEscapeCharacterEnabled()) {
+ String wifiQr = uri.substring(PREFIX_ZXING_WIFI_NETWORK_CONFIG.length());
+ Pair<Integer, String> zxingUriElement;
+ int start = 0;
+ while (start < wifiQr.length()) {
+ String value = wifiQr.substring(start);
+ char ch = wifiQr.charAt(start);
+ if (value.startsWith(PREFIX_ZXING_SSID)) {
+ zxingUriElement = getZxingUriElement(value, PREFIX_ZXING_SSID);
+ ssid = zxingUriElement.second;
+ start = start + zxingUriElement.first + PREFIX_ZXING_SSID.length();
+ } else if (value.startsWith(PREFIX_ZXING_SECURITY)) {
+ zxingUriElement = getZxingUriElement(value, PREFIX_ZXING_SECURITY);
+ security = zxingUriElement.second;
+ start = start + zxingUriElement.first + PREFIX_ZXING_SECURITY.length();
+ } else if (value.startsWith(PREFIX_ZXING_PASSWORD)) {
+ zxingUriElement = getZxingUriElement(value, PREFIX_ZXING_PASSWORD);
+ password = zxingUriElement.second;
+ start = start + zxingUriElement.first + PREFIX_ZXING_PASSWORD.length();
+ } else if (value.startsWith(PREFIX_ZXING_HIDDEN_SSID)) {
+ zxingUriElement = getZxingUriElement(value, PREFIX_ZXING_HIDDEN_SSID);
+ hiddenSsidString = zxingUriElement.second;
+ start = start + zxingUriElement.first
+ + PREFIX_ZXING_HIDDEN_SSID.length();
+ } else if (value.startsWith(PREFIX_ZXING_TRANSITION_DISABLE)) {
+ zxingUriElement = getZxingUriElement(value,
+ PREFIX_ZXING_TRANSITION_DISABLE);
+ transitionDisabledValue = zxingUriElement.second;
+ start = start + zxingUriElement.first
+ + PREFIX_ZXING_TRANSITION_DISABLE.length();
+ } else if (Character.isWhitespace(ch) || ch == URI_DELIMITER_CHAR) {
+ // Skip space and DELIMITER_QR_CODE in URI when detecting prefix
+ start++;
+ } else {
+ zxingUriElement = getZxingUriElement(value, "" /* empty prefix */);
+ String unsupportedUriPrefix = zxingUriElement.second;
+ Log.i(TAG, "UnsupportedUriPrefix Found:" + unsupportedUriPrefix);
+ start = start + zxingUriElement.first;
+ }
+ }
+ } else {
+ List<String> keyValueList =
+ getKeyValueList(uri, PREFIX_ZXING_WIFI_NETWORK_CONFIG, DELIMITER_QR_CODE);
+ security = getValueOrNull(keyValueList, PREFIX_ZXING_SECURITY);
+ ssid = getValueOrNull(keyValueList, PREFIX_ZXING_SSID);
+ password = getValueOrNull(keyValueList, PREFIX_ZXING_PASSWORD);
+ hiddenSsidString = getValueOrNull(keyValueList, PREFIX_ZXING_HIDDEN_SSID);
+ transitionDisabledValue = getValueOrNull(keyValueList,
+ PREFIX_ZXING_TRANSITION_DISABLE);
+
+ // "\", ";", "," and ":" are escaped with a backslash "\", should remove at first
+ security = removeBackSlash(security);
+ ssid = removeBackSlash(ssid);
+ password = removeBackSlash(password);
+ }
boolean hiddenSsid = "true".equalsIgnoreCase(hiddenSsidString);
boolean isTransitionDisabled = "1".equalsIgnoreCase(transitionDisabledValue);
-
- // "\", ";", "," and ":" are escaped with a backslash "\", should remove at first
- security = removeBackSlash(security);
- ssid = removeBackSlash(ssid);
- password = removeBackSlash(password);
if (isValidConfig(security, ssid, password)) {
- config = generatetWifiConfiguration(
+ config = generateWifiConfiguration(
security, ssid, password, hiddenSsid, WifiConfiguration.INVALID_NETWORK_ID,
isTransitionDisabled);
}
@@ -148,6 +205,36 @@ public class WifiUriParser {
null, null, config);
}
+ private static Pair<Integer, String> getZxingUriElement(@NonNull String uriSubString,
+ @NonNull String prefixString) {
+ StringBuilder sb = new StringBuilder();
+ int numberOfCharHandled = 0;
+ boolean isPreviousCharEscaped = false;
+ for (int i = prefixString.length(); i < uriSubString.length(); i++) {
+ char ch = uriSubString.charAt(i);
+ numberOfCharHandled++;
+ if (ch == '\\') {
+ if (isPreviousCharEscaped) {
+ // The '\' is the part of the uri field
+ sb.append(ch);
+ isPreviousCharEscaped = false;
+ continue;
+ }
+ isPreviousCharEscaped = true;
+ } else if (ch == URI_DELIMITER_CHAR) {
+ if (!isPreviousCharEscaped) {
+ break;
+ }
+ sb.append(ch);
+ isPreviousCharEscaped = false;
+ } else {
+ sb.append(ch);
+ isPreviousCharEscaped = false;
+ }
+ }
+ return new Pair<>(numberOfCharHandled, sb.toString());
+ }
+
/**
* Splits key/value pairs from uri
*
@@ -203,13 +290,15 @@ public class WifiUriParser {
return sb.toString();
}
- private static String addQuotationIfNeeded(String input) {
+ private static String addQuotation(String input) {
if (TextUtils.isEmpty(input)) {
return "";
}
- if (input.length() >= 2 && input.startsWith("\"") && input.endsWith("\"")) {
- return input;
+ if (!mockableIsFlagNewUriParsingForEscapeCharacterEnabled()) {
+ if (input.length() >= 2 && input.startsWith("\"") && input.endsWith("\"")) {
+ return input;
+ }
}
StringBuilder sb = new StringBuilder();
@@ -236,11 +325,11 @@ public class WifiUriParser {
*
* @return WifiConfiguration from parsing result
*/
- private static WifiConfiguration generatetWifiConfiguration(
+ private static WifiConfiguration generateWifiConfiguration(
String security, String ssid, String preSharedKey, boolean hiddenSsid, int networkId,
boolean isTransitionDisabled) {
final WifiConfiguration wifiConfiguration = new WifiConfiguration();
- wifiConfiguration.SSID = addQuotationIfNeeded(ssid);
+ wifiConfiguration.SSID = addQuotation(ssid);
wifiConfiguration.hiddenSSID = hiddenSsid;
wifiConfiguration.networkId = networkId;
@@ -263,7 +352,7 @@ public class WifiUriParser {
&& preSharedKey.matches("[0-9A-Fa-f]*")) {
wifiConfiguration.wepKeys[0] = preSharedKey;
} else {
- wifiConfiguration.wepKeys[0] = addQuotationIfNeeded(preSharedKey);
+ wifiConfiguration.wepKeys[0] = addQuotation(preSharedKey);
}
} else if (security.startsWith(SECURITY_WPA_PSK)) {
List<SecurityParams> securityParamsList = new ArrayList<>();
@@ -281,17 +370,18 @@ public class WifiUriParser {
if (preSharedKey.matches("[0-9A-Fa-f]{64}")) {
wifiConfiguration.preSharedKey = preSharedKey;
} else {
- wifiConfiguration.preSharedKey = addQuotationIfNeeded(preSharedKey);
+ wifiConfiguration.preSharedKey = addQuotation(preSharedKey);
}
} else if (security.startsWith(SECURITY_SAE)) {
wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
if (preSharedKey.length() != 0) {
- wifiConfiguration.preSharedKey = addQuotationIfNeeded(preSharedKey);
+ wifiConfiguration.preSharedKey = addQuotation(preSharedKey);
}
} else if (security.startsWith(SECURITY_ADB)) {
- Log.i(TAG, "Specific security key: ADB");
+ Log.i(TAG, "Security key: ADB, the ssid and passphrase should NOT add quotation");
+ wifiConfiguration.SSID = ssid;
if (preSharedKey.length() != 0) {
- wifiConfiguration.preSharedKey = addQuotationIfNeeded(preSharedKey);
+ wifiConfiguration.preSharedKey = preSharedKey;
}
} else {
throw new IllegalArgumentException("Unsupported security");
diff --git a/framework/java/android/net/wifi/aware/AwarePairingConfig.java b/framework/java/android/net/wifi/aware/AwarePairingConfig.java
index f37174aee2..f677e10271 100644
--- a/framework/java/android/net/wifi/aware/AwarePairingConfig.java
+++ b/framework/java/android/net/wifi/aware/AwarePairingConfig.java
@@ -16,11 +16,16 @@
package android.net.wifi.aware;
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128;
+
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.wifi.flags.Flags;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
@@ -73,6 +78,11 @@ public final class AwarePairingConfig implements Parcelable {
* Aware Pairing bootstrapping method NFC reader
*/
public static final int PAIRING_BOOTSTRAPPING_NFC_READER = 1 << 8;
+ /**
+ * This is used for the boundary check and should be the max value of the bitmap + 1.
+ * @hide
+ */
+ public static final int PAIRING_BOOTSTRAPPING_MAX = 1 << 9;
/** @hide */
@@ -96,6 +106,7 @@ public final class AwarePairingConfig implements Parcelable {
private final boolean mPairingCache;
private final boolean mPairingVerification;
private final int mBootstrappingMethods;
+ private final int mCipherSuites;
/**
* Check if the NPK/NIK cache is support in the config
@@ -129,6 +140,29 @@ public final class AwarePairingConfig implements Parcelable {
return mBootstrappingMethods;
}
+ /**
+ * Get the supported cipher suites in this config.
+ */
+ @FlaggedApi(Flags.FLAG_AWARE_PAIRING)
+ @Characteristics.WifiAwarePairingCipherSuites
+ public int getSupportedCipherSuites() {
+ return mCipherSuites;
+ }
+
+ /**
+ * Verifies that the contents of the AwarePairingConfig are valid
+ * @hide
+ */
+ public boolean assertValid(Characteristics characteristics) {
+ if (mBootstrappingMethods < 0 || mBootstrappingMethods >= PAIRING_BOOTSTRAPPING_MAX) {
+ return false;
+ }
+ if ((characteristics.getSupportedPairingCipherSuites() & mCipherSuites) == 0) {
+ return false;
+ }
+ return true;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -136,21 +170,24 @@ public final class AwarePairingConfig implements Parcelable {
AwarePairingConfig that = (AwarePairingConfig) o;
return mPairingSetup == that.mPairingSetup && mPairingCache == that.mPairingCache
&& mPairingVerification == that.mPairingVerification
- && mBootstrappingMethods == that.mBootstrappingMethods;
+ && mBootstrappingMethods == that.mBootstrappingMethods
+ && mCipherSuites == that.mCipherSuites;
}
@Override
public int hashCode() {
return Objects.hash(mPairingSetup, mPairingCache, mPairingVerification,
- mBootstrappingMethods);
+ mBootstrappingMethods, mCipherSuites);
}
/** @hide */
- public AwarePairingConfig(boolean setup, boolean cache, boolean verification, int method) {
+ public AwarePairingConfig(boolean setup, boolean cache, boolean verification, int method,
+ int cipherSuites) {
mPairingSetup = setup;
mPairingCache = cache;
mPairingVerification = verification;
mBootstrappingMethods = method;
+ mCipherSuites = cipherSuites;
}
/** @hide */
@@ -159,6 +196,7 @@ public final class AwarePairingConfig implements Parcelable {
mPairingCache = in.readBoolean();
mPairingVerification = in.readBoolean();
mBootstrappingMethods = in.readInt();
+ mCipherSuites = in.readInt();
}
@Override
@@ -167,6 +205,7 @@ public final class AwarePairingConfig implements Parcelable {
dest.writeBoolean(mPairingCache);
dest.writeBoolean(mPairingVerification);
dest.writeInt(mBootstrappingMethods);
+ dest.writeInt(mCipherSuites);
}
@Override
@@ -194,6 +233,7 @@ public final class AwarePairingConfig implements Parcelable {
private boolean mPairingCache = false;
private boolean mPairingVerification = false;
private int mBootStrappingMethods = 0;
+ private int mCipherSuites = WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128;
/**
* Set whether enable the Aware Pairing setup
@@ -238,13 +278,26 @@ public final class AwarePairingConfig implements Parcelable {
}
/**
+ * Set the supported cipher suites. If not set, default will be
+ * {@link Characteristics#WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128}
+ * @param cipherSuites cipher suites supported
+ * @return the current {@link Builder} builder, enabling chaining of builder methods.
+ */
+ @FlaggedApi(Flags.FLAG_AWARE_PAIRING)
+ @NonNull public Builder setSupportedCipherSuites(
+ @Characteristics.WifiAwarePairingCipherSuites int cipherSuites) {
+ mCipherSuites = cipherSuites;
+ return this;
+ }
+
+ /**
* Build {@link AwarePairingConfig} given the current requests made on the
* builder.
*/
@NonNull
public AwarePairingConfig build() {
return new AwarePairingConfig(mPairingSetup, mPairingCache, mPairingVerification,
- mBootStrappingMethods);
+ mBootStrappingMethods, mCipherSuites);
}
}
}
diff --git a/framework/java/android/net/wifi/aware/PublishConfig.java b/framework/java/android/net/wifi/aware/PublishConfig.java
index aa43cdbb99..b429fac63d 100644
--- a/framework/java/android/net/wifi/aware/PublishConfig.java
+++ b/framework/java/android/net/wifi/aware/PublishConfig.java
@@ -302,6 +302,9 @@ public final class PublishConfig implements Parcelable {
if (mPairingConfig != null && !characteristics.isAwarePairingSupported()) {
throw new IllegalArgumentException("Aware Pairing is not supported");
}
+ if (mPairingConfig != null && !mPairingConfig.assertValid(characteristics)) {
+ throw new IllegalArgumentException("Unsupported pairing config");
+ }
}
if (!rttSupported && mEnableRanging) {
diff --git a/framework/java/android/net/wifi/rtt/RangingResult.java b/framework/java/android/net/wifi/rtt/RangingResult.java
index 87b1ed9af3..6739291929 100644
--- a/framework/java/android/net/wifi/rtt/RangingResult.java
+++ b/framework/java/android/net/wifi/rtt/RangingResult.java
@@ -1009,13 +1009,13 @@ public final class RangingResult implements Parcelable {
.append(mIs80211mcMeasurement)
.append(", frequencyMHz=").append(mFrequencyMHz)
.append(", packetBw=").append(mPacketBw)
- .append("is80211azNtbMeasurement").append(mIs80211azNtbMeasurement)
- .append("ntbMinMeasurementTime").append(mNtbMinMeasurementTime)
- .append("ntbMaxMeasurementTime").append(mNtbMaxMeasurementTime)
- .append("i2rTxLtfRepetitions").append(mI2rTxLtfRepetitions)
- .append("r2iTxLtfRepetitions").append(mR2iTxLtfRepetitions)
- .append("txSpatialStreams").append(mNumTxSpatialStreams)
- .append("rxSpatialStreams").append(mNumRxSpatialStreams)
+ .append(", is80211azNtbMeasurement=").append(mIs80211azNtbMeasurement)
+ .append(", ntbMinMeasurementTimeMicros=").append(mNtbMinMeasurementTime)
+ .append(", ntbMaxMeasurementTimeMicros=").append(mNtbMaxMeasurementTime)
+ .append(", i2rTxLtfRepetitions=").append(mI2rTxLtfRepetitions)
+ .append(", r2iTxLtfRepetitions=").append(mR2iTxLtfRepetitions)
+ .append(", numTxSpatialStreams=").append(mNumTxSpatialStreams)
+ .append(", numRxSpatialStreams=").append(mNumRxSpatialStreams)
.append(", vendorData=").append(mVendorData)
.append("]").toString();
}
diff --git a/framework/java/android/net/wifi/util/ScanResultUtil.java b/framework/java/android/net/wifi/util/ScanResultUtil.java
index 9851957ffc..ca8d62b3d3 100644
--- a/framework/java/android/net/wifi/util/ScanResultUtil.java
+++ b/framework/java/android/net/wifi/util/ScanResultUtil.java
@@ -464,9 +464,10 @@ public class ScanResultUtil {
} else {
rssiInfo = String.format("%9d ", r.level);
}
+ String capabilities = r.capabilities;
if ((r.flags & FLAG_PASSPOINT_NETWORK)
== FLAG_PASSPOINT_NETWORK) {
- r.capabilities += "[PASSPOINT]";
+ capabilities += "[PASSPOINT]";
}
pw.printf(" %17s %9d %18s %7s %-32s %s\n",
r.BSSID,
@@ -474,7 +475,7 @@ public class ScanResultUtil {
rssiInfo,
age,
String.format("%1.32s", ssid),
- r.capabilities);
+ capabilities);
}
}
}
diff --git a/framework/java/android/net/wifi/util/WifiResourceCache.java b/framework/java/android/net/wifi/util/WifiResourceCache.java
index 89d7cb964a..1d987d3fb4 100644
--- a/framework/java/android/net/wifi/util/WifiResourceCache.java
+++ b/framework/java/android/net/wifi/util/WifiResourceCache.java
@@ -19,7 +19,9 @@ package android.net.wifi.util;
import android.content.Context;
import java.io.PrintWriter;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -27,31 +29,150 @@ import java.util.Map;
* @hide
*/
public class WifiResourceCache {
+ private static final String TAG = "WifiResourceCache";
private final Context mContext;
- private final Map<String, Boolean> mBooleanResourceMap;
- private final Map<String, Integer> mIntegerResourceMap;
+ private final Map<Integer, Boolean> mBooleanResourceMap;
+ private final Map<Integer, Integer> mIntegerResourceMap;
+ private final Map<Integer, String> mStringResourceMap;
+ private final Map<Integer, String[]> mStringArrayResourceMap;
+ private final Map<Integer, int[]> mIntArrayResourceMap;
+ private final List<Map> mValueMapList;
+ private final Map<String, Integer> mResourceNameMap;
+
+ private int mTempId = -1;
+ private final Object mLock = new Object();
public WifiResourceCache(Context context) {
mContext = context;
mBooleanResourceMap = new HashMap<>();
mIntegerResourceMap = new HashMap<>();
+ mStringArrayResourceMap = new HashMap<>();
+ mIntArrayResourceMap = new HashMap<>();
+ mStringResourceMap = new HashMap<>();
+ mValueMapList = List.of(mBooleanResourceMap, mIntegerResourceMap, mIntArrayResourceMap,
+ mStringArrayResourceMap, mStringResourceMap);
+ mResourceNameMap = new HashMap<>();
}
/**
* Get and cache the boolean value as {@link android.content.res.Resources#getBoolean(int)}
*/
- public boolean getBoolean(int resourceId, String resourceName) {
- return mBooleanResourceMap.computeIfAbsent(resourceName,
- v -> mContext.getResources().getBoolean(resourceId));
+ public boolean getBoolean(int resourceId) {
+ synchronized (mLock) {
+ if (mBooleanResourceMap.containsKey(resourceId)) {
+ return mBooleanResourceMap.get(resourceId);
+ }
+
+ String resourceName = mContext.getResources().getResourceEntryName(resourceId);
+ if (mResourceNameMap.containsKey(resourceName)) {
+ int tempId = mResourceNameMap.get(resourceName);
+ boolean value = mBooleanResourceMap.get(tempId);
+ mBooleanResourceMap.put(resourceId, value);
+ mBooleanResourceMap.remove(tempId);
+ mResourceNameMap.put(resourceName, resourceId);
+ return value;
+ }
+ mResourceNameMap.put(resourceName, resourceId);
+ return mBooleanResourceMap.computeIfAbsent(resourceId,
+ v -> mContext.getResources().getBoolean(resourceId));
+ }
}
/**
* Get and cache the integer value as {@link android.content.res.Resources#getInteger(int)}
*/
- public int getInteger(int resourceId, String resourceName) {
- return mIntegerResourceMap.computeIfAbsent(resourceName,
- v -> mContext.getResources().getInteger(resourceId));
+ public int getInteger(int resourceId) {
+ synchronized (mLock) {
+ if (mIntegerResourceMap.containsKey(resourceId)) {
+ return mIntegerResourceMap.get(resourceId);
+ }
+
+ String resourceName = mContext.getResources().getResourceEntryName(resourceId);
+ if (mResourceNameMap.containsKey(resourceName)) {
+ int tempId = mResourceNameMap.get(resourceName);
+ int value = mIntegerResourceMap.get(tempId);
+ mIntegerResourceMap.put(resourceId, value);
+ mIntegerResourceMap.remove(tempId);
+ mResourceNameMap.put(resourceName, resourceId);
+ return value;
+ }
+ mResourceNameMap.put(resourceName, resourceId);
+ return mIntegerResourceMap.computeIfAbsent(resourceId,
+ v -> mContext.getResources().getInteger(resourceId));
+ }
+ }
+
+ /**
+ * Get and cache the integer value as {@link android.content.res.Resources#getString(int)}
+ */
+ public String getString(int resourceId) {
+ synchronized (mLock) {
+ if (mStringResourceMap.containsKey(resourceId)) {
+ return mStringResourceMap.get(resourceId);
+ }
+
+ String resourceName = mContext.getResources().getResourceEntryName(resourceId);
+ if (mResourceNameMap.containsKey(resourceName)) {
+ int tempId = mResourceNameMap.get(resourceName);
+ String value = mStringResourceMap.get(tempId);
+ mStringResourceMap.put(resourceId, value);
+ mStringResourceMap.remove(tempId);
+ mResourceNameMap.put(resourceName, resourceId);
+ return value;
+ }
+ mResourceNameMap.put(resourceName, resourceId);
+ return mStringResourceMap.computeIfAbsent(resourceId,
+ v -> mContext.getResources().getString(resourceId));
+ }
+ }
+
+ /**
+ * Get and cache the integer value as {@link android.content.res.Resources#getStringArray(int)}
+ */
+ public String[] getStringArray(int resourceId) {
+ synchronized (mLock) {
+ if (mStringArrayResourceMap.containsKey(resourceId)) {
+ return mStringArrayResourceMap.get(resourceId);
+ }
+
+ String resourceName = mContext.getResources().getResourceEntryName(resourceId);
+ if (mResourceNameMap.containsKey(resourceName)) {
+ int tempId = mResourceNameMap.get(resourceName);
+ String[] value = mStringArrayResourceMap.get(tempId);
+ mStringArrayResourceMap.put(resourceId, value);
+ mStringArrayResourceMap.remove(tempId);
+ mResourceNameMap.put(resourceName, resourceId);
+ return value;
+ }
+ mResourceNameMap.put(resourceName, resourceId);
+ return mStringArrayResourceMap.computeIfAbsent(resourceId,
+ v -> mContext.getResources().getStringArray(resourceId));
+ }
+ }
+
+ /**
+ * Get and cache the integer value as {@link android.content.res.Resources#getIntArray(int)}
+ */
+ public int[] getIntArray(int resourceId) {
+ synchronized (mLock) {
+ if (mIntArrayResourceMap.containsKey(resourceId)) {
+ return mIntArrayResourceMap.get(resourceId);
+ }
+
+ String resourceName = mContext.getResources().getResourceEntryName(resourceId);
+ if (mResourceNameMap.containsKey(resourceName)) {
+ int tempId = mResourceNameMap.get(resourceName);
+ int[] value = mIntArrayResourceMap.get(tempId);
+ mIntArrayResourceMap.put(resourceId, value);
+ mIntArrayResourceMap.remove(tempId);
+ mResourceNameMap.put(resourceName, resourceId);
+ return value;
+ }
+ mResourceNameMap.put(resourceName, resourceId);
+ return mIntArrayResourceMap.computeIfAbsent(resourceId,
+ v -> mContext.getResources().getIntArray(resourceId));
+ }
}
/**
@@ -61,14 +182,19 @@ public class WifiResourceCache {
* @param value override to this value
*/
public void overrideBooleanValue(String resourceName, boolean value) {
- mBooleanResourceMap.put(resourceName, value);
+ synchronized (mLock) {
+ int resourceId = mResourceNameMap.computeIfAbsent(resourceName, v -> mTempId--);
+ mBooleanResourceMap.put(resourceId, value);
+ }
}
/**
* Override the target boolean value
*/
public void restoreBooleanValue(String resourceName) {
- mBooleanResourceMap.remove(resourceName);
+ synchronized (mLock) {
+ mBooleanResourceMap.remove(mResourceNameMap.remove(resourceName));
+ }
}
/**
@@ -77,14 +203,82 @@ public class WifiResourceCache {
* @param value override to this value
*/
public void overrideIntegerValue(String resourceName, int value) {
- mIntegerResourceMap.put(resourceName, value);
+ synchronized (mLock) {
+ int resourceId = mResourceNameMap.computeIfAbsent(resourceName, v -> mTempId--);
+ mIntegerResourceMap.put(resourceId, value);
+ }
}
/**
* Override the target integer value
*/
public void restoreIntegerValue(String resourceName) {
- mIntegerResourceMap.remove(resourceName);
+ synchronized (mLock) {
+ mIntegerResourceMap.remove(mResourceNameMap.remove(resourceName));
+ }
+ }
+
+ /**
+ * Override the target String value
+ * @param resourceName the resource overlay name
+ * @param value override to this value
+ */
+ public void overrideStringValue(String resourceName, String value) {
+ synchronized (mLock) {
+ int resourceId = mResourceNameMap.computeIfAbsent(resourceName, v -> mTempId--);
+ mStringResourceMap.put(resourceId, value);
+ }
+ }
+
+ /**
+ * Override the target integer value
+ */
+ public void restoreStringValue(String resourceName) {
+ synchronized (mLock) {
+ mStringResourceMap.remove(mResourceNameMap.remove(resourceName));
+ }
+ }
+
+ /**
+ * Override the target string array value
+ * @param resourceName the resource overlay name
+ * @param value override to this value
+ */
+ public void overrideStringArrayValue(String resourceName, String[] value) {
+ synchronized (mLock) {
+ int resourceId = mResourceNameMap.computeIfAbsent(resourceName, v -> mTempId--);
+ mStringArrayResourceMap.put(resourceId, value);
+ }
+ }
+
+ /**
+ * Override the target string array value
+ */
+ public void restoreStringArrayValue(String resourceName) {
+ synchronized (mLock) {
+ mStringArrayResourceMap.remove(mResourceNameMap.remove(resourceName));
+ }
+ }
+
+ /**
+ * Override the target int array value
+ * @param resourceName the resource overlay name
+ * @param value override to this value
+ */
+ public void overrideIntArrayValue(String resourceName, int[] value) {
+ synchronized (mLock) {
+ int resourceId = mResourceNameMap.computeIfAbsent(resourceName, v -> mTempId--);
+ mIntArrayResourceMap.put(resourceId, value);
+ }
+ }
+
+ /**
+ * Override the target int array value
+ */
+ public void restoreIntArrayValue(String resourceName) {
+ synchronized (mLock) {
+ mIntArrayResourceMap.remove(mResourceNameMap.remove(resourceName));
+ }
}
/**
@@ -93,23 +287,36 @@ public class WifiResourceCache {
public void dump(PrintWriter pw) {
pw.println("Dump of WifiResourceCache");
pw.println("WifiResourceCache - resource value Begin ----");
-
- for (Map.Entry<String, Integer> resourceEntry : mIntegerResourceMap.entrySet()) {
- pw.println("Resource Name: " + resourceEntry.getKey()
- + ", value: " + resourceEntry.getValue());
- }
- for (Map.Entry<String, Boolean> resourceEntry : mBooleanResourceMap.entrySet()) {
- pw.println("Resource Name: " + resourceEntry.getKey()
- + ", value: " + resourceEntry.getValue());
+ synchronized (mLock) {
+ for (Map.Entry<String, Integer> resourceEntry : mResourceNameMap.entrySet()) {
+ for (Map m : mValueMapList) {
+ if (m.containsKey(resourceEntry.getValue())) {
+ pw.println("Resource Name: " + resourceEntry.getKey()
+ + ", value: " + valueToString(m.get(resourceEntry.getValue())));
+ break;
+ }
+ }
+ }
}
pw.println("WifiResourceCache - resource value End ----");
}
+ private String valueToString(Object input) {
+ if (input instanceof Object[]) {
+ return Arrays.deepToString((Object[]) input);
+ }
+ return input.toString();
+ }
+
/**
* Remove all override value and set to default
*/
public void reset() {
- mBooleanResourceMap.clear();
- mIntegerResourceMap.clear();
+ synchronized (mLock) {
+ for (Map m : mValueMapList) {
+ m.clear();
+ }
+ mResourceNameMap.clear();
+ }
}
}
diff --git a/framework/lint-baseline.xml b/framework/lint-baseline.xml
index 55c4cfc6c5..a65baa655a 100644
--- a/framework/lint-baseline.xml
+++ b/framework/lint-baseline.xml
@@ -822,7 +822,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java"
- line="6786"
+ line="6800"
column="17"/>
</issue>
@@ -833,7 +833,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java"
- line="8075"
+ line="8089"
column="37"/>
</issue>
@@ -844,7 +844,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java"
- line="8082"
+ line="8096"
column="37"/>
</issue>
@@ -855,7 +855,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java"
- line="8089"
+ line="8103"
column="37"/>
</issue>
@@ -866,7 +866,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java"
- line="12607"
+ line="12652"
column="37"/>
</issue>
@@ -877,7 +877,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java"
- line="12617"
+ line="12662"
column="37"/>
</issue>
@@ -888,7 +888,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java"
- line="12630"
+ line="12675"
column="37"/>
</issue>
@@ -921,7 +921,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pGroup.java"
- line="456"
+ line="468"
column="47"/>
</issue>
@@ -932,40 +932,40 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pGroup.java"
- line="496"
+ line="508"
column="21"/>
</issue>
<issue
id="FlaggedApi"
- message="Method `onStateChanged()` is a flagged API and should be inside an `if (Flags.androidVWifiApi())` check (or annotate the surrounding method `onStateChanged` with `@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) to transfer requirement to caller`)"
- errorLine1=" mExecutor.execute(() -> mListener.onStateChanged(p2pEnabled));"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ message="Method `onP2pStateChanged()` is a flagged API and should be inside an `if (Flags.androidVWifiApi())` check (or annotate the surrounding method `onP2pStateChanged` with `@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) to transfer requirement to caller`)"
+ errorLine1=" mExecutor.execute(() -> mListener.onP2pStateChanged(state));"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1423"
+ line="1484"
column="37"/>
</issue>
<issue
id="FlaggedApi"
message="Method `onDiscoveryStateChanged()` is a flagged API and should be inside an `if (Flags.androidVWifiApi())` check (or annotate the surrounding method `onDiscoveryStateChanged` with `@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) to transfer requirement to caller`)"
- errorLine1=" mExecutor.execute(() -> mListener.onDiscoveryStateChanged(started));"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ errorLine1=" mExecutor.execute(() -> mListener.onDiscoveryStateChanged(state));"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1429"
+ line="1490"
column="37"/>
</issue>
<issue
id="FlaggedApi"
message="Method `onListenStateChanged()` is a flagged API and should be inside an `if (Flags.androidVWifiApi())` check (or annotate the surrounding method `onListenStateChanged` with `@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) to transfer requirement to caller`)"
- errorLine1=" mExecutor.execute(() -> mListener.onListenStateChanged(started));"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ errorLine1=" mExecutor.execute(() -> mListener.onListenStateChanged(state));"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1435"
+ line="1496"
column="37"/>
</issue>
@@ -976,7 +976,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1441"
+ line="1502"
column="37"/>
</issue>
@@ -987,7 +987,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1447"
+ line="1508"
column="37"/>
</issue>
@@ -998,7 +998,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1453"
+ line="1514"
column="37"/>
</issue>
@@ -1009,7 +1009,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1459"
+ line="1520"
column="37"/>
</issue>
@@ -1020,18 +1020,18 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1465"
+ line="1526"
column="37"/>
</issue>
<issue
id="FlaggedApi"
message="Method `onGroupCreationFailed()` is a flagged API and should be inside an `if (Flags.androidVWifiApi())` check (or annotate the surrounding method `onGroupCreationFailed` with `@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) to transfer requirement to caller`)"
- errorLine1=" mExecutor.execute(() -> mListener.onGroupCreationFailed());"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ errorLine1=" mExecutor.execute(() -> mListener.onGroupCreationFailed(reason));"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1471"
+ line="1532"
column="37"/>
</issue>
@@ -1042,7 +1042,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1477"
+ line="1538"
column="37"/>
</issue>
@@ -1053,7 +1053,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1483"
+ line="1544"
column="37"/>
</issue>
@@ -1064,7 +1064,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1489"
+ line="1550"
column="37"/>
</issue>
@@ -1075,7 +1075,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1495"
+ line="1556"
column="37"/>
</issue>
@@ -1086,7 +1086,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="1501"
+ line="1562"
column="37"/>
</issue>
@@ -1097,7 +1097,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="2068"
+ line="2129"
column="74"/>
</issue>
@@ -1108,7 +1108,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="2113"
+ line="2174"
column="74"/>
</issue>
@@ -1119,7 +1119,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="packages/modules/Wifi/framework/java/android/net/wifi/p2p/WifiP2pManager.java"
- line="2163"
+ line="2224"
column="74"/>
</issue>
diff --git a/framework/tests/Android.bp b/framework/tests/Android.bp
index 23763a5515..825fdabf2c 100644
--- a/framework/tests/Android.bp
+++ b/framework/tests/Android.bp
@@ -45,6 +45,7 @@ android_test {
"net-tests-utils",
"net-utils-framework-common",
"truth",
+ "wifi_aconfig_flags_lib",
],
libs: [
diff --git a/framework/tests/src/android/net/wifi/MscsParamsTest.java b/framework/tests/src/android/net/wifi/MscsParamsTest.java
index 701511abde..9d0deab18a 100644
--- a/framework/tests/src/android/net/wifi/MscsParamsTest.java
+++ b/framework/tests/src/android/net/wifi/MscsParamsTest.java
@@ -21,13 +21,9 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
import android.os.Parcel;
-import com.android.modules.utils.build.SdkLevel;
-
-import org.junit.Before;
import org.junit.Test;
public class MscsParamsTest {
@@ -37,11 +33,6 @@ public class MscsParamsTest {
private static final int TEST_USER_PRIORITY_LIMIT = 5;
private static final int TEST_STREAM_TIMEOUT_US = 5550;
- @Before
- public void setUp() {
- assumeTrue(SdkLevel.isAtLeastV());
- }
-
/** Create an MscsParams object with all fields set to the test values. */
private MscsParams createTestMscsParams() {
return new MscsParams.Builder()
diff --git a/framework/tests/src/android/net/wifi/OuiKeyedDataTest.java b/framework/tests/src/android/net/wifi/OuiKeyedDataTest.java
index 0edd3667a7..e640af3d91 100644
--- a/framework/tests/src/android/net/wifi/OuiKeyedDataTest.java
+++ b/framework/tests/src/android/net/wifi/OuiKeyedDataTest.java
@@ -21,13 +21,10 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
import android.os.Parcel;
import android.os.PersistableBundle;
-import com.android.modules.utils.build.SdkLevel;
-
import org.junit.Before;
import org.junit.Test;
@@ -47,7 +44,6 @@ public class OuiKeyedDataTest {
@Before
public void setUp() {
- assumeTrue(SdkLevel.isAtLeastV());
mTestData = createTestBundle();
}
diff --git a/framework/tests/src/android/net/wifi/QosCharacteristicsTest.java b/framework/tests/src/android/net/wifi/QosCharacteristicsTest.java
index 4876fc18c6..2cfd9605ed 100644
--- a/framework/tests/src/android/net/wifi/QosCharacteristicsTest.java
+++ b/framework/tests/src/android/net/wifi/QosCharacteristicsTest.java
@@ -25,13 +25,9 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
import android.os.Parcel;
-import com.android.modules.utils.build.SdkLevel;
-
-import org.junit.Before;
import org.junit.Test;
public class QosCharacteristicsTest {
@@ -48,10 +44,6 @@ public class QosCharacteristicsTest {
private static final int TEST_DELIVERY_RATIO = QosCharacteristics.DELIVERY_RATIO_99;
private static final int TEST_COUNT_EXPONENT = 5;
- @Before
- public void setUp() {
- assumeTrue(SdkLevel.isAtLeastV());
- }
/**
* Get a Builder with the mandatory fields set to the default test values.
diff --git a/framework/tests/src/android/net/wifi/QosPolicyParamsTest.java b/framework/tests/src/android/net/wifi/QosPolicyParamsTest.java
index fe40e2158c..bf053615b8 100644
--- a/framework/tests/src/android/net/wifi/QosPolicyParamsTest.java
+++ b/framework/tests/src/android/net/wifi/QosPolicyParamsTest.java
@@ -20,14 +20,12 @@ package android.net.wifi;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
import android.net.DscpPolicy;
import android.os.Parcel;
import com.android.modules.utils.build.SdkLevel;
-import org.junit.Before;
import org.junit.Test;
import java.net.InetAddress;
@@ -47,11 +45,6 @@ public class QosPolicyParamsTest {
private static final String TEST_SOURCE_ADDRESS = "127.0.0.1";
private static final String TEST_DESTINATION_ADDRESS = "127.0.0.2";
- @Before
- public void setUp() {
- assumeTrue(SdkLevel.isAtLeastU());
- }
-
private InetAddress getInetAddress(String addr) {
try {
return InetAddress.getByName(addr);
diff --git a/framework/tests/src/android/net/wifi/WifiManagerTest.java b/framework/tests/src/android/net/wifi/WifiManagerTest.java
index b18a4f9f3c..54c16f36ba 100644
--- a/framework/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/framework/tests/src/android/net/wifi/WifiManagerTest.java
@@ -30,6 +30,7 @@ import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHA
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.REQUEST_REGISTERED;
import static android.net.wifi.WifiManager.OnWifiActivityEnergyInfoListener;
+import static android.net.wifi.WifiManager.PASSPOINT_HOME_NETWORK;
import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL;
import static android.net.wifi.WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
import static android.net.wifi.WifiManager.STATUS_SUGGESTION_CONNECTION_FAILURE_AUTHENTICATION;
@@ -138,6 +139,7 @@ import androidx.test.filters.SmallTest;
import com.android.modules.utils.HandlerExecutor;
import com.android.modules.utils.build.SdkLevel;
+import com.android.wifi.x.com.android.modules.utils.ParceledListSlice;
import org.junit.Before;
import org.junit.Test;
@@ -778,12 +780,12 @@ public class WifiManagerTest {
List<WifiSsid> expectedSsids = new ArrayList<>();
expectedSsids.add(WifiSsid.fromString("\"TEST_SSID\""));
mWifiManager.setSsidsAllowlist(new ArraySet<>(expectedSsids));
- verify(mWifiService).setSsidsAllowlist(any(), eq(expectedSsids));
+ verify(mWifiService).setSsidsAllowlist(any(),
+ argThat(a -> a.getList().equals(expectedSsids)));
// test empty set
- mWifiManager.setSsidsAllowlist(Collections.EMPTY_SET);
- verify(mWifiService).setSsidsAllowlist(any(),
- eq(Collections.EMPTY_LIST));
+ mWifiManager.setSsidsAllowlist(Collections.emptySet());
+ verify(mWifiService).setSsidsAllowlist(any(), argThat(a -> a.getList().isEmpty()));
}
/**
@@ -2367,16 +2369,20 @@ public class WifiManagerTest {
*/
@Test
public void testGetAllMatchingWifiConfigs() throws Exception {
- Map<String, List<ScanResult>> passpointProfiles = new HashMap<>();
- passpointProfiles.put("www.test.com_987a69bca26", new ArrayList<>());
+ Map<String, Map<Integer, List<ScanResult>>> passpointProfiles = new HashMap<>();
+ Map<Integer, List<ScanResult>> matchingResults = new HashMap<>();
+ matchingResults.put(PASSPOINT_HOME_NETWORK, new ArrayList<>());
+ passpointProfiles.put("www.test.com_987a69bca26", matchingResults);
when(mWifiService.getAllMatchingPasspointProfilesForScanResults(
- any(List.class))).thenReturn(passpointProfiles);
+ any())).thenReturn(passpointProfiles);
+ when(mWifiService.getWifiConfigsForPasspointProfiles(any()))
+ .thenReturn(new ParceledListSlice<>(Collections.emptyList()));
InOrder inOrder = inOrder(mWifiService);
mWifiManager.getAllMatchingWifiConfigs(new ArrayList<>());
- inOrder.verify(mWifiService).getAllMatchingPasspointProfilesForScanResults(any(List.class));
- inOrder.verify(mWifiService).getWifiConfigsForPasspointProfiles(any(List.class));
+ inOrder.verify(mWifiService).getAllMatchingPasspointProfilesForScanResults(any());
+ inOrder.verify(mWifiService).getWifiConfigsForPasspointProfiles(any());
}
/**
@@ -2387,7 +2393,7 @@ public class WifiManagerTest {
public void testGetMatchingOsuProviders() throws Exception {
mWifiManager.getMatchingOsuProviders(new ArrayList<>());
- verify(mWifiService).getMatchingOsuProviders(any(List.class));
+ verify(mWifiService).getMatchingOsuProviders(any());
}
/**
@@ -2398,16 +2404,16 @@ public class WifiManagerTest {
@Test
public void addGetRemoveNetworkSuggestions() throws Exception {
List<WifiNetworkSuggestion> testList = new ArrayList<>();
- when(mWifiService.addNetworkSuggestions(any(List.class), anyString(),
+ when(mWifiService.addNetworkSuggestions(any(), anyString(),
nullable(String.class))).thenReturn(STATUS_NETWORK_SUGGESTIONS_SUCCESS);
- when(mWifiService.removeNetworkSuggestions(any(List.class), anyString(), anyInt()))
+ when(mWifiService.removeNetworkSuggestions(any(), anyString(), anyInt()))
.thenReturn(STATUS_NETWORK_SUGGESTIONS_SUCCESS);
when(mWifiService.getNetworkSuggestions(anyString()))
- .thenReturn(testList);
+ .thenReturn(new ParceledListSlice<>(testList));
assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiManager.addNetworkSuggestions(testList));
- verify(mWifiService).addNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME),
+ verify(mWifiService).addNetworkSuggestions(any(), eq(TEST_PACKAGE_NAME),
nullable(String.class));
assertEquals(testList, mWifiManager.getNetworkSuggestions());
@@ -2415,17 +2421,17 @@ public class WifiManagerTest {
assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiManager.removeNetworkSuggestions(new ArrayList<>()));
- verify(mWifiService).removeNetworkSuggestions(anyList(), eq(TEST_PACKAGE_NAME),
+ verify(mWifiService).removeNetworkSuggestions(any(), eq(TEST_PACKAGE_NAME),
eq(ACTION_REMOVE_SUGGESTION_DISCONNECT));
}
@Test
public void testRemoveNetworkSuggestionWithAction() throws Exception {
- when(mWifiService.removeNetworkSuggestions(anyList(), anyString(), anyInt()))
+ when(mWifiService.removeNetworkSuggestions(any(), anyString(), anyInt()))
.thenReturn(STATUS_NETWORK_SUGGESTIONS_SUCCESS);
assertEquals(STATUS_NETWORK_SUGGESTIONS_SUCCESS, mWifiManager
.removeNetworkSuggestions(new ArrayList<>(), ACTION_REMOVE_SUGGESTION_LINGER));
- verify(mWifiService).removeNetworkSuggestions(any(List.class),
+ verify(mWifiService).removeNetworkSuggestions(any(),
eq(TEST_PACKAGE_NAME), eq(ACTION_REMOVE_SUGGESTION_LINGER));
}
@@ -3314,8 +3320,8 @@ public class WifiManagerTest {
List<WifiConfiguration> testResults = new ArrayList<>();
testResults.add(new WifiConfiguration());
- when(mWifiService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any(List.class)))
- .thenReturn(testResults);
+ when(mWifiService.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any()))
+ .thenReturn(new ParceledListSlice<>(testResults));
assertEquals(testResults, mWifiManager
.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>()));
}
@@ -3402,7 +3408,7 @@ public class WifiManagerTest {
mWifiManager.addCustomDhcpOptions(
WifiSsid.fromString(TEST_SSID), TEST_OUI, new ArrayList<DhcpOption>());
verify(mWifiService).addCustomDhcpOptions(
- WifiSsid.fromString(TEST_SSID), TEST_OUI, new ArrayList<DhcpOption>());
+ eq(WifiSsid.fromString(TEST_SSID)), eq(TEST_OUI), any());
}
/**
diff --git a/framework/tests/src/android/net/wifi/WifiUriParserTest.java b/framework/tests/src/android/net/wifi/WifiUriParserTest.java
index 396c677676..a01b6b755e 100644
--- a/framework/tests/src/android/net/wifi/WifiUriParserTest.java
+++ b/framework/tests/src/android/net/wifi/WifiUriParserTest.java
@@ -22,12 +22,18 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
import androidx.test.filters.SmallTest;
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+
import com.google.common.collect.ImmutableList;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
+import org.mockito.MockitoSession;
import java.util.Collections;
import java.util.List;
@@ -42,6 +48,26 @@ public class WifiUriParserTest {
private static final String TEST_DPP_URI = "DPP:C:81/1;I:" + TEST_DPP_INFORMATION
+ ";K:" + TEST_DPP_PUBLIC_KEY + ";;";
+ private MockitoSession mSession;
+
+ @Before
+ public void setUp() throws Exception {
+ mSession = ExtendedMockito.mockitoSession()
+ .initMocks(this)
+ .mockStatic(WifiUriParser.class, CALLS_REAL_METHODS)
+ .startMocking();
+ }
+
+ /**
+ * Called after each test
+ */
+ @After
+ public void cleanup() {
+ if (mSession != null) {
+ mSession.finishMocking();
+ }
+ }
+
private void verifyZxParsing(
UriParserResults uri,
String expectedSSID,
@@ -66,6 +92,15 @@ public class WifiUriParserTest {
@Test
public void testZxParsing() {
+ ExtendedMockito.when(WifiUriParser.mockableIsFlagNewUriParsingForEscapeCharacterEnabled())
+ .thenReturn(false);
+ testZxParsing(false);
+ ExtendedMockito.when(WifiUriParser.mockableIsFlagNewUriParsingForEscapeCharacterEnabled())
+ .thenReturn(true);
+ testZxParsing(true);
+ }
+
+ public void testZxParsing(boolean isNewParserSupported) {
// Test no password
List<SecurityParams> expectedSecurityParamsList =
ImmutableList.of(
@@ -88,7 +123,34 @@ public class WifiUriParserTest {
expectedSecurityParamsList,
null,
false);
+ // Unknown prefix tag & extra ; should keep work. (either new or old parsing)
+ uri = WifiUriParser.parseUri("WIFI:SSS:456 ;; S: test 123\\;; T:nopass");
+ verifyZxParsing(
+ uri,
+ "\" test 123;\"",
+ expectedSecurityParamsList,
+ null,
+ false);
+ if (isNewParserSupported) {
+ // The \\ in the end of ssid but it should work.
+ uri = WifiUriParser.parseUri("WIFI:S:testAbC\\\\; T:nopass");
+ verifyZxParsing(
+ uri,
+ "\"testAbC\\\"",
+ expectedSecurityParamsList,
+ null,
+ false);
+
+ // The \; and \\ in the end of ssid but it should work.
+ uri = WifiUriParser.parseUri("WIFI:S:test 123\\;\\\\\\;; T:nopass");
+ verifyZxParsing(
+ uri,
+ "\"test 123;\\;\"",
+ expectedSecurityParamsList,
+ null,
+ false);
+ }
// Test WEP
expectedSecurityParamsList =
ImmutableList.of(
@@ -101,7 +163,7 @@ public class WifiUriParserTest {
expectedSecurityParamsList,
"\"somepasswo#%^**123rd\"",
true);
- // invalid code but it should work.
+ // invalid code (space before pre-fix) but it should work.
uri = WifiUriParser.parseUri("WIFI:S:reallyLONGone;T:WEP; P:somepassword");
verifyZxParsing(
uri,
@@ -110,18 +172,30 @@ public class WifiUriParserTest {
"\"somepassword\"",
true);
- // Test WPA
+ // Test WPA & space as part of SSID and passphrase.
expectedSecurityParamsList =
ImmutableList.of(
SecurityParams.createSecurityParamsBySecurityType(
WifiConfiguration.SECURITY_TYPE_PSK));
- uri = WifiUriParser.parseUri("WIFI:S:anotherone;T:WPA;P:3#=3j9asicla");
+ uri = WifiUriParser.parseUri("WIFI:S:another one;T:WPA;P:3#=3j9 asicla");
verifyZxParsing(
uri,
- "\"anotherone\"",
+ "\"another one\"",
expectedSecurityParamsList,
- "\"3#=3j9asicla\"",
+ "\"3#=3j9 asicla\"",
false);
+
+ if (isNewParserSupported) {
+ // The " in the start and end of ssid but it should work.
+ uri = WifiUriParser.parseUri("WIFI:S:\"\"\"\"; T:WPA; P:\"\"");
+ verifyZxParsing(
+ uri,
+ "\"\"\"\"\"\"",
+ expectedSecurityParamsList,
+ "\"\"\"\"",
+ false);
+ }
+
// invalid code but it should work.
uri = WifiUriParser.parseUri("WIFI: S:anotherone;T:WPA;P:abcdefghihklmn");
verifyZxParsing(
@@ -155,9 +229,9 @@ public class WifiUriParserTest {
uri = WifiUriParser.parseUri("WIFI:T:ADB;S:myname;P:mypass;;");
verifyZxParsing(
uri,
- "\"myname\"",
+ "myname",
Collections.emptyList(),
- "\"mypass\"",
+ "mypass",
false);
// Test transition disable value
expectedSecurityParamsList =
diff --git a/framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java b/framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java
index 4a485c06ab..5a51ac6e5f 100644
--- a/framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java
+++ b/framework/tests/src/android/net/wifi/util/ScanResultUtilTest.java
@@ -363,6 +363,33 @@ public class ScanResultUtilTest {
}
/**
+ * Test that a network configured in WPA3-Compatibility mode is detected as WPA3-transition mode
+ */
+ @Test
+ public void testWPA3CompatibilityModeNetwork() {
+ final String ssid = "WPA3-Compatibility";
+ String caps = "[WPA2-PSK-CCMP][RSN-PSK-CCMP][RSN-SAE-CCMP][MFPC][RSNO]";
+
+ ScanResult input = new ScanResult.Builder(WifiSsid.fromUtf8Text(ssid),
+ "ab:cd:01:ef:45:89")
+ .setHessid(1245)
+ .setCaps(caps)
+ .setRssi(-78)
+ .setFrequency(2450)
+ .setTsf(1025)
+ .setDistanceCm(22)
+ .setDistanceSdCm(33)
+ .setIs80211McRTTResponder(true)
+ .build();
+
+ input.informationElements = new InformationElement[] {
+ createIE(InformationElement.EID_SSID, ssid.getBytes(StandardCharsets.UTF_8))
+ };
+
+ assertTrue(ScanResultUtil.isScanResultForPskSaeTransitionNetwork(input));
+ }
+
+ /**
* Test that a PSK network is not detected as transition mode
*/
@Test
diff --git a/framework/tests/src/android/net/wifi/util/WifiResourceCacheTest.java b/framework/tests/src/android/net/wifi/util/WifiResourceCacheTest.java
index 54f9add266..f1a7578211 100644
--- a/framework/tests/src/android/net/wifi/util/WifiResourceCacheTest.java
+++ b/framework/tests/src/android/net/wifi/util/WifiResourceCacheTest.java
@@ -16,91 +16,168 @@
package android.net.wifi.util;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.res.Resources;
import android.net.wifi.WifiContext;
+import android.text.TextUtils;
import androidx.test.filters.SmallTest;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
@SmallTest
public class WifiResourceCacheTest {
private static final int TEST_ID = 12345;
private static final String TEST_NAME = "test_name";
private static final int VALUE_1 = 10;
private static final int VALUE_2 = 20;
+ private static final String STRING_1 = "string_1";
+ private static final String STRING_2 = "string_2";
+ private static final int[] INT_ARRAY_1 = {1, 2, 3, 4, 5};
+ private static final int[] INT_ARRAY_2 = {5, 4, 3, 2, 1};
+ private static final String[] STRINGS_1 = {"1", "2", "3", "4", "5"};
+ private static final String[] STRINGS_2 = {"5", "4", "3", "2", "1"};
@Mock WifiContext mWifiContext;
@Mock Resources mResources;
private WifiResourceCache mWifiResourceCache;
+ @Captor
+ ArgumentCaptor<Integer> mIntegerArgumentCaptor;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
when(mWifiContext.getResources()).thenReturn(mResources);
mWifiResourceCache = new WifiResourceCache(mWifiContext);
+ doAnswer(v -> String.valueOf(v.getArguments()[0])).when(mResources)
+ .getResourceEntryName(anyInt());
+ }
+
+ @After
+ public void teardown() {
+ StringWriter sw = new StringWriter();
+ mWifiResourceCache.dump(new PrintWriter(sw));
+ assertFalse(TextUtils.isEmpty(sw.toString()));
+ Mockito.framework().clearInlineMocks();
}
@Test
public void testGetBooleanResource() {
when(mResources.getBoolean(TEST_ID)).thenReturn(true);
- assertTrue(mWifiResourceCache.getBoolean(TEST_ID, TEST_NAME));
- assertTrue(mWifiResourceCache.getBoolean(TEST_ID, TEST_NAME));
+ assertTrue(mWifiResourceCache.getBoolean(TEST_ID));
+ assertTrue(mWifiResourceCache.getBoolean(TEST_ID));
verify(mResources).getBoolean(TEST_ID);
}
@Test
public void testGetIntegerResource() {
when(mResources.getInteger(TEST_ID)).thenReturn(VALUE_1);
- assertEquals(VALUE_1, mWifiResourceCache.getInteger(TEST_ID, TEST_NAME));
- assertEquals(VALUE_1, mWifiResourceCache.getInteger(TEST_ID, TEST_NAME));
+ assertEquals(VALUE_1, mWifiResourceCache.getInteger(TEST_ID));
+ assertEquals(VALUE_1, mWifiResourceCache.getInteger(TEST_ID));
verify(mResources).getInteger(TEST_ID);
}
@Test
+ public void testGetStringResource() {
+ when(mResources.getString(TEST_ID)).thenReturn(STRING_1);
+ assertEquals(STRING_1, mWifiResourceCache.getString(TEST_ID));
+ assertEquals(STRING_1, mWifiResourceCache.getString(TEST_ID));
+ verify(mResources).getString(TEST_ID);
+ }
+
+ @Test
public void testOverrideBooleanResource() {
+ mWifiResourceCache.restoreBooleanValue(String.valueOf(TEST_ID));
when(mResources.getBoolean(TEST_ID)).thenReturn(true);
- assertTrue(mWifiResourceCache.getBoolean(TEST_ID, TEST_NAME));
- mWifiResourceCache.overrideBooleanValue(TEST_NAME, false);
- assertFalse(mWifiResourceCache.getBoolean(TEST_ID, TEST_NAME));
- mWifiResourceCache.restoreBooleanValue(TEST_NAME);
- assertTrue(mWifiResourceCache.getBoolean(TEST_ID, TEST_NAME));
+ assertTrue(mWifiResourceCache.getBoolean(TEST_ID));
+ mWifiResourceCache.overrideBooleanValue(String.valueOf(TEST_ID), false);
+ assertFalse(mWifiResourceCache.getBoolean(TEST_ID));
+ mWifiResourceCache.restoreBooleanValue(String.valueOf(TEST_ID));
+ assertTrue(mWifiResourceCache.getBoolean(TEST_ID));
verify(mResources, times(2)).getBoolean(TEST_ID);
}
@Test
public void testOverrideIntegerResource() {
+ mWifiResourceCache.restoreIntegerValue(String.valueOf(TEST_ID));
when(mResources.getInteger(TEST_ID)).thenReturn(VALUE_1);
- assertEquals(VALUE_1, mWifiResourceCache.getInteger(TEST_ID, TEST_NAME));
- mWifiResourceCache.overrideIntegerValue(TEST_NAME, VALUE_2);
- assertEquals(VALUE_2, mWifiResourceCache.getInteger(TEST_ID, TEST_NAME));
- mWifiResourceCache.restoreIntegerValue(TEST_NAME);
- assertEquals(VALUE_1, mWifiResourceCache.getInteger(TEST_ID, TEST_NAME));
+ assertEquals(VALUE_1, mWifiResourceCache.getInteger(TEST_ID));
+ mWifiResourceCache.overrideIntegerValue(String.valueOf(TEST_ID), VALUE_2);
+ assertEquals(VALUE_2, mWifiResourceCache.getInteger(TEST_ID));
+ mWifiResourceCache.restoreIntegerValue(String.valueOf(TEST_ID));
+ assertEquals(VALUE_1, mWifiResourceCache.getInteger(TEST_ID));
verify(mResources, times(2)).getInteger(TEST_ID);
}
@Test
+ public void testOverrideStringResource() {
+ mWifiResourceCache.restoreStringValue(String.valueOf(TEST_ID));
+ when(mResources.getString(TEST_ID)).thenReturn(STRING_1);
+ assertEquals(STRING_1, mWifiResourceCache.getString(TEST_ID));
+ mWifiResourceCache.overrideStringValue(String.valueOf(TEST_ID), STRING_2);
+ assertEquals(STRING_2, mWifiResourceCache.getString(TEST_ID));
+ mWifiResourceCache.restoreStringValue(String.valueOf(TEST_ID));
+ assertEquals(STRING_1, mWifiResourceCache.getString(TEST_ID));
+ verify(mResources, times(2)).getString(TEST_ID);
+ }
+
+ @Test
+ public void testOverrideIntArrayResource() {
+ mWifiResourceCache.restoreIntArrayValue(String.valueOf(TEST_ID));
+ when(mResources.getIntArray(TEST_ID)).thenReturn(INT_ARRAY_1);
+ assertEquals(INT_ARRAY_1, mWifiResourceCache.getIntArray(TEST_ID));
+ mWifiResourceCache.overrideIntArrayValue(String.valueOf(TEST_ID), INT_ARRAY_2);
+ assertArrayEquals(INT_ARRAY_2, mWifiResourceCache.getIntArray(TEST_ID));
+ mWifiResourceCache.restoreIntArrayValue(String.valueOf(TEST_ID));
+ mWifiResourceCache.restoreIntArrayValue(String.valueOf(TEST_ID));
+ assertEquals(INT_ARRAY_1, mWifiResourceCache.getIntArray(TEST_ID));
+ verify(mResources, times(2)).getIntArray(TEST_ID);
+ }
+
+ @Test
+ public void testOverrideStringArrayResource() {
+ mWifiResourceCache.restoreStringArrayValue(String.valueOf(TEST_ID));
+ when(mResources.getStringArray(TEST_ID)).thenReturn(STRINGS_1);
+ assertEquals(STRINGS_1, mWifiResourceCache.getStringArray(TEST_ID));
+ mWifiResourceCache.overrideStringArrayValue(String.valueOf(TEST_ID), STRINGS_2);
+ assertEquals(STRINGS_2, mWifiResourceCache.getStringArray(TEST_ID));
+ mWifiResourceCache.restoreStringArrayValue(String.valueOf(TEST_ID));
+ assertEquals(STRINGS_1, mWifiResourceCache.getStringArray(TEST_ID));
+ verify(mResources, times(2)).getStringArray(TEST_ID);
+ }
+
+
+ @Test
public void testReset() {
when(mResources.getBoolean(TEST_ID)).thenReturn(true);
- when(mResources.getInteger(TEST_ID)).thenReturn(VALUE_1);
- assertTrue(mWifiResourceCache.getBoolean(TEST_ID, TEST_NAME));
- assertEquals(VALUE_1, mWifiResourceCache.getInteger(TEST_ID, TEST_NAME));
- mWifiResourceCache.overrideBooleanValue(TEST_NAME, false);
- mWifiResourceCache.overrideIntegerValue(TEST_NAME, VALUE_2);
- assertEquals(VALUE_2, mWifiResourceCache.getInteger(TEST_ID, TEST_NAME));
- assertFalse(mWifiResourceCache.getBoolean(TEST_ID, TEST_NAME));
+ when(mResources.getInteger(TEST_ID + 1)).thenReturn(VALUE_1);
+ assertTrue(mWifiResourceCache.getBoolean(TEST_ID));
+ assertEquals(VALUE_1, mWifiResourceCache.getInteger(TEST_ID + 1));
+ mWifiResourceCache.overrideBooleanValue(String.valueOf(TEST_ID), false);
+ mWifiResourceCache.overrideIntegerValue(String.valueOf(TEST_ID + 1), VALUE_2);
+ assertEquals(VALUE_2, mWifiResourceCache.getInteger(TEST_ID + 1));
+ assertFalse(mWifiResourceCache.getBoolean(TEST_ID));
mWifiResourceCache.reset();
- assertTrue(mWifiResourceCache.getBoolean(TEST_ID, TEST_NAME));
- assertEquals(VALUE_1, mWifiResourceCache.getInteger(TEST_ID, TEST_NAME));
+ assertTrue(mWifiResourceCache.getBoolean(TEST_ID));
+ assertEquals(VALUE_1, mWifiResourceCache.getInteger(TEST_ID + 1));
verify(mResources, times(2)).getBoolean(TEST_ID);
- verify(mResources, times(2)).getInteger(TEST_ID);
+ verify(mResources, times(2)).getInteger(TEST_ID + 1);
}
}
diff --git a/service/Android.bp b/service/Android.bp
index 5528b0ce3e..4c1ec37e0e 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -96,7 +96,7 @@ java_library {
"android.hardware.wifi.hostapd-V1.2-java",
"android.hardware.wifi.hostapd-V1.3-java",
// AIDL supplicant implementation
- "android.hardware.wifi.supplicant-V3-java",
+ "android.hardware.wifi.supplicant-V4-java",
// HIDL supplicant implementation
"android.hardware.wifi.supplicant-V1.0-java",
"android.hardware.wifi.supplicant-V1.1-java",
diff --git a/service/ServiceWifiResources/res/values-fr-rCA-feminine/strings.xml b/service/ServiceWifiResources/res/values-fr-rCA-feminine/strings.xml
new file mode 100644
index 0000000000..e90236a14b
--- /dev/null
+++ b/service/ServiceWifiResources/res/values-fr-rCA-feminine/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="wifi_eap_error_message_code_32763_carrier_overrides">
+ <item msgid="591026649262091217">"<xliff:g id="CARRIER_ID_PREFIX">:::1839:::</xliff:g><xliff:g id="SSID">%1$s</xliff:g> : vous êtes déjà connectée à Verizon Wi-Fi Access. (Erreur = 32763)"</item>
+ </string-array>
+ <string name="wifi_ca_cert_dialog_preT_continue_text" msgid="9118713368838029797">"Rester connectée"</string>
+</resources>
diff --git a/service/ServiceWifiResources/res/values-fr-rCA-masculine/strings.xml b/service/ServiceWifiResources/res/values-fr-rCA-masculine/strings.xml
new file mode 100644
index 0000000000..6d357d7e41
--- /dev/null
+++ b/service/ServiceWifiResources/res/values-fr-rCA-masculine/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="wifi_eap_error_message_code_32763_carrier_overrides">
+ <item msgid="591026649262091217">"<xliff:g id="CARRIER_ID_PREFIX">:::1839:::</xliff:g><xliff:g id="SSID">%1$s</xliff:g> : vous êtes déjà connecté à Verizon Wi-Fi Access. (Erreur = 32763)"</item>
+ </string-array>
+ <string name="wifi_ca_cert_dialog_preT_continue_text" msgid="9118713368838029797">"Rester connecté"</string>
+</resources>
diff --git a/service/ServiceWifiResources/res/values-fr-rCA-neuter/strings.xml b/service/ServiceWifiResources/res/values-fr-rCA-neuter/strings.xml
new file mode 100644
index 0000000000..1c3e4f2f68
--- /dev/null
+++ b/service/ServiceWifiResources/res/values-fr-rCA-neuter/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="wifi_eap_error_message_code_32763_carrier_overrides">
+ <item msgid="591026649262091217">"<xliff:g id="CARRIER_ID_PREFIX">:::1839:::</xliff:g><xliff:g id="SSID">%1$s</xliff:g> : votre connexion à Verizon Wi-Fi Access est déjà établie. (Erreur = 32763)"</item>
+ </string-array>
+ <string name="wifi_ca_cert_dialog_preT_continue_text" msgid="9118713368838029797">"Rester connecté·e"</string>
+</resources>
diff --git a/service/ServiceWifiResources/res/values/config.xml b/service/ServiceWifiResources/res/values/config.xml
index ab73f3ac90..aaaa4ab5d6 100644
--- a/service/ServiceWifiResources/res/values/config.xml
+++ b/service/ServiceWifiResources/res/values/config.xml
@@ -216,6 +216,11 @@
<!-- boolean indicating whether or not to auto-upgrade band setting configuration to dual bands during cloud configuration restore when device supported -->
<bool translatable="false" name ="config_wifiSoftapAutoUpgradeToBridgedConfigWhenSupported">true</bool>
+ <!-- boolean indicating whether or not to temporarily auto-upgrade tethering softap to
+ 2.4 + 5GHz Bridged if it is currently available and the usable configured bands only
+ contain 2.4 or 5Ghz.-->
+ <bool translatable="false" name ="config_wifiSoftapUpgradeTetheredTo2g5gBridgedIfBandsAreSubset">false</bool>
+
<!-- List of allowed channels in 2GHz band for softap. If the device doesn't want to restrict
channels this should be empty. Values is a comma separated channel string and/or channel
range string like '1-6,11'. -->
@@ -1099,6 +1104,14 @@
it as low priority when disconnected, allowing it to be deleted to create other
interfaces. A negative value disables this behavior. -->
<integer translatable="false" name="config_disconnectedP2pIfaceLowPriorityTimeoutMs">-1</integer>
+ <!-- list of package names that the framework will allow to use P2P/Aware concurrency. If this
+ list is empty, then all packages are allowed -->
+ <string-array translatable="false" name="config_wifiP2pAwareConcurrencyAllowlist">
+ <!-- Below is a sample configuration for this list:
+ <item>com.company1.example.test.name1</item>
+ <item>com.company2.example.test.name2</item>
+ -->
+ </string-array>
<!-- boolean indicating whether the Easy Connect (DPP) AKM is supported -->
<bool translatable="false" name ="config_wifiDppAkmSupported">false</bool>
<!-- Indicates the number of octets to mask for each BSSID in the SecurityLog output.
@@ -1342,4 +1355,27 @@
-->
<bool translatable="false" name="config_wifiTwtSupported">true</bool>
+ <!-- Boolean indicating whether the WiFi framework network selection should set the target BSSID. -->
+ <bool translatable="false" name="config_wifiNetworkSelectionSetTargetBssid">false</bool>
+
+ <!-- Array containing carrier IDs whose networks should not auto-connect upon initial discovery.
+ These networks are eligible to become network selection candidates if they still appear in
+ the scan results after the delay period has passed. Carriers who have requested this
+ feature are included in the array by default.
+ -->
+ <integer-array translatable="false" name="config_wifiDelayedSelectionCarrierIds">
+ <item>2032</item>
+ </integer-array>
+
+ <!-- Delay time in milliseconds for delayed carrier network selection.
+ See also config_wifiDelayedSelectionCarrierIds.
+ -->
+ <integer translatable="false" name="config_wifiDelayedCarrierSelectionTimeMs">90000</integer>
+
+ <!-- Boolean indicating whether the device supports Wi-Fi Alliance WPA3 Specification
+ version 3.3 Section 14 - RSN Overriding.
+ Enabling this config allows framework to parse the RSNO IE and RSNO2 IE.
+ Only enable this flag if Supplicant and driver/firmware supports RSN Overriding. otherwise
+ the connection may fail or downgrade to WPA2 -->
+ <bool translatable="false" name ="config_wifiRsnOverridingEnabled">false</bool>
</resources>
diff --git a/service/ServiceWifiResources/res/values/overlayable.xml b/service/ServiceWifiResources/res/values/overlayable.xml
index e736668dd1..d499e366a2 100644
--- a/service/ServiceWifiResources/res/values/overlayable.xml
+++ b/service/ServiceWifiResources/res/values/overlayable.xml
@@ -83,6 +83,7 @@
<item type="bool" name="config_wifiSoftapResetAutoShutdownTimerConfig" />
<item type="bool" name="config_wifiSoftapResetMaxClientSettingConfig" />
<item type="bool" name="config_wifiSoftapAutoUpgradeToBridgedConfigWhenSupported" />
+ <item type="bool" name="config_wifiSoftapUpgradeTetheredTo2g5gBridgedIfBandsAreSubset" />
<item type="string" name="config_wifiSoftap2gChannelList" />
<item type="string" name="config_wifiSoftap5gChannelList" />
<item type="string" name="config_wifiSoftap6gChannelList" />
@@ -305,6 +306,7 @@
<item type="array" name="config_wifiExcludedFromUserApprovalForD2dInterfacePriority" />
<item type="bool" name="config_wifiUserApprovalNotRequireForDisconnectedP2p" />
<item type="integer" name="config_disconnectedP2pIfaceLowPriorityTimeoutMs" />
+ <item type="array" name="config_wifiP2pAwareConcurrencyAllowlist" />
<item type="bool" name="config_wifiNetworkCentricQosPolicyFeatureEnabled" />
<item type="bool" name="config_wifiApplicationCentricQosPolicyFeatureEnabled" />
<item type="string" name="config_wifiDriverWorldModeCountryCode" />
@@ -344,7 +346,11 @@
<item type="array" name="config_wifiTwtBlockedOuiList" />
<item type="bool" name="config_wifiSoftApSingleLinkMloInBridgedModeSupported" />
<item type="bool" name="config_wifiTwtSupported" />
+ <item type="bool" name="config_wifiNetworkSelectionSetTargetBssid" />
<item type="bool" name="config_wifiWepAllowedControlSupported" />
+ <item type="array" name="config_wifiDelayedSelectionCarrierIds" />
+ <item type="integer" name="config_wifiDelayedCarrierSelectionTimeMs" />
+ <item type="bool" name="config_wifiRsnOverridingEnabled" />
<!-- Params from config.xml that can be overlayed -->
diff --git a/service/java/com/android/server/wifi/ActiveModeWarden.java b/service/java/com/android/server/wifi/ActiveModeWarden.java
index fc6392c949..6b6b5c00f5 100644
--- a/service/java/com/android/server/wifi/ActiveModeWarden.java
+++ b/service/java/com/android/server/wifi/ActiveModeWarden.java
@@ -51,10 +51,12 @@ import android.net.wifi.SoftApCapability;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApState;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.DeviceMobilityState;
import android.net.wifi.WifiScanner;
+import android.net.wifi.util.WifiResourceCache;
import android.os.BatteryStatsManager;
import android.os.Build;
import android.os.Handler;
@@ -127,7 +129,7 @@ public class ActiveModeWarden {
private final WifiInjector mWifiInjector;
private final Looper mLooper;
private final Handler mHandler;
- private final Context mContext;
+ private final WifiContext mContext;
private final WifiDiagnostics mWifiDiagnostics;
private final WifiSettingsStore mSettingsStore;
private final FrameworkFacade mFacade;
@@ -191,6 +193,7 @@ public class ActiveModeWarden {
private final AtomicInteger mWifiState = new AtomicInteger(WIFI_STATE_DISABLED);
private ContentObserver mSatelliteModeContentObserver;
+ private final WifiResourceCache mResourceCache;
/**
* Method that allows the active ClientModeManager to set the wifi state that is
@@ -380,7 +383,7 @@ public class ActiveModeWarden {
DefaultClientModeManager defaultClientModeManager,
BatteryStatsManager batteryStatsManager,
WifiDiagnostics wifiDiagnostics,
- Context context,
+ WifiContext context,
WifiSettingsStore settingsStore,
FrameworkFacade facade,
WifiPermissionsUtil wifiPermissionsUtil,
@@ -392,6 +395,7 @@ public class ActiveModeWarden {
mLooper = looper;
mHandler = new Handler(looper);
mContext = context;
+ mResourceCache = mContext.getResourceCache();
mWifiDiagnostics = wifiDiagnostics;
mSettingsStore = settingsStore;
mFacade = facade;
@@ -601,7 +605,7 @@ public class ActiveModeWarden {
return false;
}
if (clientRole == ROLE_CLIENT_LOCAL_ONLY) {
- if (!mContext.getResources().getBoolean(
+ if (!mResourceCache.getBoolean(
R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) {
return false;
}
@@ -614,13 +618,13 @@ public class ActiveModeWarden {
packageName, Build.VERSION_CODES.S, uid);
}
if (clientRole == ROLE_CLIENT_SECONDARY_TRANSIENT) {
- return mContext.getResources().getBoolean(
+ return mResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled);
}
if (clientRole == ROLE_CLIENT_SECONDARY_LONG_LIVED) {
- return mContext.getResources().getBoolean(
+ return mResourceCache.getBoolean(
R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled)
- || mContext.getResources().getBoolean(
+ || mResourceCache.getBoolean(
R.bool.config_wifiMultiStaMultiInternetConcurrencyEnabled);
}
Log.e(TAG, "Unrecognized role=" + clientRole);
@@ -640,7 +644,7 @@ public class ActiveModeWarden {
*/
public boolean isStaStaConcurrencySupportedForLocalOnlyConnections() {
return mWifiNative.isStaStaConcurrencySupported()
- && mContext.getResources().getBoolean(
+ && mResourceCache.getBoolean(
R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled);
}
@@ -650,7 +654,7 @@ public class ActiveModeWarden {
*/
public boolean isStaStaConcurrencySupportedForMbb() {
return mWifiNative.isStaStaConcurrencySupported()
- && mContext.getResources().getBoolean(
+ && mResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled);
}
@@ -660,7 +664,7 @@ public class ActiveModeWarden {
*/
public boolean isStaStaConcurrencySupportedForRestrictedConnections() {
return mWifiNative.isStaStaConcurrencySupported()
- && mContext.getResources().getBoolean(
+ && mResourceCache.getBoolean(
R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled);
}
@@ -670,7 +674,7 @@ public class ActiveModeWarden {
*/
public boolean isStaStaConcurrencySupportedForMultiInternet() {
return mWifiNative.isStaStaConcurrencySupported()
- && mContext.getResources().getBoolean(
+ && mResourceCache.getBoolean(
R.bool.config_wifiMultiStaMultiInternetConcurrencyEnabled);
}
@@ -706,7 +710,7 @@ public class ActiveModeWarden {
emergencyCallbackModeChanged(emergencyMode);
}
}, new IntentFilter(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED));
- boolean trackEmergencyCallState = mContext.getResources().getBoolean(
+ boolean trackEmergencyCallState = mResourceCache.getBoolean(
R.bool.config_wifi_turn_off_during_emergency_call);
if (trackEmergencyCallState) {
mContext.registerReceiver(new BroadcastReceiver() {
@@ -1490,16 +1494,16 @@ public class ActiveModeWarden {
pw.println("STA + STA Concurrency Supported: " + isStaStaConcurrencySupported);
if (isStaStaConcurrencySupported) {
pw.println(" MBB use-case enabled: "
- + mContext.getResources().getBoolean(
+ + mResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled));
pw.println(" Local only use-case enabled: "
- + mContext.getResources().getBoolean(
+ + mResourceCache.getBoolean(
R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled));
pw.println(" Restricted use-case enabled: "
- + mContext.getResources().getBoolean(
+ + mResourceCache.getBoolean(
R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled));
pw.println(" Multi internet use-case enabled: "
- + mContext.getResources().getBoolean(
+ + mResourceCache.getBoolean(
R.bool.config_wifiMultiStaMultiInternetConcurrencyEnabled));
}
pw.println("STA + AP Concurrency Supported: " + mWifiNative.isStaApConcurrencySupported());
@@ -1743,7 +1747,8 @@ public class ActiveModeWarden {
boolean scanEnabled = hasAnyClientModeManager();
boolean scanningForHiddenNetworksEnabled;
- if (mContext.getResources().getBoolean(R.bool.config_wifiScanHiddenNetworksScanOnlyMode)) {
+ if (mResourceCache
+ .getBoolean(R.bool.config_wifiScanHiddenNetworksScanOnlyMode)) {
scanningForHiddenNetworksEnabled = hasAnyClientModeManager();
} else {
scanningForHiddenNetworksEnabled = hasAnyClientModeManagerInConnectivityRole();
@@ -1845,7 +1850,7 @@ public class ActiveModeWarden {
WifiController() {
super(TAG, mLooper);
- final int threshold = mContext.getResources().getInteger(
+ final int threshold = mResourceCache.getInteger(
R.integer.config_wifiConfigurationWifiRunnerThresholdInMs);
DefaultState defaultState = new DefaultState(threshold);
mEnabledState = new EnabledState(threshold);
@@ -1967,7 +1972,7 @@ public class ActiveModeWarden {
}
private int readWifiRecoveryDelay() {
- int recoveryDelayMillis = mContext.getResources().getInteger(
+ int recoveryDelayMillis = mResourceCache.getInteger(
R.integer.config_wifi_framework_recovery_timeout_delay);
if (recoveryDelayMillis > MAX_RECOVERY_TIMEOUT_DELAY_MS) {
recoveryDelayMillis = MAX_RECOVERY_TIMEOUT_DELAY_MS;
@@ -2741,19 +2746,19 @@ public class ActiveModeWarden {
concurrencyFeatureSet |= WifiManager.WIFI_FEATURE_AP_STA;
}
if (isStaStaConcurrencySupported) {
- if (mContext.getResources().getBoolean(
+ if (mResourceCache.getBoolean(
R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled)) {
concurrencyFeatureSet |= WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY;
}
- if (mContext.getResources().getBoolean(
+ if (mResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled)) {
concurrencyFeatureSet |= WifiManager.WIFI_FEATURE_ADDITIONAL_STA_MBB;
}
- if (mContext.getResources().getBoolean(
+ if (mResourceCache.getBoolean(
R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled)) {
concurrencyFeatureSet |= WifiManager.WIFI_FEATURE_ADDITIONAL_STA_RESTRICTED;
}
- if (mContext.getResources().getBoolean(
+ if (mResourceCache.getBoolean(
R.bool.config_wifiMultiStaMultiInternetConcurrencyEnabled)) {
concurrencyFeatureSet |= WifiManager.WIFI_FEATURE_ADDITIONAL_STA_MULTI_INTERNET;
}
@@ -2767,13 +2772,13 @@ public class ActiveModeWarden {
(WifiManager.WIFI_FEATURE_D2D_RTT | WifiManager.WIFI_FEATURE_D2AP_RTT);
}
- if (!mContext.getResources().getBoolean(
+ if (!mResourceCache.getBoolean(
R.bool.config_wifi_p2p_mac_randomization_supported)) {
// flags filled in by vendor HAL, remove if overlay disables it.
excludedFeatureSet |= WifiManager.WIFI_FEATURE_P2P_RAND_MAC;
}
- if (mContext.getResources().getBoolean(
+ if (mResourceCache.getBoolean(
R.bool.config_wifi_connected_mac_randomization_supported)) {
// no corresponding flags in vendor HAL, set if overlay enables it.
additionalFeatureSet |= WifiManager.WIFI_FEATURE_CONNECTED_RAND_MAC;
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 913ac9bf7b..8e97cae460 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -26,6 +26,7 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_FILS_SHA384;
import static android.net.wifi.WifiManager.WIFI_FEATURE_LINK_LAYER_STATS;
import static android.net.wifi.WifiManager.WIFI_FEATURE_TDLS;
import static android.net.wifi.WifiManager.WIFI_FEATURE_TRUST_ON_FIRST_USE;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_LOCAL_ONLY;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY;
@@ -34,6 +35,12 @@ import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_LO
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT;
import static com.android.server.wifi.WifiSettingsConfigStore.SECONDARY_WIFI_STA_FACTORY_MAC_ADDRESS;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_STA_FACTORY_MAC_ADDRESS;
+import static com.android.server.wifi.proto.WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_LOCAL_ONLY;
+import static com.android.server.wifi.proto.WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_OTHERS;
+import static com.android.server.wifi.proto.WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY;
+import static com.android.server.wifi.proto.WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_SECONDARY_INTERNET;
+import static com.android.server.wifi.proto.WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_SECONDARY_LONG_LIVED;
+import static com.android.server.wifi.proto.WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_SECONDARY_TRANSIENT;
import static com.android.server.wifi.proto.WifiStatsLog.WIFI_DISCONNECT_REPORTED__FAILURE_CODE__SUPPLICANT_DISCONNECTED;
import android.annotation.IntDef;
@@ -697,7 +704,6 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
public static final int EAP_FAILURE_CODE_CERTIFICATE_EXPIRED = 32768;
private boolean mCurrentConnectionReportedCertificateExpired = false;
-
/** Note that this constructor will also start() the StateMachine. */
public ClientModeImpl(
@NonNull WifiContext context,
@@ -1644,6 +1650,13 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
}
/**
+ * @return true if this device supports WPA3_SAE
+ */
+ private boolean isWpa3SaeSupported() {
+ return (getSupportedFeatures() & WIFI_FEATURE_WPA3_SAE) != 0;
+ }
+
+ /**
* Update interface capabilities
* This method is used to update some of interface capabilities defined in overlay
*/
@@ -1668,6 +1681,10 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
&& cap.getMaxNumberAkms() >= 3) {
mWifiGlobals.setWpa3SaeUpgradeOffloadEnabled();
}
+ if (SdkLevel.isAtLeastV() && mWifiNative.isSupplicantAidlServiceVersionAtLeast(3)
+ && isWpa3SaeSupported()) {
+ mWifiGlobals.enableWpa3SaeH2eSupport();
+ }
mWifiNative.setDeviceWiphyCapabilities(mInterfaceName, cap);
}
@@ -2430,6 +2447,12 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
case WifiMonitor.BSS_FREQUENCY_CHANGED_EVENT:
sb.append(" frequency=" + msg.arg1);
break;
+ case WifiMonitor.AUXILIARY_SUPPLICANT_EVENT:
+ SupplicantEventInfo eventInfo = (SupplicantEventInfo) msg.obj;
+ if (eventInfo != null) {
+ sb.append(" ").append(eventInfo.toString());
+ }
+ break;
default:
sb.append(" ");
sb.append(Integer.toString(msg.arg1));
@@ -2892,6 +2915,9 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiInfo.setSuccessfulRxPacketsPerSecond(0);
mWifiScoreReport.reset();
mLastLinkLayerStats = null;
+ if (isPrimary()) {
+ mWifiMetrics.resetWifiUnusableEvent();
+ }
updateCurrentConnectionInfo();
}
@@ -3250,6 +3276,10 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiInfo.clearCurrentSecurityType();
mWifiInfo.resetMultiLinkInfo();
}
+ if (state == SupplicantState.SCANNING) {
+ // Set networkId only for matching Wi-Fi entry in UI.
+ mWifiInfo.setNetworkId(stateChangeResult.networkId);
+ }
// SSID might have been updated, so call updateCapabilities
updateCapabilities();
@@ -3737,19 +3767,18 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
ActiveModeManager.ClientRole clientRole = mClientModeManager.getRole();
if (clientRole == ROLE_CLIENT_PRIMARY) {
return config != null && config.fromWifiNetworkSpecifier
- ? WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_LOCAL_ONLY
- : WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY;
+ ? WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_LOCAL_ONLY
+ : WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY;
} else if (clientRole == ROLE_CLIENT_LOCAL_ONLY) {
- return WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_LOCAL_ONLY;
+ return WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_LOCAL_ONLY;
} else if (clientRole == ROLE_CLIENT_SECONDARY_LONG_LIVED) {
return mClientModeManager.isSecondaryInternet()
- ? WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_SECONDARY_INTERNET
- : WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_SECONDARY_LONG_LIVED;
+ ? WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_SECONDARY_INTERNET
+ : WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_SECONDARY_LONG_LIVED;
} else if (clientRole == ROLE_CLIENT_SECONDARY_TRANSIENT) {
- return WifiStatsLog
- .WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_SECONDARY_TRANSIENT;
+ return WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_SECONDARY_TRANSIENT;
}
- return WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_OTHERS;
+ return WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_OTHERS;
}
/**
@@ -4131,6 +4160,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
// processing the posted message sent from the legacy IpClientCallbacks instance,
// see b/286338765.
maybeShutdownIpclient();
+ mTargetNetworkId = config.networkId;
transitionTo(mWaitBeforeL3ProvisioningState);
updateCurrentConnectionInfo();
@@ -4840,6 +4870,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
if (!isTrustOnFirstUseSupported()) {
mInsecureEapNetworkHandler.startUserApprovalIfNecessary(mIsUserSelected);
}
+ mFrameworkDisconnectReasonOverride = 0;
connectToNetwork(config);
break;
}
@@ -5377,7 +5408,8 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
* @param bssid BSSID of the AP.
* @return true if BSSID matches to one of the affiliated link BSSIDs, false otherwise.
*/
- public boolean isAffiliatedLinkBssid(@NonNull MacAddress bssid) {
+ public boolean isAffiliatedLinkBssid(@Nullable MacAddress bssid) {
+ if (bssid == null) return false;
List<MloLink> links = mWifiInfo.getAffiliatedMloLinks();
for (MloLink link: links) {
if (bssid.equals(link.getApMacAddress())) {
@@ -6773,12 +6805,15 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
&& mLastNetworkId != WifiConfiguration.INVALID_NETWORK_ID) {
WifiConfiguration config =
mWifiConfigManager.getConfiguredNetwork(mLastNetworkId);
- if (config != null
- && ((message.arg1 == RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED
+ if (config == null) {
+ break;
+ }
+ boolean isSimBasedNetwork = config.enterpriseConfig != null
+ && config.enterpriseConfig.isAuthenticationSimBased();
+ boolean isLastSubReady = mWifiCarrierInfoManager.isSimReady(mLastSubId);
+ if ((message.arg1 == RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED
&& config.carrierId != TelephonyManager.UNKNOWN_CARRIER_ID)
- || (config.enterpriseConfig != null
- && config.enterpriseConfig.isAuthenticationSimBased()
- && !mWifiCarrierInfoManager.isSimReady(mLastSubId)))) {
+ || (isSimBasedNetwork && !isLastSubReady)) {
mWifiMetrics.logStaEvent(mInterfaceName,
StaEvent.TYPE_FRAMEWORK_DISCONNECT,
StaEvent.DISCONNECT_RESET_SIM_NETWORKS);
@@ -6786,7 +6821,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
mWifiNative.removeNetworkCachedData(mLastNetworkId);
// remove network so that supplicant's PMKSA cache is cleared
mWifiNative.removeAllNetworks(mInterfaceName);
- if (isPrimary() && !mWifiCarrierInfoManager.isSimReady(mLastSubId)) {
+ if (isPrimary() && isSimBasedNetwork && !isLastSubReady) {
mSimRequiredNotifier.showSimRequiredNotification(
config, mLastSimBasedConnectionCarrierName);
}
@@ -6899,6 +6934,19 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
int statusDataStall = mWifiDataStall.checkDataStallAndThroughputSufficiency(
mInterfaceName, mLastConnectionCapabilities, mLastLinkLayerStats, stats,
mWifiInfo, txBytes, rxBytes);
+ if (getClientRoleForMetrics(getConnectedWifiConfiguration())
+ == WIFI_CONNECTION_RESULT_REPORTED__ROLE__ROLE_CLIENT_PRIMARY) {
+ mWifiMetrics.logScorerPredictionResult(mWifiInjector.hasActiveModem(),
+ mWifiCarrierInfoManager.hasActiveSubInfo(),
+ mWifiCarrierInfoManager.isMobileDataEnabled(),
+ mWifiGlobals.getPollRssiIntervalMillis(),
+ mWifiScoreReport.getAospScorerPredictionStatusForEvaluation(),
+ mWifiScoreReport.getExternalScorerPredictionStatusForEvaluation(),
+ mWifiScoreReport.getLingering(),
+ mWifiInfo, mLastConnectionCapabilities);
+ mWifiScoreReport.clearScorerPredictionStatusForEvaluation();
+ }
+
if (mDataStallTriggerTimeMs == -1
&& statusDataStall != WifiIsUnusableEvent.TYPE_UNKNOWN) {
mDataStallTriggerTimeMs = mClock.getElapsedSinceBootMillis();
@@ -6997,6 +7045,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
case CMD_IPCLIENT_CREATED: {
if (!isFromCurrentIpClientCallbacks(message)) break;
mIpClient = (IpClientManager) message.obj;
+ setMulticastFilter(true);
transitionTo(mL3ProvisioningState);
break;
}
diff --git a/service/java/com/android/server/wifi/ConcreteClientModeManager.java b/service/java/com/android/server/wifi/ConcreteClientModeManager.java
index 3864262b56..33c5f3142f 100644
--- a/service/java/com/android/server/wifi/ConcreteClientModeManager.java
+++ b/service/java/com/android/server/wifi/ConcreteClientModeManager.java
@@ -465,6 +465,8 @@ public class ConcreteClientModeManager implements ClientModeManager {
return true;
}
}
+ } catch (UnsupportedOperationException ex) {
+ Log.d(TAG, "IMS Manager is not supported.");
} catch (RuntimeException ex) {
Log.e(TAG, "IMS Manager is not available.", ex);
}
diff --git a/service/java/com/android/server/wifi/DeviceConfigFacade.java b/service/java/com/android/server/wifi/DeviceConfigFacade.java
index ec5c4bfef9..3b777b6135 100644
--- a/service/java/com/android/server/wifi/DeviceConfigFacade.java
+++ b/service/java/com/android/server/wifi/DeviceConfigFacade.java
@@ -152,6 +152,7 @@ public class DeviceConfigFacade {
// Maximum traffic stats threshold for link bandwidth estimator
static final int DEFAULT_TRAFFIC_STATS_THRESHOLD_MAX_KB = 8000;
static final int DEFAULT_BANDWIDTH_ESTIMATOR_TIME_CONSTANT_LARGE_SEC = 6;
+ static final String DEFAULT_DRY_RUN_SCORER_PKG_NAME = "";
// Cached values of fields updated via updateDeviceConfigFlags()
private boolean mIsAbnormalConnectionBugreportEnabled;
private int mAbnormalConnectionDurationMs;
@@ -215,6 +216,8 @@ public class DeviceConfigFacade {
private boolean mHighPerfLockDeprecated;
private Optional<Boolean> mOobPseudonymEnabled = Optional.empty();
private Consumer<Boolean> mOobPseudonymFeatureFlagChangedListener = null;
+ private String mDryRunScorerPkgName;
+ private Consumer<String> mDryRunScorerPkgNameChangedListener = null;
private boolean mApplicationQosPolicyApiEnabled;
private boolean mAdjustPollRssiIntervalEnabled;
private boolean mSoftwarePnoEnabled;
@@ -412,6 +415,16 @@ public class DeviceConfigFacade {
() -> mOobPseudonymFeatureFlagChangedListener.accept(oobPseudonymEnabled));
}
mOobPseudonymEnabled = Optional.of(oobPseudonymEnabled);
+
+ String dryRunScorerPkgName = DeviceConfig.getString(NAMESPACE, "dry_run_scorer_pkg_name",
+ DEFAULT_DRY_RUN_SCORER_PKG_NAME);
+ if (mDryRunScorerPkgNameChangedListener != null
+ && !dryRunScorerPkgName.equalsIgnoreCase(mDryRunScorerPkgName)) {
+ mWifiHandler.post(
+ () -> mDryRunScorerPkgNameChangedListener.accept(dryRunScorerPkgName));
+ }
+ mDryRunScorerPkgName = dryRunScorerPkgName;
+
mApplicationQosPolicyApiEnabled = DeviceConfig.getBoolean(NAMESPACE,
"application_qos_policy_api_enabled", true);
mAdjustPollRssiIntervalEnabled =
@@ -937,6 +950,18 @@ public class DeviceConfigFacade {
mOobPseudonymFeatureFlagChangedListener = listener;
}
+ /*
+ * Sets the listener to be notified when the DryRunScorerPkgName is changed.
+ * Only 1 listener is accepted.
+ */
+ public void setDryRunScorerPkgNameChangedListener(Consumer<String> listener) {
+ mDryRunScorerPkgNameChangedListener = listener;
+ }
+
+ public String getDryRunScorerPkgName() {
+ return mDryRunScorerPkgName;
+ }
+
/**
* Get the set of bugreports that are explicitly disabled.
* @return A Set of String to indicate disabled auto-bugreports trigger points.
diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java
index 99f929c8f3..8d0d9c44b6 100644
--- a/service/java/com/android/server/wifi/HalDeviceManager.java
+++ b/service/java/com/android/server/wifi/HalDeviceManager.java
@@ -19,6 +19,7 @@ package com.android.server.wifi;
import static com.android.server.wifi.HalDeviceManagerUtil.jsonToStaticChipInfo;
import static com.android.server.wifi.HalDeviceManagerUtil.staticChipInfoToJson;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_STATIC_CHIP_INFO;
+import static com.android.server.wifi.util.GeneralUtil.bitsetToLong;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -64,10 +65,10 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -951,6 +952,14 @@ public class HalDeviceManager {
public List<Pair<Integer, WorkSource>> reportImpactToCreateIface(
@HdmIfaceTypeForCreation int createIfaceType, boolean queryForNewInterface,
WorkSource requestorWs) {
+ if (!isWifiStarted()) {
+ if (canDeviceSupportCreateTypeCombo(new SparseArray<>() {{
+ put(createIfaceType, 1);
+ }})) {
+ return Collections.emptyList();
+ }
+ return null;
+ }
List<WifiIfaceInfo> ifaces = getIfacesToDestroyForRequest(createIfaceType,
queryForNewInterface, CHIP_CAPABILITY_ANY, requestorWs);
if (ifaces == null) {
@@ -1851,6 +1860,22 @@ public class HalDeviceManager {
}
}
+ private boolean isRequestorAllowedToUseP2pNanConcurrency(WorkSource requestorWs) {
+ String[] allowlistArray = mContext.getResources().getStringArray(
+ R.array.config_wifiP2pAwareConcurrencyAllowlist);
+ if (allowlistArray == null || allowlistArray.length == 0) {
+ // No allowlist defined, so allow.
+ return true;
+ }
+ List<String> allowlist = Arrays.asList(allowlistArray);
+ for (int i = 0; i < requestorWs.size(); i++) {
+ if (allowlist.contains(requestorWs.getPackageName(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Checks whether the input chip-create-type-combo can support the requested create type:
* if not then returns null, if yes then returns information containing the list of interfaces
@@ -1883,6 +1908,21 @@ public class HalDeviceManager {
return null;
}
+ // Remove P2P/NAN concurrency if the requestor isn't on the allowlist.
+ if ((requestedCreateType == HDM_CREATE_IFACE_P2P
+ || requestedCreateType == HDM_CREATE_IFACE_NAN)
+ && chipCreateTypeCombo[HDM_CREATE_IFACE_P2P] > 0
+ && chipCreateTypeCombo[HDM_CREATE_IFACE_NAN] > 0) {
+ if (!isRequestorAllowedToUseP2pNanConcurrency(requestorWs)) {
+ chipCreateTypeCombo = chipCreateTypeCombo.clone();
+ if (requestedCreateType == HDM_CREATE_IFACE_P2P) {
+ chipCreateTypeCombo[HDM_CREATE_IFACE_NAN] = 0;
+ } else {
+ chipCreateTypeCombo[HDM_CREATE_IFACE_P2P] = 0;
+ }
+ }
+ }
+
IfaceCreationData ifaceCreationData = new IfaceCreationData();
ifaceCreationData.chipInfo = chipInfo;
ifaceCreationData.chipModeId = chipModeId;
@@ -2492,6 +2532,7 @@ public class HalDeviceManager {
return false;
}
+ boolean success = false;
synchronized (mLock) {
WifiChip chip = getChip(iface);
if (chip == null) {
@@ -2504,7 +2545,6 @@ public class HalDeviceManager {
return false;
}
- boolean success = false;
switch (type) {
case WifiChip.IFACE_TYPE_STA:
mClientModeManagers.remove(name);
@@ -2523,20 +2563,20 @@ public class HalDeviceManager {
Log.wtf(TAG, "removeIfaceInternal: invalid type=" + type);
return false;
}
+ }
- // dispatch listeners no matter what status
- dispatchDestroyedListeners(name, type);
- if (validateRttController) {
- // Try to update the RttController
- updateRttControllerWhenInterfaceChanges();
- }
+ // dispatch listeners no matter what status
+ dispatchDestroyedListeners(name, type);
+ if (validateRttController) {
+ // Try to update the RttController
+ updateRttControllerWhenInterfaceChanges();
+ }
- if (success) {
- return true;
- } else {
- Log.e(TAG, "IWifiChip.removeXxxIface failed, name=" + name + ", type=" + type);
- return false;
- }
+ if (success) {
+ return true;
+ } else {
+ Log.e(TAG, "IWifiChip.removeXxxIface failed, name=" + name + ", type=" + type);
+ return false;
}
}
@@ -2546,20 +2586,19 @@ public class HalDeviceManager {
// onlyOnOtherThreads = false: call all listeners
private void dispatchDestroyedListeners(String name, int type) {
if (VDBG) Log.d(TAG, "dispatchDestroyedListeners: iface(name)=" + name);
+ InterfaceCacheEntry entry;
+ List<InterfaceDestroyedListenerProxy> triggerList;
synchronized (mLock) {
- InterfaceCacheEntry entry = mInterfaceInfoCache.remove(Pair.create(name, type));
+ entry = mInterfaceInfoCache.remove(Pair.create(name, type));
if (entry == null) {
Log.e(TAG, "dispatchDestroyedListeners: no cache entry for iface(name)=" + name);
return;
}
-
- Iterator<InterfaceDestroyedListenerProxy> iterator =
- entry.destroyedListeners.iterator();
- while (iterator.hasNext()) {
- InterfaceDestroyedListenerProxy listener = iterator.next();
- iterator.remove();
- listener.action();
- }
+ triggerList = new ArrayList<>(entry.destroyedListeners);
+ entry.destroyedListeners.clear();
+ }
+ for (InterfaceDestroyedListenerProxy listener : triggerList) {
+ listener.action();
}
}
@@ -2570,9 +2609,7 @@ public class HalDeviceManager {
List<InterfaceDestroyedListenerProxy> triggerList = new ArrayList<>();
synchronized (mLock) {
for (InterfaceCacheEntry cacheEntry: mInterfaceInfoCache.values()) {
- for (InterfaceDestroyedListenerProxy listener : cacheEntry.destroyedListeners) {
- triggerList.add(listener);
- }
+ triggerList.addAll(cacheEntry.destroyedListeners);
cacheEntry.destroyedListeners.clear(); // for insurance
}
mInterfaceInfoCache.clear();
@@ -2821,12 +2858,12 @@ public class HalDeviceManager {
* @param wifiChip WifiChip to get the features for.
* @return Bitset of WifiManager.WIFI_FEATURE_* values.
*/
- public long getChipCapabilities(@NonNull WifiChip wifiChip) {
+ private long getChipCapabilities(@NonNull WifiChip wifiChip) {
if (wifiChip == null) return 0;
- WifiChip.Response<Long> capsResp = wifiChip.getCapabilitiesBeforeIfacesExist();
+ WifiChip.Response<BitSet> capsResp = wifiChip.getCapabilitiesBeforeIfacesExist();
if (capsResp.getStatusCode() == WifiHal.WIFI_STATUS_SUCCESS) {
- return capsResp.getValue();
+ return bitsetToLong(capsResp.getValue());
} else if (capsResp.getStatusCode() != WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION) {
// Non-remote exception here is likely because HIDL HAL < v1.5
// does not support getting capabilities before creating an interface.
diff --git a/service/java/com/android/server/wifi/HostapdHal.java b/service/java/com/android/server/wifi/HostapdHal.java
index dbb7c705ff..7d7b2bfda2 100644
--- a/service/java/com/android/server/wifi/HostapdHal.java
+++ b/service/java/com/android/server/wifi/HostapdHal.java
@@ -16,9 +16,9 @@
package com.android.server.wifi;
import android.annotation.NonNull;
-import android.content.Context;
import android.net.MacAddress;
import android.net.wifi.SoftApConfiguration;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.util.Log;
@@ -42,13 +42,13 @@ public class HostapdHal {
private final Object mLock = new Object();
private boolean mVerboseLoggingEnabled = false;
private boolean mVerboseHalLoggingEnabled = false;
- private final Context mContext;
+ private final WifiContext mContext;
private final Handler mEventHandler;
// Hostapd HAL interface object - might be implemented by HIDL or AIDL
private IHostapdHal mIHostapd;
- public HostapdHal(Context context, Handler handler) {
+ public HostapdHal(WifiContext context, Handler handler) {
mContext = context;
mEventHandler = handler;
}
diff --git a/service/java/com/android/server/wifi/HostapdHalAidlImp.java b/service/java/com/android/server/wifi/HostapdHalAidlImp.java
index ffca0c3526..c689998078 100644
--- a/service/java/com/android/server/wifi/HostapdHalAidlImp.java
+++ b/service/java/com/android/server/wifi/HostapdHalAidlImp.java
@@ -16,7 +16,6 @@
package com.android.server.wifi;
import android.annotation.NonNull;
-import android.content.Context;
import android.hardware.wifi.hostapd.ApInfo;
import android.hardware.wifi.hostapd.BandMask;
import android.hardware.wifi.hostapd.ChannelBandwidth;
@@ -39,7 +38,9 @@ import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApConfiguration.BandType;
import android.net.wifi.SoftApInfo;
import android.net.wifi.WifiAnnotations;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiManager;
+import android.net.wifi.util.WifiResourceCache;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
@@ -84,7 +85,7 @@ public class HostapdHalAidlImp implements IHostapdHal {
private final Object mLock = new Object();
private boolean mVerboseLoggingEnabled = false;
private boolean mVerboseHalLoggingEnabled = false;
- private final Context mContext;
+ private final WifiContext mContext;
private final Handler mEventHandler;
// Hostapd HAL interface objects
@@ -96,6 +97,7 @@ public class HostapdHalAidlImp implements IHostapdHal {
private boolean mServiceDeclared = false;
private int mServiceVersion;
private CountDownLatch mWaitForDeathLatch;
+ private final WifiResourceCache mResourceCache;
/**
* Default death recipient. Called any time the service dies.
@@ -127,9 +129,10 @@ public class HostapdHalAidlImp implements IHostapdHal {
}
}
- public HostapdHalAidlImp(@NonNull Context context, @NonNull Handler handler) {
+ public HostapdHalAidlImp(@NonNull WifiContext context, @NonNull Handler handler) {
mContext = context;
mEventHandler = handler;
+ mResourceCache = mContext.getResourceCache();
Log.d(TAG, "init HostapdHalAidlImp");
}
@@ -380,14 +383,23 @@ public class HostapdHalAidlImp implements IHostapdHal {
public void onFailure(String ifaceName, String instanceName) {
Log.w(TAG, "Failure on iface " + ifaceName + ", instance: " + instanceName);
Runnable onFailureListener = mSoftApFailureListeners.get(ifaceName);
- SoftApHalCallback callback = mSoftApHalCallbacks.get(ifaceName);
- if (onFailureListener != null) {
- mActiveInstances.remove(instanceName);
- if (mActiveInstances.size() == 0) {
+ if (onFailureListener != null && ifaceName != null) {
+ if (ifaceName.equals(instanceName)) {
+ // Single AP
onFailureListener.run();
- } else if (callback != null) {
- callback.onInstanceFailure(instanceName);
+ } else {
+ // Bridged AP
+ if (mActiveInstances.contains(instanceName)) {
+ SoftApHalCallback callback = mSoftApHalCallbacks.get(ifaceName);
+ if (callback != null) {
+ callback.onInstanceFailure(instanceName);
+ }
+ } else {
+ Log.w(TAG, "Ignore error for inactive instances");
+
+ }
}
+ mActiveInstances.remove(instanceName);
}
}
@@ -688,15 +700,15 @@ public class HostapdHalAidlImp implements IHostapdHal {
String oemConfig;
switch (band) {
case SoftApConfiguration.BAND_2GHZ:
- oemConfig = mContext.getResources().getString(
+ oemConfig = mResourceCache.getString(
R.string.config_wifiSoftap2gChannelList);
break;
case SoftApConfiguration.BAND_5GHZ:
- oemConfig = mContext.getResources().getString(
+ oemConfig = mResourceCache.getString(
R.string.config_wifiSoftap5gChannelList);
break;
case SoftApConfiguration.BAND_6GHZ:
- oemConfig = mContext.getResources().getString(
+ oemConfig = mResourceCache.getString(
R.string.config_wifiSoftap6gChannelList);
break;
default:
@@ -901,20 +913,20 @@ public class HostapdHalAidlImp implements IHostapdHal {
private HwModeParams prepareHwModeParams(SoftApConfiguration config) {
HwModeParams hwModeParams = new HwModeParams();
hwModeParams.enable80211N = true;
- hwModeParams.enable80211AC = mContext.getResources().getBoolean(
+ hwModeParams.enable80211AC = mResourceCache.getBoolean(
R.bool.config_wifi_softap_ieee80211ac_supported);
hwModeParams.enable80211AX = ApConfigUtil.isIeee80211axSupported(mContext);
//Update 80211ax support with the configuration.
hwModeParams.enable80211AX &= config.isIeee80211axEnabledInternal();
hwModeParams.enable6GhzBand = ApConfigUtil.isBandSupported(
SoftApConfiguration.BAND_6GHZ, mContext);
- hwModeParams.enableHeSingleUserBeamformer = mContext.getResources().getBoolean(
+ hwModeParams.enableHeSingleUserBeamformer = mResourceCache.getBoolean(
R.bool.config_wifiSoftapHeSuBeamformerSupported);
- hwModeParams.enableHeSingleUserBeamformee = mContext.getResources().getBoolean(
+ hwModeParams.enableHeSingleUserBeamformee = mResourceCache.getBoolean(
R.bool.config_wifiSoftapHeSuBeamformeeSupported);
- hwModeParams.enableHeMultiUserBeamformer = mContext.getResources().getBoolean(
+ hwModeParams.enableHeMultiUserBeamformer = mResourceCache.getBoolean(
R.bool.config_wifiSoftapHeMuBeamformerSupported);
- hwModeParams.enableHeTargetWakeTime = mContext.getResources().getBoolean(
+ hwModeParams.enableHeTargetWakeTime = mResourceCache.getBoolean(
R.bool.config_wifiSoftapHeTwtSupported);
if (SdkLevel.isAtLeastT()) {
@@ -954,7 +966,7 @@ public class HostapdHalAidlImp implements IHostapdHal {
channelParamsList[i].bandMask = getHalBandMask(band);
channelParamsList[i].acsChannelFreqRangesMhz = new FrequencyRange[0];
if (channelParamsList[i].enableAcs) {
- channelParamsList[i].acsShouldExcludeDfs = !mContext.getResources()
+ channelParamsList[i].acsShouldExcludeDfs = !mResourceCache
.getBoolean(R.bool.config_wifiSoftapAcsIncludeDfs);
if (ApConfigUtil.isSendFreqRangesNeeded(band, mContext, config)) {
prepareAcsChannelFreqRangesMhz(channelParamsList[i], band, config);
diff --git a/service/java/com/android/server/wifi/HostapdHalHidlImp.java b/service/java/com/android/server/wifi/HostapdHalHidlImp.java
index 1dc63f03dd..ce74efe1fd 100644
--- a/service/java/com/android/server/wifi/HostapdHalHidlImp.java
+++ b/service/java/com/android/server/wifi/HostapdHalHidlImp.java
@@ -16,7 +16,6 @@
package com.android.server.wifi;
import android.annotation.NonNull;
-import android.content.Context;
import android.hardware.wifi.hostapd.V1_0.HostapdStatus;
import android.hardware.wifi.hostapd.V1_0.HostapdStatusCode;
import android.hardware.wifi.hostapd.V1_0.IHostapd;
@@ -31,7 +30,9 @@ import android.net.wifi.ScanResult;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApConfiguration.BandType;
import android.net.wifi.SoftApInfo;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiManager;
+import android.net.wifi.util.WifiResourceCache;
import android.os.Handler;
import android.os.IHwBinder.DeathRecipient;
import android.os.RemoteException;
@@ -74,7 +75,7 @@ public class HostapdHalHidlImp implements IHostapdHal {
private final Object mLock = new Object();
private boolean mVerboseLoggingEnabled = false;
private boolean mVerboseHalLoggingEnabled = false;
- private final Context mContext;
+ private final WifiContext mContext;
private final Handler mEventHandler;
// Hostapd HAL interface objects
@@ -87,6 +88,7 @@ public class HostapdHalHidlImp implements IHostapdHal {
private HostapdDeathRecipient mHostapdDeathRecipient;
// Death recipient cookie registered for current hostapd instance.
private long mDeathRecipientCookie = 0;
+ private final WifiResourceCache mResourceCache;
private final IServiceNotification mServiceNotificationCallback =
new IServiceNotification.Stub() {
@@ -131,11 +133,12 @@ public class HostapdHalHidlImp implements IHostapdHal {
}
}
- public HostapdHalHidlImp(@NonNull Context context, @NonNull Handler handler) {
+ public HostapdHalHidlImp(@NonNull WifiContext context, @NonNull Handler handler) {
mContext = context;
mEventHandler = handler;
mServiceManagerDeathRecipient = new ServiceManagerDeathRecipient();
mHostapdDeathRecipient = new HostapdDeathRecipient();
+ mResourceCache = mContext.getResourceCache();
Log.d(TAG, "init HostapdHalHidlImp");
}
@@ -790,16 +793,16 @@ public class HostapdHalHidlImp implements IHostapdHal {
ifaceParams12.hwModeParams.enable6GhzBand =
ApConfigUtil.isBandSupported(SoftApConfiguration.BAND_6GHZ, mContext);
ifaceParams12.hwModeParams.enableHeSingleUserBeamformer =
- mContext.getResources().getBoolean(
+ mResourceCache.getBoolean(
R.bool.config_wifiSoftapHeSuBeamformerSupported);
ifaceParams12.hwModeParams.enableHeSingleUserBeamformee =
- mContext.getResources().getBoolean(
+ mResourceCache.getBoolean(
R.bool.config_wifiSoftapHeSuBeamformeeSupported);
ifaceParams12.hwModeParams.enableHeMultiUserBeamformer =
- mContext.getResources().getBoolean(
+ mResourceCache.getBoolean(
R.bool.config_wifiSoftapHeMuBeamformerSupported);
ifaceParams12.hwModeParams.enableHeTargetWakeTime =
- mContext.getResources().getBoolean(R.bool.config_wifiSoftapHeTwtSupported);
+ mResourceCache.getBoolean(R.bool.config_wifiSoftapHeTwtSupported);
}
private android.hardware.wifi.hostapd.V1_0.IHostapd.IfaceParams
@@ -807,12 +810,12 @@ public class HostapdHalHidlImp implements IHostapdHal {
IHostapd.IfaceParams ifaceParamsV1_0 = new IHostapd.IfaceParams();
ifaceParamsV1_0.ifaceName = ifaceName;
ifaceParamsV1_0.hwModeParams.enable80211N = true;
- ifaceParamsV1_0.hwModeParams.enable80211AC = mContext.getResources().getBoolean(
+ ifaceParamsV1_0.hwModeParams.enable80211AC = mResourceCache.getBoolean(
R.bool.config_wifi_softap_ieee80211ac_supported);
boolean enableAcs = ApConfigUtil.isAcsSupported(mContext) && config.getChannel() == 0;
if (enableAcs) {
ifaceParamsV1_0.channelParams.enableAcs = true;
- ifaceParamsV1_0.channelParams.acsShouldExcludeDfs = !mContext.getResources()
+ ifaceParamsV1_0.channelParams.acsShouldExcludeDfs = !mResourceCache
.getBoolean(R.bool.config_wifiSoftapAcsIncludeDfs);
}
ifaceParamsV1_0.channelParams.channel = config.getChannel();
@@ -832,12 +835,12 @@ public class HostapdHalHidlImp implements IHostapdHal {
if (ifaceParamsV10.channelParams.enableAcs) {
if ((config.getBand() & SoftApConfiguration.BAND_2GHZ) != 0) {
ifaceParamsV1_1.channelParams.acsChannelRanges.addAll(
- toAcsChannelRanges(mContext.getResources().getString(
+ toAcsChannelRanges(mResourceCache.getString(
R.string.config_wifiSoftap2gChannelList)));
}
if ((config.getBand() & SoftApConfiguration.BAND_5GHZ) != 0) {
ifaceParamsV1_1.channelParams.acsChannelRanges.addAll(
- toAcsChannelRanges(mContext.getResources().getString(
+ toAcsChannelRanges(mResourceCache.getString(
R.string.config_wifiSoftap5gChannelList)));
}
}
@@ -1070,15 +1073,15 @@ public class HostapdHalHidlImp implements IHostapdHal {
String oemConfig;
switch (band) {
case SoftApConfiguration.BAND_2GHZ:
- oemConfig = mContext.getResources().getString(
+ oemConfig = mResourceCache.getString(
R.string.config_wifiSoftap2gChannelList);
break;
case SoftApConfiguration.BAND_5GHZ:
- oemConfig = mContext.getResources().getString(
+ oemConfig = mResourceCache.getString(
R.string.config_wifiSoftap5gChannelList);
break;
case SoftApConfiguration.BAND_6GHZ:
- oemConfig = mContext.getResources().getString(
+ oemConfig = mResourceCache.getString(
R.string.config_wifiSoftap6gChannelList);
break;
default:
diff --git a/service/java/com/android/server/wifi/ISupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/ISupplicantStaIfaceHal.java
index 6796b2e904..96e703dfcb 100644
--- a/service/java/com/android/server/wifi/ISupplicantStaIfaceHal.java
+++ b/service/java/com/android/server/wifi/ISupplicantStaIfaceHal.java
@@ -25,6 +25,7 @@ import android.net.wifi.SecurityParams;
import android.net.wifi.WifiConfiguration;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.List;
import java.util.Map;
@@ -563,23 +564,23 @@ interface ISupplicantStaIfaceHal {
boolean setConcurrencyPriority(boolean isStaHigherPriority);
/**
- * Returns a bitmask of advanced capabilities: WPA3 SAE/SUITE B and OWE
+ * Returns a BitSet of advanced capabilities: WPA3 SAE/SUITE B and OWE
* Bitmask used is:
* - WIFI_FEATURE_WPA3_SAE
* - WIFI_FEATURE_WPA3_SUITE_B
* - WIFI_FEATURE_OWE
*
- * On error, or if these features are not supported, 0 is returned.
+ * On error, or if these features are not supported, an empty BitSet is returned.
*/
- long getAdvancedCapabilities(@NonNull String ifaceName);
+ @NonNull BitSet getAdvancedCapabilities(@NonNull String ifaceName);
/**
* Get the driver supported features through supplicant.
*
* @param ifaceName Name of the interface.
- * @return bitmask defined by WifiManager.WIFI_FEATURE_*.
+ * @return BitSet defined by WifiManager.WIFI_FEATURE_*.
*/
- long getWpaDriverFeatureSet(@NonNull String ifaceName);
+ @NonNull BitSet getWpaDriverFeatureSet(@NonNull String ifaceName);
/**
* Returns connection capabilities of the current network
diff --git a/service/java/com/android/server/wifi/PmkCacheManager.java b/service/java/com/android/server/wifi/PmkCacheManager.java
index adcd54948d..18a7c51b14 100644
--- a/service/java/com/android/server/wifi/PmkCacheManager.java
+++ b/service/java/com/android/server/wifi/PmkCacheManager.java
@@ -217,6 +217,9 @@ public class PmkCacheManager {
for (int i = 0; i < mPmkCacheEntries.size(); i++) {
int networkId = mPmkCacheEntries.keyAt(i);
List<PmkCacheStoreData> list = mPmkCacheEntries.get(networkId);
+ if (null == list) {
+ continue;
+ }
list.removeIf(pmkData -> !pmkData.isValid(elapseTimeInSecond));
if (list.size() == 0) {
emptyStoreDataList.add(networkId);
diff --git a/service/java/com/android/server/wifi/RssiMonitor.java b/service/java/com/android/server/wifi/RssiMonitor.java
index 9e2867cbeb..4f976b006e 100644
--- a/service/java/com/android/server/wifi/RssiMonitor.java
+++ b/service/java/com/android/server/wifi/RssiMonitor.java
@@ -42,7 +42,6 @@ public class RssiMonitor {
private final DeviceConfigFacade mDeviceConfigFacade;
private boolean mEnableClientRssiMonitor = false;
- private boolean mIsPollRssiIntervalOverridden = false;
private int[] mAppThresholds = {};
private byte[] mRssiRanges = {};
@@ -138,7 +137,7 @@ public class RssiMonitor {
mEnableClientRssiMonitor = false;
mAppThresholds = new int[] {};
mRssiRanges = new byte[] {};
- if (!mIsPollRssiIntervalOverridden) {
+ if (!mWifiGlobals.isPollRssiIntervalOverridden()) {
int shortInterval = mWifiGlobals.getPollRssiShortIntervalMillis();
mWifiGlobals.setPollRssiIntervalMillis(shortInterval);
}
@@ -162,7 +161,7 @@ public class RssiMonitor {
public void updatePollRssiInterval(@DeviceMobilityState int state) {
if (!mWifiGlobals.isAdjustPollRssiIntervalEnabled()
|| !mDeviceConfigFacade.isAdjustPollRssiIntervalEnabled()
- || mIsPollRssiIntervalOverridden) {
+ || mWifiGlobals.isPollRssiIntervalOverridden()) {
return;
}
int curRssi = mWifiInfo.getRssi();
@@ -192,7 +191,7 @@ public class RssiMonitor {
* Change the RSSI polling interval to the short interval and disable client mode RSSI monitor
*/
public void setShortPollRssiInterval() {
- if (mIsPollRssiIntervalOverridden) {
+ if (mWifiGlobals.isPollRssiIntervalOverridden()) {
return;
}
int shortInterval = mWifiGlobals.getPollRssiShortIntervalMillis();
@@ -287,7 +286,7 @@ public class RssiMonitor {
* For automatic handling of the interval, use value 0
*/
public void overridePollRssiInterval(int newIntervalMs) {
- if (mIsPollRssiIntervalOverridden && newIntervalMs == 0) {
+ if (mWifiGlobals.isPollRssiIntervalOverridden() && newIntervalMs == 0) {
setAutoPollRssiInterval();
return;
}
@@ -297,13 +296,13 @@ public class RssiMonitor {
}
private void setAutoPollRssiInterval() {
- mIsPollRssiIntervalOverridden = false;
+ mWifiGlobals.setPollRssiIntervalOverridden(false);
int regularInterval = mWifiGlobals.getPollRssiShortIntervalMillis();
mWifiGlobals.setPollRssiIntervalMillis(regularInterval);
}
private void setFixedPollRssiInterval(int newIntervalMs) {
- mIsPollRssiIntervalOverridden = true;
+ mWifiGlobals.setPollRssiIntervalOverridden(true);
mWifiGlobals.setPollRssiIntervalMillis(newIntervalMs);
if (mEnableClientRssiMonitor) {
disableClientRssiMonitorAndUpdateThresholds(mWifiInfo.getRssi());
diff --git a/service/java/com/android/server/wifi/ScanRequestProxy.java b/service/java/com/android/server/wifi/ScanRequestProxy.java
index e8651652a5..38cf93767a 100644
--- a/service/java/com/android/server/wifi/ScanRequestProxy.java
+++ b/service/java/com/android/server/wifi/ScanRequestProxy.java
@@ -464,8 +464,8 @@ public class ScanRequestProxy {
* Safely retrieve package importance.
*/
private int getPackageImportance(int callingUid, String packageName) {
- mAppOps.checkPackage(callingUid, packageName);
try {
+ mAppOps.checkPackage(callingUid, packageName);
return mActivityManager.getPackageImportance(packageName);
} catch (SecurityException e) {
Log.e(TAG, "Failed to check the app state", e);
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index a0ceb41f96..5afaf78c82 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -40,6 +40,7 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
import android.net.wifi.nl80211.DeviceWiphyCapabilities;
+import android.net.wifi.util.WifiResourceCache;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.Looper;
@@ -73,6 +74,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -181,6 +183,7 @@ public class SoftApManager implements ActiveModeManager {
private final SoftApNotifier mSoftApNotifier;
private final InterfaceConflictManager mInterfaceConflictManager;
private final WifiInjector mWifiInjector;
+ private final WifiResourceCache mResourceCache;
@VisibleForTesting
static final long SOFT_AP_PENDING_DISCONNECTION_CHECK_DELAY_MS = 1000;
@@ -448,6 +451,7 @@ public class SoftApManager implements ActiveModeManager {
mWifiInjector = wifiInjector;
mCoexManager = coexManager;
mInterfaceConflictManager = interfaceConflictManager;
+ mResourceCache = mContext.getResourceCache();
if (SdkLevel.isAtLeastS()) {
mCoexListener = new CoexListener() {
@Override
@@ -494,12 +498,12 @@ public class SoftApManager implements ActiveModeManager {
mWifiDiagnostics = wifiDiagnostics;
mStateMachine = new SoftApStateMachine(looper);
configureInternalConfiguration();
- mDefaultShutdownTimeoutMillis = mContext.getResources().getInteger(
+ mDefaultShutdownTimeoutMillis = mResourceCache.getInteger(
R.integer.config_wifiFrameworkSoftApShutDownTimeoutMilliseconds);
- mDefaultShutdownIdleInstanceInBridgedModeTimeoutMillis = mContext.getResources().getInteger(
- R.integer
+ mDefaultShutdownIdleInstanceInBridgedModeTimeoutMillis = mResourceCache
+ .getInteger(R.integer
.config_wifiFrameworkSoftApShutDownIdleInstanceInBridgedModeTimeoutMillisecond);
- mIsDisableShutDownBridgedModeIdleInstanceTimerWhenPlugged = mContext.getResources()
+ mIsDisableShutDownBridgedModeIdleInstanceTimerWhenPlugged = mResourceCache
.getBoolean(R.bool
.config_wifiFrameworkSoftApDisableBridgedModeShutdownIdleInstanceWhenCharging);
mCmiMonitor = cmiMonitor;
@@ -854,7 +858,7 @@ public class SoftApManager implements ActiveModeManager {
new SoftApConfiguration.Builder(mCurrentSoftApConfiguration);
startResult = ApConfigUtil.updateApChannelConfig(
- mWifiNative, mCoexManager, mContext.getResources(), mCountryCode,
+ mWifiNative, mCoexManager, mResourceCache, mCountryCode,
localConfigBuilder, mCurrentSoftApConfiguration, mCurrentSoftApCapability);
if (startResult != START_RESULT_SUCCESS) {
Log.e(getTag(), "Failed to update AP band and channel");
@@ -1064,7 +1068,7 @@ public class SoftApManager implements ActiveModeManager {
SoftApStateMachine(Looper looper) {
super(TAG, looper);
- final int threshold = mContext.getResources().getInteger(
+ final int threshold = mResourceCache.getInteger(
R.integer.config_wifiConfigurationWifiRunnerThresholdInMs);
mIdleState = new IdleState(threshold);
mWaitingForDriverCountryCodeChangedState =
@@ -1181,8 +1185,9 @@ public class SoftApManager implements ActiveModeManager {
handleStartSoftApFailure(START_RESULT_FAILURE_GENERAL);
break;
}
- if (TextUtils.isEmpty(mCountryCode) && mContext.getResources().getBoolean(
- R.bool.config_wifiDriverSupportedNl80211RegChangedEvent)) {
+ if (TextUtils.isEmpty(mCountryCode) && mResourceCache
+ .getBoolean(
+ R.bool.config_wifiDriverSupportedNl80211RegChangedEvent)) {
Log.i(getTag(), "No country code set in the framework."
+ " Should Wait for driver country code update to start AP");
shouldwaitForDriverCountryCodeIfNoCountryToSet = true;
@@ -1196,43 +1201,8 @@ public class SoftApManager implements ActiveModeManager {
+ ", base country in SoftApCapability = "
+ mCurrentSoftApCapability.getCountryCode());
}
+
if (isBridgedMode()) {
- boolean isFallbackToSingleAp = false;
- final List<ClientModeManager> cmms =
- mActiveModeWarden.getClientModeManagers();
- // Checking STA status only when device supports STA + AP concurrency
- // since STA would be dropped when device doesn't support it.
- if (cmms.size() != 0 && mWifiNative.isStaApConcurrencySupported()) {
- if (ApConfigUtil.isStaWithBridgedModeSupported(mContext,
- mWifiNative)) {
- for (ClientModeManager cmm
- : mActiveModeWarden.getClientModeManagers()) {
- WifiInfo wifiConnectedInfo = cmm.getConnectionInfo();
- int wifiFrequency = wifiConnectedInfo.getFrequency();
- if (wifiFrequency > 0
- && !mSafeChannelFrequencyList.contains(
- wifiFrequency)) {
- Log.d(getTag(), "Wifi connected to unavailable freq: "
- + wifiFrequency);
- isFallbackToSingleAp = true;
- break;
- }
- }
- } else {
- // The client mode exist but DUT doesn't support
- // STA + bridged AP, we should fallback to single AP mode.
- Log.d(getTag(), " STA iface exist but device doesn't support"
- + " STA + Bridged AP");
- isFallbackToSingleAp = true;
- }
- }
- if (isCountryCodeChanged && mCountryCode.equalsIgnoreCase(
- mContext.getResources().getString(
- R.string.config_wifiDriverWorldModeCountryCode))) {
- Log.i(getTag(), "Country code changed to world mode"
- + " - fallback to single AP");
- isFallbackToSingleAp = true;
- }
if (!isCountryCodeChanged) {
SoftApConfiguration tempConfig =
ApConfigUtil.removeUnavailableBandsFromConfig(
@@ -1246,26 +1216,9 @@ public class SoftApManager implements ActiveModeManager {
break;
}
mCurrentSoftApConfiguration = tempConfig;
- if (mCurrentSoftApConfiguration.getBands().length == 1) {
- isFallbackToSingleAp = true;
- Log.i(
- getTag(),
- "Removed unavailable bands"
- + " - fallback to single AP");
- }
- }
- // Fall back to Single AP if it's not possible to create a Bridged AP.
- if (!mWifiNative.isItPossibleToCreateBridgedApIface(mRequestorWs)) {
- isFallbackToSingleAp = true;
- }
- // Fall back to single AP if creating a single AP does not require
- // destroying an existing iface, but creating a bridged AP does.
- if (mWifiNative.shouldDowngradeToSingleApForConcurrency(mRequestorWs)) {
- Log.d(getTag(), "Creating bridged AP will destroy an existing"
- + " iface, but single AP will not.");
- isFallbackToSingleAp = true;
}
- if (isFallbackToSingleAp) {
+ if (!isBridgedApAvailable()
+ || mCurrentSoftApConfiguration.getBands().length == 1) {
int newSingleApBand = 0;
for (int configuredBand : mCurrentSoftApConfiguration.getBands()) {
newSingleApBand |= configuredBand;
@@ -1276,16 +1229,27 @@ public class SoftApManager implements ActiveModeManager {
+ newSingleApBand);
mCurrentSoftApConfiguration =
new SoftApConfiguration.Builder(mCurrentSoftApConfiguration)
- .setBand(newSingleApBand)
- .build();
+ .setBand(newSingleApBand)
+ .build();
}
+ } else if (!isCountryCodeChanged
+ && mRole == ROLE_SOFTAP_TETHERED && isBridgedApAvailable()) {
+ // Try upgrading config to 2 + 5 GHz Dual Band if the available config
+ // bands only include 2 or 5 Ghz. This is to handle cases where the
+ // config was previously set to single band in a CC that didn't support
+ // DBS, but the current one does.
+ mCurrentSoftApConfiguration =
+ ApConfigUtil.upgradeTo2g5gBridgedIfAvailableBandsAreSubset(
+ mCurrentSoftApConfiguration,
+ mCurrentSoftApCapability,
+ mContext);
}
// Remove 6GHz from requested bands if security type is restricted
// Note: 6GHz only band is already handled by initial validation
SoftApConfiguration tempConfig =
ApConfigUtil.remove6gBandForUnsupportedSecurity(
- mContext.getResources(),
+ mResourceCache,
mCurrentSoftApConfiguration, isBridgedMode());
if (tempConfig == null) {
handleStartSoftApFailure(START_RESULT_FAILURE_UNSUPPORTED_CONFIG);
@@ -1401,6 +1365,64 @@ public class SoftApManager implements ActiveModeManager {
}
}
+ private boolean isBridgedApAvailable() {
+ // Skip if bridged mode isn't supported.
+ if (!ApConfigUtil.isBridgedModeSupported(mContext, mWifiNative)) {
+ return false;
+ }
+
+ // Checking STA status only when device supports STA + AP concurrency
+ // since STA would be dropped when device doesn't support it.
+ final List<ClientModeManager> cmms =
+ mActiveModeWarden.getClientModeManagers();
+ if (cmms.size() != 0 && mWifiNative.isStaApConcurrencySupported()) {
+ if (ApConfigUtil.isStaWithBridgedModeSupported(mContext,
+ mWifiNative)) {
+ for (ClientModeManager cmm
+ : mActiveModeWarden.getClientModeManagers()) {
+ WifiInfo wifiConnectedInfo = cmm.getConnectionInfo();
+ int wifiFrequency = wifiConnectedInfo.getFrequency();
+ if (wifiFrequency > 0
+ && !mSafeChannelFrequencyList.contains(
+ wifiFrequency)) {
+ Log.d(getTag(), "Wifi connected to unavailable freq: "
+ + wifiFrequency);
+ return false;
+ }
+ }
+ } else {
+ // The client mode exist but DUT doesn't support
+ // STA + bridged AP, we should fallback to single AP mode.
+ Log.d(getTag(), " STA iface exist but device doesn't support STA + Bridged AP");
+ return false;
+ }
+ }
+
+ // Fallback if the target country code is world mode.
+ if (mCountryCode != null && mCountryCode.equalsIgnoreCase(
+ mResourceCache.getString(
+ R.string.config_wifiDriverWorldModeCountryCode))) {
+ Log.i(getTag(), "Country code changed to world mode - fallback to single AP");
+ return false;
+ }
+
+ // Fall back to Single AP if it's not possible to create a Bridged AP.
+ if (!mWifiNative.isItPossibleToCreateBridgedApIface(mRequestorWs)) {
+ Log.i(getTag(), "Not possible to create bridged AP iface - fallback to single AP");
+ return false;
+ }
+
+ // Fall back to single AP if creating a single AP does not require
+ // destroying an exististng iface, but creating a bridged AP does.
+ if (mWifiNative.shouldDowngradeToSingleApForConcurrency(mRequestorWs)) {
+ Log.d(getTag(), "Creating bridged AP will destroy an existing"
+ + " iface, but single AP will not.");
+ return false;
+ }
+
+ return true;
+ }
+
private class WaitingForDriverCountryCodeChangedState extends RunnerState {
private static final int TIMEOUT_MS = 5_000;
@@ -1439,6 +1461,14 @@ public class SoftApManager implements ActiveModeManager {
ApConfigUtil.updateSoftApCapabilityWithAvailableChannelList(
mCurrentSoftApCapability, mContext, mWifiNative, null);
updateSafeChannelFrequencyList();
+ int[] oldBands = mCurrentSoftApConfiguration.getBands();
+ if (mRole == ROLE_SOFTAP_TETHERED && isBridgedApAvailable()) {
+ mCurrentSoftApConfiguration =
+ ApConfigUtil.upgradeTo2g5gBridgedIfAvailableBandsAreSubset(
+ mCurrentSoftApConfiguration,
+ mCurrentSoftApCapability,
+ mContext);
+ }
if (isBridgedMode()) {
SoftApConfiguration tempConfig =
ApConfigUtil.removeUnavailableBandsFromConfig(
@@ -1450,9 +1480,10 @@ public class SoftApManager implements ActiveModeManager {
return HANDLED;
}
mCurrentSoftApConfiguration = tempConfig;
- if (mCurrentSoftApConfiguration.getBands().length == 1) {
- Log.i(getTag(), "Moving to single AP after updating the CC and band."
- + " Teardown bridged interface and setup single AP interface");
+ if (mCurrentSoftApConfiguration.getBands().length != oldBands.length) {
+ Log.i(getTag(), "Restarting AP interface to accommodate band change"
+ + " from " + Arrays.toString(oldBands) + " to "
+ + Arrays.toString(mCurrentSoftApConfiguration.getBands()));
mWifiNative.teardownInterface(mApInterfaceName);
mApInterfaceName = mWifiNative.setupInterfaceForSoftApMode(
mWifiNativeInterfaceCallback, mRequestorWs,
@@ -2060,8 +2091,10 @@ public class SoftApManager implements ActiveModeManager {
if (instance != null) {
Log.i(getTag(), "receive instanceFailure on " + instance);
removeIfaceInstanceFromBridgedApIface(instance);
- // there is an available instance, keep AP on.
- if (mCurrentSoftApInfoMap.size() == 1) {
+ instances =
+ mWifiNative.getBridgedApInstances(mApInterfaceName);
+ // Check if there's any instance still active.
+ if (instances != null && instances.size() > 0) {
break;
}
} else if (mCurrentSoftApInfoMap.size() == 1 && instances != null
@@ -2300,7 +2333,8 @@ public class SoftApManager implements ActiveModeManager {
mWifiNative.isStaApConcurrencySupported(),
ApConfigUtil.isStaWithBridgedModeSupported(mContext, mWifiNative),
getCurrentStaFreqMhz(),
- securityType);
+ securityType,
+ mRequestorWs);
}
private void writeSoftApStoppedEvent(@StopEvent int stopEvent) {
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java
index 5f377894cb..ae98ccbfdc 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackAidlImpl.java
@@ -318,28 +318,21 @@ class SupplicantStaIfaceCallbackAidlImpl extends ISupplicantStaIfaceCallback.Stu
}
@Override
- public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int reasonCode) {
+ public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int halReasonCode) {
synchronized (mLock) {
mStaIfaceHal.logCallback("onDisconnected");
if (mStaIfaceHal.isVerboseLoggingEnabled()) {
Log.e(TAG, "onDisconnected state=" + mStateBeforeDisconnect
+ " locallyGenerated=" + locallyGenerated
- + " reasonCode=" + reasonCode);
+ + " reasonCode=" + halReasonCode);
}
+ int reasonCode = halToFrameworkReasonCode(halReasonCode);
WifiConfiguration curConfiguration =
mStaIfaceHal.getCurrentNetworkLocalConfig(mIfaceName);
if (curConfiguration != null) {
- // In case of PSK networks the disconnection event in the middle of key exchange
- // happens due to PSK mismatch. But filter out the de-authentication/disassociation
- // frame from AP with known reason codes which are not related to PSK mismatch from
- // reporting wrong password error.
if (mStateBeforeDisconnect == StaIfaceCallbackState.FOURWAY_HANDSHAKE
- && (WifiConfigurationUtil.isConfigForPskNetwork(curConfiguration)
- || WifiConfigurationUtil.isConfigForWapiPskNetwork(
- curConfiguration))
- && (!locallyGenerated
- || (reasonCode != StaIfaceReasonCode.IE_IN_4WAY_DIFFERS
- && reasonCode != StaIfaceReasonCode.DISASSOC_AP_BUSY))) {
+ && NativeUtil.isEapol4WayHandshakeFailureDueToWrongPassword(
+ curConfiguration, locallyGenerated, reasonCode)) {
mWifiMonitor.broadcastAuthenticationFailureEvent(
mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1,
mCurrentSsid, MacAddress.fromBytes(bssid));
@@ -351,7 +344,7 @@ class SupplicantStaIfaceCallbackAidlImpl extends ISupplicantStaIfaceCallback.Stu
}
}
mWifiMonitor.broadcastNetworkDisconnectionEvent(
- mIfaceName, locallyGenerated, halToFrameworkReasonCode(reasonCode),
+ mIfaceName, locallyGenerated, reasonCode,
mCurrentSsid, NativeUtil.macAddressFromByteArray(bssid));
}
}
@@ -1239,6 +1232,9 @@ class SupplicantStaIfaceCallbackAidlImpl extends ISupplicantStaIfaceCallback.Stu
@Override
public void onNetworkNotFound(byte[] ssid) {
mStaIfaceHal.logCallback("onNetworkNotFoundNotification");
+ if (mStaIfaceHal.shouldIgnoreNetworkNotFound(mIfaceName)) {
+ return;
+ }
if (mStaIfaceHal.connectToFallbackSsid(mIfaceName)) {
return;
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java
index da8a38b9e3..facbb7bfe0 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlImpl.java
@@ -276,28 +276,21 @@ abstract class SupplicantStaIfaceCallbackHidlImpl extends ISupplicantStaIfaceCal
}
@Override
- public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int reasonCode) {
+ public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int halReasonCode) {
synchronized (mLock) {
mStaIfaceHal.logCallback("onDisconnected");
if (mStaIfaceHal.isVerboseLoggingEnabled()) {
Log.e(TAG, "onDisconnected state=" + mStateBeforeDisconnect
+ " locallyGenerated=" + locallyGenerated
- + " reasonCode=" + reasonCode);
+ + " reasonCode=" + halReasonCode);
}
+ int reasonCode = halToFrameworkReasonCode(halReasonCode);
WifiConfiguration curConfiguration =
mStaIfaceHal.getCurrentNetworkLocalConfig(mIfaceName);
if (curConfiguration != null) {
- // In case of PSK networks the disconnection event in the middle of key exchange
- // happens due to PSK mismatch. But filter out the de-authentication/disassociation
- // frame from AP with known reason codes which are not related to PSK mismatch from
- // reporting wrong password error.
if (mStateBeforeDisconnect == State.FOURWAY_HANDSHAKE
- && (WifiConfigurationUtil.isConfigForPskNetwork(curConfiguration)
- || WifiConfigurationUtil.isConfigForWapiPskNetwork(
- curConfiguration))
- && (!locallyGenerated
- || (reasonCode != ReasonCode.IE_IN_4WAY_DIFFERS
- && reasonCode != ReasonCode.DISASSOC_AP_BUSY))) {
+ && NativeUtil.isEapol4WayHandshakeFailureDueToWrongPassword(
+ curConfiguration, locallyGenerated, reasonCode)) {
mWifiMonitor.broadcastAuthenticationFailureEvent(
mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD, -1,
mCurrentSsid, MacAddress.fromBytes(bssid));
@@ -309,7 +302,7 @@ abstract class SupplicantStaIfaceCallbackHidlImpl extends ISupplicantStaIfaceCal
}
}
mWifiMonitor.broadcastNetworkDisconnectionEvent(
- mIfaceName, locallyGenerated, halToFrameworkReasonCode(reasonCode),
+ mIfaceName, locallyGenerated, reasonCode,
mCurrentSsid, NativeUtil.macAddressFromByteArray(bssid));
}
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlV1_4Impl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlV1_4Impl.java
index 1cdf26eda1..5ceee6416a 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlV1_4Impl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackHidlV1_4Impl.java
@@ -275,6 +275,9 @@ abstract class SupplicantStaIfaceCallbackHidlV1_4Impl extends
@Override
public void onNetworkNotFound(ArrayList<Byte> ssid) {
mStaIfaceHal.logCallback("onNetworkNotFoundNotification");
+ if (mStaIfaceHal.shouldIgnoreNetworkNotFound(mIfaceName)) {
+ return;
+ }
if (mStaIfaceHal.connectToFallbackSsid(mIfaceName)) {
return;
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
index eb6f4609df..7129609f9b 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
@@ -34,6 +34,7 @@ import java.lang.annotation.RetentionPolicy;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.List;
import java.util.Map;
@@ -119,7 +120,7 @@ public class SupplicantStaIfaceHal {
public static final byte INSUFFICIENT_RSSI = 5;
}
- protected static class StaIfaceReasonCode {
+ public static class StaIfaceReasonCode {
public static final int UNSPECIFIED = 1;
public static final int PREV_AUTH_NOT_VALID = 2;
public static final int DEAUTH_LEAVING = 3;
@@ -1926,37 +1927,28 @@ public class SupplicantStaIfaceHal {
/**
- * Returns a bitmask of advanced capabilities: WPA3 SAE/SUITE B and OWE
- * Bitmask used is:
- * - WIFI_FEATURE_WPA3_SAE
- * - WIFI_FEATURE_WPA3_SUITE_B
- * - WIFI_FEATURE_OWE
- *
- * On error, or if these features are not supported, 0 is returned.
+ * See comments for {@link ISupplicantStaIfaceHal#getAdvancedCapabilities(String)}
*/
- public long getAdvancedCapabilities(@NonNull String ifaceName) {
+ public @NonNull BitSet getAdvancedCapabilities(@NonNull String ifaceName) {
synchronized (mLock) {
String methodStr = "getAdvancedCapabilities";
if (mStaIfaceHal == null) {
handleNullHal(methodStr);
- return 0;
+ return new BitSet();
}
return mStaIfaceHal.getAdvancedCapabilities(ifaceName);
}
}
/**
- * Get the driver supported features through supplicant.
- *
- * @param ifaceName Name of the interface.
- * @return bitmask defined by WifiManager.WIFI_FEATURE_*.
+ * See comments for {@link ISupplicantStaIfaceHal#getWpaDriverFeatureSet(String)}
*/
- public long getWpaDriverFeatureSet(@NonNull String ifaceName) {
+ public @NonNull BitSet getWpaDriverFeatureSet(@NonNull String ifaceName) {
synchronized (mLock) {
String methodStr = "getWpaDriverFeatureSet";
if (mStaIfaceHal == null) {
handleNullHal(methodStr);
- return 0;
+ return new BitSet();
}
return mStaIfaceHal.getWpaDriverFeatureSet(ifaceName);
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java
index 1bcf4b742d..b378188fd6 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java
@@ -33,6 +33,9 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_WAPI;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WFD_R2;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
+import static android.os.Build.VERSION.SDK_INT;
+
+import static com.android.server.wifi.util.GeneralUtil.getCapabilityIndex;
import android.annotation.NonNull;
import android.content.Context;
@@ -87,7 +90,9 @@ import android.net.wifi.SecurityParams;
import android.net.wifi.WifiAnnotations;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiKeystore;
+import android.net.wifi.WifiMigration;
import android.net.wifi.WifiSsid;
+import android.net.wifi.flags.Flags;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
@@ -106,9 +111,8 @@ import com.android.server.wifi.util.NativeUtil;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.Deque;
+import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -132,6 +136,9 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
private static final String HAL_INSTANCE_NAME = ISupplicant.DESCRIPTOR + "/default";
@VisibleForTesting
public static final long WAIT_FOR_DEATH_TIMEOUT_MS = 50L;
+ private static final long INVALID_CONNECT_TO_NETWORK_TIMESTAMP = -1L;
+ @VisibleForTesting
+ public static final long IGNORE_NETWORK_NOT_FOUND_DURATION_MS = 1000L;
/**
* Regex pattern for extracting the wps device type bytes.
@@ -154,8 +161,9 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
private Map<String, SupplicantStaNetworkHalAidlImpl>
mCurrentNetworkRemoteHandles = new HashMap<>();
private Map<String, WifiConfiguration> mCurrentNetworkLocalConfigs = new HashMap<>();
- private Map<String, Deque<WifiSsid>> mCurrentNetworkFallbackSsids = new HashMap<>();
- private Map<String, WifiSsid> mCurrentNetworkFirstSsid = new HashMap<>();
+ private Map<String, Long> mCurrentNetworkConnectTimestamp = new HashMap<>();
+ private Map<String, List<WifiSsid>> mCurrentNetworkFallbackSsids = new HashMap<>();
+ private Map<String, Integer> mCurrentNetworkFallbackSsidIndex = new HashMap<>();
private Map<String, List<Pair<SupplicantStaNetworkHalAidlImpl, WifiConfiguration>>>
mLinkedNetworkLocalAndRemoteConfigs = new HashMap<>();
@VisibleForTesting
@@ -176,6 +184,9 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
private SupplicantStaIfaceHal.QosScsResponseCallback mQosScsResponseCallback;
private MscsParams mLastMscsParams;
+ @VisibleForTesting
+ protected boolean mHasMigratedLegacyKeystoreAliases = false;
+
private class SupplicantDeathRecipient implements DeathRecipient {
@Override
public void binderDied() {
@@ -435,6 +446,9 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
mCurrentNetworkRemoteHandles.clear();
mLinkedNetworkLocalAndRemoteConfigs.clear();
mNonStandardCertCallback = null;
+ mCurrentNetworkConnectTimestamp.clear();
+ mCurrentNetworkFallbackSsidIndex.clear();
+ mCurrentNetworkFallbackSsids.clear();
}
}
@@ -642,24 +656,48 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
/**
+ * Returns whether to ignore the NETWORK_NOT_FOUND event in case it is based on stale cached
+ * scans.
+ *
+ * @param ifaceName Name of the interface.
+ * @return true if we should ignore NETWORK_NOT_FOUND, false otherwise
+ */
+ public boolean shouldIgnoreNetworkNotFound(@NonNull String ifaceName) {
+ synchronized (mLock) {
+ return (mClock.getElapsedSinceBootMillis()
+ - mCurrentNetworkConnectTimestamp.getOrDefault(
+ ifaceName, INVALID_CONNECT_TO_NETWORK_TIMESTAMP)
+ < IGNORE_NETWORK_NOT_FOUND_DURATION_MS);
+ }
+ }
+
+ /**
* Connects to the next fallback SSID (if any) of the current network upon a network not found
* notification. If all the fallback SSIDs have been tried, return to the first SSID and go
* through the fallbacks again.
*
- * Returns false if there's no fallback SSID to connect to, or if we've wrapped back to the
- * first SSID.
+ * @return true if we're connecting to a fallback SSID, false if there are no fallback SSIDs, or
+ * we've looped back to the first SSID.
*/
public boolean connectToFallbackSsid(@NonNull String ifaceName) {
synchronized (mLock) {
- Deque<WifiSsid> fallbackSsids = mCurrentNetworkFallbackSsids.get(ifaceName);
+ List<WifiSsid> fallbackSsids = mCurrentNetworkFallbackSsids.get(ifaceName);
if (fallbackSsids == null || fallbackSsids.isEmpty()) {
return false;
}
- WifiSsid nextSsid = fallbackSsids.removeFirst();
- fallbackSsids.addLast(nextSsid);
- Log.d(TAG, "connectToFallbackSsid " + nextSsid);
+ // Select the next fallback ssid.
+ // Note that the very first SSID we connect to is index 0, so the next SSID (i.e the
+ // first fallback SSID) will start with index 1. Once the entire list has been tried,
+ // wrap back to the first SSID at index 0.
+ int nextIndex = mCurrentNetworkFallbackSsidIndex.getOrDefault(ifaceName, 0) + 1;
+ if (nextIndex >= fallbackSsids.size()) {
+ nextIndex = 0;
+ }
+ mCurrentNetworkFallbackSsidIndex.put(ifaceName, nextIndex);
+ WifiSsid nextSsid = fallbackSsids.get(nextIndex);
+ Log.d(TAG, "connectToFallbackSsid " + nextSsid + " at index " + nextIndex);
connectToNetwork(ifaceName, getCurrentNetworkLocalConfig(ifaceName), nextSsid);
- return !Objects.equals(nextSsid, mCurrentNetworkFirstSsid.get(ifaceName));
+ return nextIndex != 0;
}
}
@@ -715,7 +753,7 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
supplicantConfig.SSID = actualSsid.toString();
} else {
mCurrentNetworkFallbackSsids.remove(ifaceName);
- mCurrentNetworkFirstSsid.remove(ifaceName);
+ mCurrentNetworkFallbackSsidIndex.remove(ifaceName);
if (config.SSID != null) {
// No actual SSID supplied, so select from the network selection BSSID
// or the latest candidate BSSID.
@@ -725,15 +763,15 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
Log.d(TAG, "Selecting supplicant SSID " + supplicantSsid);
supplicantConfig.SSID = supplicantSsid.toString();
- Deque<WifiSsid> fallbackSsids = new ArrayDeque<>(mSsidTranslator
- .getAllPossibleOriginalSsids(configSsid));
+ List<WifiSsid> fallbackSsids = mSsidTranslator
+ .getAllPossibleOriginalSsids(configSsid);
fallbackSsids.remove(supplicantSsid);
if (!fallbackSsids.isEmpty()) {
// Store the unused SSIDs to fallback on in
// connectToFallbackSsid(String) if the chosen SSID isn't found.
- fallbackSsids.addLast(supplicantSsid);
+ fallbackSsids.add(0, supplicantSsid);
mCurrentNetworkFallbackSsids.put(ifaceName, fallbackSsids);
- mCurrentNetworkFirstSsid.put(ifaceName, supplicantSsid);
+ mCurrentNetworkFallbackSsidIndex.put(ifaceName, 0);
}
}
// Set the actual translation of the original SSID in case the untranslated
@@ -779,6 +817,7 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
Log.e(TAG, "Failed to select network configuration: " + config.getProfileKey());
return false;
}
+ mCurrentNetworkConnectTimestamp.put(ifaceName, mClock.getElapsedSinceBootMillis());
return true;
}
}
@@ -893,6 +932,9 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
if (networkHandle == null) {
return false;
}
+ Log.d(TAG, "Remove fallback ssids to avoid endless loop");
+ mCurrentNetworkFallbackSsids.remove(ifaceName);
+ mCurrentNetworkFallbackSsidIndex.remove(ifaceName);
return networkHandle.disable();
}
}
@@ -2543,29 +2585,24 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
/**
- * Returns a bitmask of advanced capabilities: WPA3 SAE/SUITE B and OWE
- * Bitmask used is:
- * - WIFI_FEATURE_WPA3_SAE
- * - WIFI_FEATURE_WPA3_SUITE_B
- * - WIFI_FEATURE_OWE
- *
- * @return true if successful, false otherwise.
+ * See comments for {@link ISupplicantStaIfaceHal#getAdvancedCapabilities(String)}
*/
- public long getAdvancedCapabilities(@NonNull String ifaceName) {
+ public @NonNull BitSet getAdvancedCapabilities(@NonNull String ifaceName) {
synchronized (mLock) {
final String methodStr = "getAdvancedCapabilities";
- long advancedCapabilities = 0;
+ BitSet advancedCapabilities = new BitSet();
int keyMgmtCapabilities = getKeyMgmtCapabilities(ifaceName);
- advancedCapabilities |= WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS
- | WIFI_FEATURE_DECORATED_IDENTITY;
+ advancedCapabilities.set(
+ getCapabilityIndex(WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS));
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_DECORATED_IDENTITY));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": Passpoint T&C supported");
Log.v(TAG, methodStr + ": RFC 7542 decorated identity supported");
}
if ((keyMgmtCapabilities & KeyMgmtMask.SAE) != 0) {
- advancedCapabilities |= WIFI_FEATURE_WPA3_SAE;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_WPA3_SAE));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": SAE supported");
@@ -2573,7 +2610,7 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
if ((keyMgmtCapabilities & KeyMgmtMask.SUITE_B_192) != 0) {
- advancedCapabilities |= WIFI_FEATURE_WPA3_SUITE_B;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_WPA3_SUITE_B));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": SUITE_B supported");
@@ -2581,7 +2618,7 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
if ((keyMgmtCapabilities & KeyMgmtMask.OWE) != 0) {
- advancedCapabilities |= WIFI_FEATURE_OWE;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_OWE));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": OWE supported");
@@ -2589,8 +2626,8 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
if ((keyMgmtCapabilities & KeyMgmtMask.DPP) != 0) {
- advancedCapabilities |= WIFI_FEATURE_DPP
- | WIFI_FEATURE_DPP_ENROLLEE_RESPONDER;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_DPP));
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_DPP_ENROLLEE_RESPONDER));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": DPP supported");
@@ -2599,7 +2636,7 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
if ((keyMgmtCapabilities & KeyMgmtMask.WAPI_PSK) != 0) {
- advancedCapabilities |= WIFI_FEATURE_WAPI;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_WAPI));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": WAPI supported");
@@ -2607,7 +2644,7 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
if ((keyMgmtCapabilities & KeyMgmtMask.FILS_SHA256) != 0) {
- advancedCapabilities |= WIFI_FEATURE_FILS_SHA256;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_FILS_SHA256));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": FILS_SHA256 supported");
@@ -2615,7 +2652,7 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
if ((keyMgmtCapabilities & KeyMgmtMask.FILS_SHA384) != 0) {
- advancedCapabilities |= WIFI_FEATURE_FILS_SHA384;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_FILS_SHA384));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": FILS_SHA384 supported");
@@ -2652,21 +2689,21 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
}
- private long aidlWpaDrvFeatureSetToFrameworkV2(int drvCapabilitiesMask) {
- if (!isServiceVersionAtLeast(2)) return 0;
+ private BitSet aidlWpaDrvFeatureSetToFrameworkV2(int drvCapabilitiesMask) {
+ if (!isServiceVersionAtLeast(2)) return new BitSet();
final String methodStr = "getWpaDriverFeatureSetV2";
- long featureSet = 0;
+ BitSet featureSet = new BitSet();
if ((drvCapabilitiesMask & WpaDriverCapabilitiesMask.SET_TLS_MINIMUM_VERSION) != 0) {
- featureSet |= WIFI_FEATURE_SET_TLS_MINIMUM_VERSION;
+ featureSet.set(getCapabilityIndex(WIFI_FEATURE_SET_TLS_MINIMUM_VERSION));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": EAP-TLS minimum version supported");
}
}
if ((drvCapabilitiesMask & WpaDriverCapabilitiesMask.TLS_V1_3) != 0) {
- featureSet |= WIFI_FEATURE_TLS_V1_3;
+ featureSet.set(getCapabilityIndex(WIFI_FEATURE_TLS_V1_3));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": EAP-TLS v1.3 supported");
}
@@ -2675,24 +2712,21 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
/**
- * Get the driver supported features through supplicant.
- *
- * @param ifaceName Name of the interface.
- * @return bitmask defined by WifiManager.WIFI_FEATURE_*.
+ * See comments for {@link ISupplicantStaIfaceHal#getWpaDriverFeatureSet(String)}
*/
- public long getWpaDriverFeatureSet(@NonNull String ifaceName) {
+ public @NonNull BitSet getWpaDriverFeatureSet(@NonNull String ifaceName) {
synchronized (mLock) {
final String methodStr = "getWpaDriverFeatureSet";
int drvCapabilitiesMask = getWpaDriverCapabilities(ifaceName);
- long featureSet = 0;
+ BitSet featureSet = new BitSet();
if ((drvCapabilitiesMask & WpaDriverCapabilitiesMask.MBO) != 0) {
- featureSet |= WIFI_FEATURE_MBO;
+ featureSet.set(getCapabilityIndex(WIFI_FEATURE_MBO));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": MBO supported");
}
if ((drvCapabilitiesMask & WpaDriverCapabilitiesMask.OCE) != 0) {
- featureSet |= WIFI_FEATURE_OCE;
+ featureSet.set(getCapabilityIndex(WIFI_FEATURE_OCE));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": OCE supported");
}
@@ -2700,14 +2734,14 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
}
if ((drvCapabilitiesMask & WpaDriverCapabilitiesMask.SAE_PK) != 0) {
- featureSet |= WIFI_FEATURE_SAE_PK;
+ featureSet.set(getCapabilityIndex(WIFI_FEATURE_SAE_PK));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": SAE-PK supported");
}
}
if ((drvCapabilitiesMask & WpaDriverCapabilitiesMask.WFD_R2) != 0) {
- featureSet |= WIFI_FEATURE_WFD_R2;
+ featureSet.set(getCapabilityIndex(WIFI_FEATURE_WFD_R2));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": WFD-R2 supported");
}
@@ -2715,13 +2749,13 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
if ((drvCapabilitiesMask
& WpaDriverCapabilitiesMask.TRUST_ON_FIRST_USE) != 0) {
- featureSet |= WIFI_FEATURE_TRUST_ON_FIRST_USE;
+ featureSet.set(getCapabilityIndex(WIFI_FEATURE_TRUST_ON_FIRST_USE));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": Trust-On-First-Use supported");
}
}
- featureSet |= aidlWpaDrvFeatureSetToFrameworkV2(drvCapabilitiesMask);
+ featureSet.or(aidlWpaDrvFeatureSetToFrameworkV2(drvCapabilitiesMask));
return featureSet;
}
@@ -4038,6 +4072,13 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal {
return;
}
+ // TODO: Use SdkLevel API when it exists, rather than the SDK_INT
+ if (!mHasMigratedLegacyKeystoreAliases && SDK_INT >= 36
+ && Flags.legacyKeystoreToWifiBlobstoreMigrationReadOnly()) {
+ WifiMigration.migrateLegacyKeystoreToWifiBlobstore();
+ mHasMigratedLegacyKeystoreAliases = true;
+ }
+
try {
INonStandardCertCallback tempCallback = new NonStandardCertCallback();
mISupplicant.registerNonStandardCertCallback(tempCallback);
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java
index fbd031259d..c98e23af3a 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHalHidlImpl.java
@@ -30,6 +30,8 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_WFD_R2;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
+import static com.android.server.wifi.util.GeneralUtil.getCapabilityIndex;
+
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.wifi.V1_0.WifiChannelWidthInMhz;
@@ -73,9 +75,8 @@ import com.android.server.wifi.util.NativeUtil;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.Deque;
+import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -101,6 +102,9 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
public static final String HAL_INSTANCE_NAME = "default";
@VisibleForTesting
public static final long WAIT_FOR_DEATH_TIMEOUT_MS = 50L;
+ private static final long INVALID_CONNECT_TO_NETWORK_TIMESTAMP = -1L;
+ @VisibleForTesting
+ public static final long IGNORE_NETWORK_NOT_FOUND_DURATION_MS = 1000L;
/**
* Regex pattern for extracting the wps device type bytes.
* Matches a strings like the following: "<categ>-<OUI>-<subcateg>";
@@ -121,8 +125,9 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
private Map<String, SupplicantStaNetworkHalHidlImpl> mCurrentNetworkRemoteHandles =
new HashMap<>();
private Map<String, WifiConfiguration> mCurrentNetworkLocalConfigs = new HashMap<>();
- private Map<String, Deque<WifiSsid>> mCurrentNetworkFallbackSsids = new HashMap<>();
- private Map<String, WifiSsid> mCurrentNetworkFirstSsid = new HashMap<>();
+ private Map<String, Long> mCurrentNetworkConnectTimestamp = new HashMap<>();
+ private Map<String, List<WifiSsid>> mCurrentNetworkFallbackSsids = new HashMap<>();
+ private Map<String, Integer> mCurrentNetworkFallbackSsidIndex = new HashMap<>();
private Map<String, List<Pair<SupplicantStaNetworkHalHidlImpl, WifiConfiguration>>>
mLinkedNetworkLocalAndRemoteConfigs = new HashMap<>();
@VisibleForTesting
@@ -644,6 +649,9 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
mCurrentNetworkLocalConfigs.clear();
mCurrentNetworkRemoteHandles.clear();
mLinkedNetworkLocalAndRemoteConfigs.clear();
+ mCurrentNetworkConnectTimestamp.clear();
+ mCurrentNetworkFallbackSsidIndex.clear();
+ mCurrentNetworkFallbackSsids.clear();
}
}
@@ -976,24 +984,48 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
}
/**
+ * Returns whether to ignore the NETWORK_NOT_FOUND event in case it is based on stale cached
+ * scans.
+ *
+ * @param ifaceName Name of the interface.
+ * @return true if we should ignore NETWORK_NOT_FOUND, false otherwise
+ */
+ public boolean shouldIgnoreNetworkNotFound(@NonNull String ifaceName) {
+ synchronized (mLock) {
+ return mClock.getElapsedSinceBootMillis()
+ - mCurrentNetworkConnectTimestamp.getOrDefault(
+ ifaceName, INVALID_CONNECT_TO_NETWORK_TIMESTAMP)
+ < IGNORE_NETWORK_NOT_FOUND_DURATION_MS;
+ }
+ }
+
+ /**
* Connects to the next fallback SSID (if any) of the current network upon a network not found
* notification. If all the fallback SSIDs have been tried, return to the first SSID and go
* through the fallbacks again.
*
- * Returns false if there's no fallback SSID to connect to, or if we've wrapped back to the
- * first SSID.
+ * @return true if we're connecting to a fallback SSID, false if there are no fallback SSIDs, or
+ * we've looped back to the first SSID.
*/
public boolean connectToFallbackSsid(@NonNull String ifaceName) {
synchronized (mLock) {
- Deque<WifiSsid> fallbackSsids = mCurrentNetworkFallbackSsids.get(ifaceName);
+ List<WifiSsid> fallbackSsids = mCurrentNetworkFallbackSsids.get(ifaceName);
if (fallbackSsids == null || fallbackSsids.isEmpty()) {
return false;
}
- WifiSsid nextSsid = fallbackSsids.removeFirst();
- fallbackSsids.addLast(nextSsid);
- Log.d(TAG, "connectToFallbackSsid " + nextSsid);
+ // Select the next fallback ssid.
+ // Note that the very first SSID we connect to is index 0, so the next SSID (i.e the
+ // first fallback SSID) will start with index 1. Once the entire list has been tried,
+ // wrap back to the first SSID at index 0.
+ int nextIndex = mCurrentNetworkFallbackSsidIndex.getOrDefault(ifaceName, 0) + 1;
+ if (nextIndex >= fallbackSsids.size()) {
+ nextIndex = 0;
+ }
+ mCurrentNetworkFallbackSsidIndex.put(ifaceName, nextIndex);
+ WifiSsid nextSsid = fallbackSsids.get(nextIndex);
+ Log.d(TAG, "connectToFallbackSsid " + nextSsid + " at index " + nextIndex);
connectToNetwork(ifaceName, getCurrentNetworkLocalConfig(ifaceName), nextSsid);
- return !Objects.equals(nextSsid, mCurrentNetworkFirstSsid.get(ifaceName));
+ return nextIndex != 0;
}
}
@@ -1049,7 +1081,7 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
supplicantConfig.SSID = actualSsid.toString();
} else {
mCurrentNetworkFallbackSsids.remove(ifaceName);
- mCurrentNetworkFirstSsid.remove(ifaceName);
+ mCurrentNetworkFallbackSsidIndex.remove(ifaceName);
if (config.SSID != null) {
// No actual SSID supplied, so select from the network selection BSSID
// or the latest candidate BSSID.
@@ -1059,15 +1091,15 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
Log.d(TAG, "Selecting supplicant SSID " + supplicantSsid);
supplicantConfig.SSID = supplicantSsid.toString();
- Deque<WifiSsid> fallbackSsids = new ArrayDeque<>(mSsidTranslator
- .getAllPossibleOriginalSsids(configSsid));
+ List<WifiSsid> fallbackSsids = mSsidTranslator
+ .getAllPossibleOriginalSsids(configSsid);
fallbackSsids.remove(supplicantSsid);
if (!fallbackSsids.isEmpty()) {
// Store the unused SSIDs to fallback on in
// connectToFallbackSsid(String) if the chosen SSID isn't found.
- fallbackSsids.addLast(supplicantSsid);
+ fallbackSsids.add(0, supplicantSsid);
mCurrentNetworkFallbackSsids.put(ifaceName, fallbackSsids);
- mCurrentNetworkFirstSsid.put(ifaceName, supplicantSsid);
+ mCurrentNetworkFallbackSsidIndex.put(ifaceName, 0);
}
}
// Set the actual translation of the original SSID in case the untranslated
@@ -1111,6 +1143,7 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
loge("Failed to select network configuration: " + config.getProfileKey());
return false;
}
+ mCurrentNetworkConnectTimestamp.put(ifaceName, mClock.getElapsedSinceBootMillis());
return true;
}
}
@@ -1222,6 +1255,9 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
SupplicantStaNetworkHalHidlImpl networkHandle =
checkSupplicantStaNetworkAndLogFailure(ifaceName, "disableCurrentNetwork");
if (networkHandle == null) return false;
+ Log.d(TAG, "Remove fallback ssids to avoid endless loop");
+ mCurrentNetworkFallbackSsids.remove(ifaceName);
+ mCurrentNetworkFallbackSsidIndex.remove(ifaceName);
return networkHandle.disable();
}
}
@@ -2925,24 +2961,20 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
}
/**
- * Returns a bitmask of advanced capabilities: WPA3 SAE/SUITE B and OWE
- * Bitmask used is:
- * - WIFI_FEATURE_WPA3_SAE
- * - WIFI_FEATURE_WPA3_SUITE_B
- * - WIFI_FEATURE_OWE
+ * See comments for {@link ISupplicantStaIfaceHal#getAdvancedCapabilities(String)}
*
* This is a v1.2+ HAL feature.
- * On error, or if these features are not supported, 0 is returned.
+ * On error, or if these features are not supported, an empty BitSet is returned.
*/
- public long getAdvancedCapabilities(@NonNull String ifaceName) {
+ public @NonNull BitSet getAdvancedCapabilities(@NonNull String ifaceName) {
final String methodStr = "getAdvancedCapabilities";
- long advancedCapabilities = 0;
+ BitSet advancedCapabilities = new BitSet();
int keyMgmtCapabilities = getKeyMgmtCapabilities(ifaceName);
if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
.KeyMgmtMask.SAE) != 0) {
- advancedCapabilities |= WIFI_FEATURE_WPA3_SAE;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_WPA3_SAE));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": SAE supported");
@@ -2951,7 +2983,7 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
.KeyMgmtMask.SUITE_B_192) != 0) {
- advancedCapabilities |= WIFI_FEATURE_WPA3_SUITE_B;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_WPA3_SUITE_B));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": SUITE_B supported");
@@ -2960,7 +2992,7 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
.KeyMgmtMask.OWE) != 0) {
- advancedCapabilities |= WIFI_FEATURE_OWE;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_OWE));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": OWE supported");
@@ -2969,13 +3001,13 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
.KeyMgmtMask.DPP) != 0) {
- advancedCapabilities |= WIFI_FEATURE_DPP;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_DPP));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": DPP supported");
}
if (isV1_4()) {
- advancedCapabilities |= WIFI_FEATURE_DPP_ENROLLEE_RESPONDER;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_DPP_ENROLLEE_RESPONDER));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": DPP ENROLLEE RESPONDER supported");
}
@@ -2983,8 +3015,9 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
}
if (isV1_4()) {
- advancedCapabilities |= WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS
- | WIFI_FEATURE_DECORATED_IDENTITY;
+ advancedCapabilities.set(
+ getCapabilityIndex(WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS));
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_DECORATED_IDENTITY));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": Passpoint T&C supported");
Log.v(TAG, methodStr + ": RFC 7542 decorated identity supported");
@@ -2993,7 +3026,7 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
.KeyMgmtMask.WAPI_PSK) != 0) {
- advancedCapabilities |= WIFI_FEATURE_WAPI;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_WAPI));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": WAPI supported");
@@ -3002,7 +3035,7 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
.KeyMgmtMask.FILS_SHA256) != 0) {
- advancedCapabilities |= WIFI_FEATURE_FILS_SHA256;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_FILS_SHA256));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": FILS_SHA256 supported");
@@ -3010,7 +3043,7 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
}
if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
.KeyMgmtMask.FILS_SHA384) != 0) {
- advancedCapabilities |= WIFI_FEATURE_FILS_SHA384;
+ advancedCapabilities.set(getCapabilityIndex(WIFI_FEATURE_FILS_SHA384));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": FILS_SHA384 supported");
@@ -3164,15 +3197,12 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
}
/**
- * Get the driver supported features through supplicant.
- *
- * @param ifaceName Name of the interface.
- * @return bitmask defined by WifiManager.WIFI_FEATURE_*.
+ * See comments for {@link ISupplicantStaIfaceHal#getWpaDriverFeatureSet(String)}
*/
- public long getWpaDriverFeatureSet(@NonNull String ifaceName) {
+ public @NonNull BitSet getWpaDriverFeatureSet(@NonNull String ifaceName) {
final String methodStr = "getWpaDriverFeatureSet";
Mutable<Integer> drvCapabilitiesMask = new Mutable<>(0);
- long featureSet = 0;
+ BitSet featureSet = new BitSet();
if (isV1_4()) {
drvCapabilitiesMask = getWpaDriverCapabilities_1_4(ifaceName);
@@ -3180,17 +3210,17 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
drvCapabilitiesMask = getWpaDriverCapabilities_1_3(ifaceName);
} else {
Log.i(TAG, "Method " + methodStr + " is not supported in existing HAL");
- return 0;
+ return new BitSet();
}
if ((drvCapabilitiesMask.value & WpaDriverCapabilitiesMask.MBO) != 0) {
- featureSet |= WIFI_FEATURE_MBO;
+ featureSet.set(getCapabilityIndex(WIFI_FEATURE_MBO));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": MBO supported");
}
if ((drvCapabilitiesMask.value
& WpaDriverCapabilitiesMask.OCE) != 0) {
- featureSet |= WIFI_FEATURE_OCE;
+ featureSet.set(getCapabilityIndex(WIFI_FEATURE_OCE));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": OCE supported");
}
@@ -3199,7 +3229,7 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
if ((drvCapabilitiesMask.value
& android.hardware.wifi.supplicant.V1_4.WpaDriverCapabilitiesMask.SAE_PK) != 0) {
- featureSet |= WIFI_FEATURE_SAE_PK;
+ featureSet.set(getCapabilityIndex(WIFI_FEATURE_SAE_PK));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": SAE-PK supported");
}
@@ -3207,7 +3237,7 @@ public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal {
if ((drvCapabilitiesMask.value
& android.hardware.wifi.supplicant.V1_4.WpaDriverCapabilitiesMask.WFD_R2) != 0) {
- featureSet |= WIFI_FEATURE_WFD_R2;
+ featureSet.set(getCapabilityIndex(WIFI_FEATURE_WFD_R2));
if (mVerboseLoggingEnabled) {
Log.v(TAG, methodStr + ": WFD-R2 supported");
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java
index 3c1a8b4993..3a0a810003 100644
--- a/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java
@@ -16,6 +16,11 @@
package com.android.server.wifi;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_TLS_V1_3;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
+
+import static com.android.server.wifi.util.GeneralUtil.getCapabilityIndex;
+
import android.annotation.NonNull;
import android.content.Context;
import android.hardware.wifi.supplicant.AuthAlgMask;
@@ -38,7 +43,6 @@ import android.net.wifi.OuiKeyedData;
import android.net.wifi.SecurityParams;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
-import android.net.wifi.WifiManager;
import android.net.wifi.WifiSsid;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -151,13 +155,13 @@ public class SupplicantStaNetworkHalAidlImpl {
private String mEapDomainSuffixMatch;
private @WifiEnterpriseConfig.Ocsp int mOcsp;
private String mWapiCertSuite;
- private long mAdvanceKeyMgmtFeatures;
- private long mWpaDriverFeatures;
+ private BitSet mAdvanceKeyMgmtFeatures;
+ private BitSet mWpaDriverFeatures;
SupplicantStaNetworkHalAidlImpl(int serviceVersion,
ISupplicantStaNetwork staNetwork, String ifaceName,
Context context, WifiMonitor monitor, WifiGlobals wifiGlobals,
- long advanceKeyMgmtFeature, long wpaDriverFeatures) {
+ BitSet advanceKeyMgmtFeature, BitSet wpaDriverFeatures) {
mServiceVersion = serviceVersion;
mISupplicantStaNetwork = staNetwork;
mContext = context;
@@ -884,7 +888,7 @@ public class SupplicantStaNetworkHalAidlImpl {
private int getOptimalMinimumTlsVersion(WifiEnterpriseConfig enterpriseConfig) {
int maxTlsVersionSupported = WifiEnterpriseConfig.TLS_V1_2;
- if ((mWpaDriverFeatures & WifiManager.WIFI_FEATURE_TLS_V1_3) != 0) {
+ if (mWpaDriverFeatures.get(getCapabilityIndex(WIFI_FEATURE_TLS_V1_3))) {
maxTlsVersionSupported = WifiEnterpriseConfig.TLS_V1_3;
}
@@ -1044,8 +1048,8 @@ public class SupplicantStaNetworkHalAidlImpl {
mask |= GroupCipherMask.GTK_NOT_USED;
break;
case WifiConfiguration.GroupCipher.GCMP_256:
- if (0 == (mAdvanceKeyMgmtFeatures
- & WifiManager.WIFI_FEATURE_WPA3_SUITE_B)) {
+ if (!mAdvanceKeyMgmtFeatures.get(
+ getCapabilityIndex(WIFI_FEATURE_WPA3_SUITE_B))) {
Log.d(TAG, "Ignore unsupported GCMP_256 cipher.");
break;
}
@@ -1106,8 +1110,8 @@ public class SupplicantStaNetworkHalAidlImpl {
mask |= PairwiseCipherMask.CCMP;
break;
case WifiConfiguration.PairwiseCipher.GCMP_256:
- if (0 == (mAdvanceKeyMgmtFeatures
- & WifiManager.WIFI_FEATURE_WPA3_SUITE_B)) {
+ if (!mAdvanceKeyMgmtFeatures.get(
+ getCapabilityIndex(WIFI_FEATURE_WPA3_SUITE_B))) {
Log.d(TAG, "Ignore unsupporting GCMP_256 cipher.");
break;
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaNetworkHalHidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaNetworkHalHidlImpl.java
index 7e2d2e3567..896019f5ac 100644
--- a/service/java/com/android/server/wifi/SupplicantStaNetworkHalHidlImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantStaNetworkHalHidlImpl.java
@@ -15,6 +15,10 @@
*/
package com.android.server.wifi;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
+
+import static com.android.server.wifi.util.GeneralUtil.getCapabilityIndex;
+
import android.content.Context;
import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork;
import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetworkCallback;
@@ -24,7 +28,6 @@ import android.net.wifi.SecurityParams;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiEnterpriseConfig.Ocsp;
-import android.net.wifi.WifiManager;
import android.net.wifi.WifiSsid;
import android.os.RemoteException;
import android.text.TextUtils;
@@ -134,11 +137,11 @@ public class SupplicantStaNetworkHalHidlImpl {
private String mEapDomainSuffixMatch;
private @Ocsp int mOcsp;
private String mWapiCertSuite;
- private long mAdvanceKeyMgmtFeatures;
+ private BitSet mAdvanceKeyMgmtFeatures;
SupplicantStaNetworkHalHidlImpl(ISupplicantStaNetwork iSupplicantStaNetwork, String ifaceName,
Context context, WifiMonitor monitor, WifiGlobals wifiGlobals,
- long advanceKeyMgmtFeature) {
+ BitSet advanceKeyMgmtFeature) {
mISupplicantStaNetwork = iSupplicantStaNetwork;
mContext = context;
mIfaceName = ifaceName;
@@ -991,7 +994,8 @@ public class SupplicantStaNetworkHalHidlImpl {
Log.d(TAG, "Ignore GCMP_256 cipher for the HAL older than 1.2.");
break;
}
- if (0 == (mAdvanceKeyMgmtFeatures & WifiManager.WIFI_FEATURE_WPA3_SUITE_B)) {
+ if (!mAdvanceKeyMgmtFeatures.get(
+ getCapabilityIndex(WIFI_FEATURE_WPA3_SUITE_B))) {
Log.d(TAG, "Ignore unsupporting GCMP_256 cipher.");
break;
}
@@ -1068,7 +1072,8 @@ public class SupplicantStaNetworkHalHidlImpl {
Log.d(TAG, "Ignore GCMP_256 cipher for the HAL older than 1.2.");
break;
}
- if (0 == (mAdvanceKeyMgmtFeatures & WifiManager.WIFI_FEATURE_WPA3_SUITE_B)) {
+ if (!mAdvanceKeyMgmtFeatures.get(
+ getCapabilityIndex(WIFI_FEATURE_WPA3_SUITE_B))) {
Log.d(TAG, "Ignore unsupporting GCMP_256 cipher.");
break;
}
diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java
index f4d062279b..d5167ac57a 100644
--- a/service/java/com/android/server/wifi/WifiApConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiApConfigStore.java
@@ -32,7 +32,9 @@ import android.net.MacAddress;
import android.net.wifi.SoftApCapability;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApConfiguration.BandType;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiSsid;
+import android.net.wifi.util.WifiResourceCache;
import android.os.Handler;
import android.os.Process;
import android.text.TextUtils;
@@ -79,7 +81,7 @@ public class WifiApConfigStore {
private SoftApConfiguration mPersistentWifiApConfig = null;
private String mLastConfiguredPassphrase = null;
- private final Context mContext;
+ private final WifiContext mContext;
private final Handler mHandler;
private final WifiMetrics mWifiMetrics;
private final BackupManagerProxy mBackupManagerProxy;
@@ -95,6 +97,7 @@ public class WifiApConfigStore {
private int mForcedApChannel;
private int mForcedApMaximumChannelBandWidth;
private final boolean mIsAutoAppendLowerBandEnabled;
+ private final WifiResourceCache mResourceCache;
/**
* Module to interact with the wifi config store.
@@ -125,7 +128,7 @@ public class WifiApConfigStore {
}
}
- WifiApConfigStore(Context context,
+ WifiApConfigStore(WifiContext context,
WifiInjector wifiInjector,
Handler handler,
BackupManagerProxy backupManagerProxy,
@@ -147,7 +150,8 @@ public class WifiApConfigStore {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_HOTSPOT_CONFIG_USER_TAPPED_CONTENT);
mMacAddressUtil = wifiInjector.getMacAddressUtil();
- mIsAutoAppendLowerBandEnabled = mContext.getResources().getBoolean(
+ mResourceCache = context.getResourceCache();
+ mIsAutoAppendLowerBandEnabled = mResourceCache.getBoolean(
R.bool.config_wifiSoftapAutoAppendLowerBandsToBandConfigurationEnabled);
mHalDeviceManager = wifiInjector.getHalDeviceManager();
mWifiSettingsConfigStore = wifiInjector.getSettingsConfigStore();
@@ -240,7 +244,7 @@ public class WifiApConfigStore {
@NonNull SoftApConfiguration config) {
SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(config);
if (SdkLevel.isAtLeastS() && ApConfigUtil.isBridgedModeSupported(mContext, mWifiNative)
- && config.getBands().length == 1 && mContext.getResources().getBoolean(
+ && config.getBands().length == 1 && mResourceCache.getBoolean(
R.bool.config_wifiSoftapAutoUpgradeToBridgedConfigWhenSupported)) {
int[] dual_bands = new int[] {
SoftApConfiguration.BAND_2GHZ,
@@ -274,7 +278,7 @@ public class WifiApConfigStore {
@NonNull SoftApConfiguration config) {
SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(config);
if ((!ApConfigUtil.isClientForceDisconnectSupported(mContext)
- || mContext.getResources().getBoolean(
+ || mResourceCache.getBoolean(
R.bool.config_wifiSoftapResetUserControlConfig))
&& (config.isClientControlByUserEnabled()
|| config.getBlockedClientList().size() != 0)) {
@@ -284,7 +288,7 @@ public class WifiApConfigStore {
}
if ((!ApConfigUtil.isClientForceDisconnectSupported(mContext)
- || mContext.getResources().getBoolean(
+ || mResourceCache.getBoolean(
R.bool.config_wifiSoftapResetMaxClientSettingConfig))
&& config.getMaxNumberOfClients() != 0) {
configBuilder.setMaxNumberOfClients(0);
@@ -304,7 +308,7 @@ public class WifiApConfigStore {
Log.i(TAG, "Device doesn't support WPA3-SAE, reset config to WPA2");
}
- if (mContext.getResources().getBoolean(R.bool.config_wifiSoftapResetChannelConfig)
+ if (mResourceCache.getBoolean(R.bool.config_wifiSoftapResetChannelConfig)
&& config.getChannel() != 0) {
// The device might not support customize channel or forced channel might not
// work in some countries. Need to reset it.
@@ -339,13 +343,13 @@ public class WifiApConfigStore {
}
}
- if (mContext.getResources().getBoolean(R.bool.config_wifiSoftapResetHiddenConfig)
+ if (mResourceCache.getBoolean(R.bool.config_wifiSoftapResetHiddenConfig)
&& config.isHiddenSsid()) {
configBuilder.setHiddenSsid(false);
Log.i(TAG, "Reset SAP Hidden Network configuration");
}
- if (mContext.getResources().getBoolean(
+ if (mResourceCache.getBoolean(
R.bool.config_wifiSoftapResetAutoShutdownTimerConfig)
&& config.getShutdownTimeoutMillis() > 0) {
if (CompatChanges.isChangeEnabled(
@@ -426,7 +430,7 @@ public class WifiApConfigStore {
private SoftApConfiguration getDefaultApConfiguration() {
SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder();
configBuilder.setBand(generateDefaultBand(mContext));
- configBuilder.setSsid(mContext.getResources().getString(
+ configBuilder.setSsid(mResourceCache.getString(
R.string.wifi_tether_configure_ssid_default) + "_" + getRandomIntForDefaultSsid());
try {
if (ApConfigUtil.isWpa3SaeSupported(mContext)) {
@@ -470,8 +474,8 @@ public class WifiApConfigStore {
return random.nextInt((RAND_SSID_INT_MAX - RAND_SSID_INT_MIN) + 1) + RAND_SSID_INT_MIN;
}
- private static String generateLohsSsid(Context context) {
- return context.getResources().getString(
+ private static String generateLohsSsid(WifiContext context) {
+ return context.getResourceCache().getString(
R.string.wifi_localhotspot_configure_ssid_default) + "_"
+ getRandomIntForDefaultSsid();
}
@@ -484,7 +488,7 @@ public class WifiApConfigStore {
* Generate a temporary WPA2 based configuration for use by the local only hotspot.
* This config is not persisted and will not be stored by the WifiApConfigStore.
*/
- public SoftApConfiguration generateLocalOnlyHotspotConfig(@NonNull Context context,
+ public SoftApConfiguration generateLocalOnlyHotspotConfig(@NonNull WifiContext context,
@Nullable SoftApConfiguration customConfig, @NonNull SoftApCapability capability) {
SoftApConfiguration.Builder configBuilder;
if (customConfig != null) {
@@ -529,11 +533,11 @@ public class WifiApConfigStore {
// Automotive mode can force the LOHS to specific bands
if (hasAutomotiveFeature(context)) {
int desiredBand = SoftApConfiguration.BAND_2GHZ;
- if (context.getResources().getBoolean(R.bool.config_wifiLocalOnlyHotspot6ghz)
+ if (context.getResourceCache().getBoolean(R.bool.config_wifiLocalOnlyHotspot6ghz)
&& ApConfigUtil.isBandSupported(SoftApConfiguration.BAND_6GHZ, mContext)) {
desiredBand |= SoftApConfiguration.BAND_6GHZ;
}
- if (context.getResources().getBoolean(R.bool.config_wifi_local_only_hotspot_5ghz)
+ if (context.getResourceCache().getBoolean(R.bool.config_wifi_local_only_hotspot_5ghz)
&& ApConfigUtil.isBandSupported(SoftApConfiguration.BAND_5GHZ, mContext)) {
desiredBand |= SoftApConfiguration.BAND_5GHZ;
}
@@ -619,7 +623,7 @@ public class WifiApConfigStore {
* otherwise.
*/
static boolean validateApWifiConfiguration(@NonNull SoftApConfiguration apConfig,
- boolean isPrivileged, Context context, WifiNative wifiNative) {
+ boolean isPrivileged, WifiContext context, WifiNative wifiNative) {
// first check the SSID
WifiSsid ssid = apConfig.getWifiSsid();
if (ssid == null || ssid.getBytes().length == 0) {
@@ -659,7 +663,7 @@ public class WifiApConfigStore {
return false;
}
- if (context.getResources().getBoolean(
+ if (context.getResourceCache().getBoolean(
R.bool.config_wifiSoftapPassphraseAsciiEncodableCheck)) {
final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
if (!asciiEncoder.canEncode(preSharedKey)) {
@@ -686,7 +690,7 @@ public class WifiApConfigStore {
// Only return failure if requested band is limited to 6GHz only
if (band == SoftApConfiguration.BAND_6GHZ
&& !ApConfigUtil.canHALConvertRestrictedSecurityTypeFor6GHz(
- context.getResources(), authType)) {
+ context.getResourceCache(), authType)) {
Log.d(TAG, "security type: " + authType
+ " is not allowed for softap in 6GHz band");
return false;
@@ -728,7 +732,7 @@ public class WifiApConfigStore {
* @param context The caller context used to get value from resource file.
* @return A band which will be used for a default band in default configuration.
*/
- public static @BandType int generateDefaultBand(Context context) {
+ public static @BandType int generateDefaultBand(WifiContext context) {
for (int band : SoftApConfiguration.BAND_TYPES) {
if (ApConfigUtil.isBandSupported(band, context)) {
return band;
@@ -738,7 +742,7 @@ public class WifiApConfigStore {
return SoftApConfiguration.BAND_2GHZ;
}
- private static boolean isBandsSupported(@NonNull int[] apBands, Context context) {
+ private static boolean isBandsSupported(@NonNull int[] apBands, WifiContext context) {
for (int band : apBands) {
if (!ApConfigUtil.isBandSupported(band, context)) {
return false;
diff --git a/service/java/com/android/server/wifi/WifiCarrierInfoManager.java b/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
index 1936abb7ae..1e623a6987 100644
--- a/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
+++ b/service/java/com/android/server/wifi/WifiCarrierInfoManager.java
@@ -2178,6 +2178,31 @@ public class WifiCarrierInfoManager {
return enabled;
}
+ /**
+ * Return true if there is one or more SIMs' mobile data is enabled.
+ */
+ public boolean isMobileDataEnabled() {
+ if (mActiveSubInfos == null) {
+ return false;
+ }
+ for (SubscriptionInfo info : mActiveSubInfos) {
+ if (isMobileDataEnabled(info.getSubscriptionId())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return true if there is one or more active SubInfo.
+ */
+ public boolean hasActiveSubInfo() {
+ if (mActiveSubInfos == null || mActiveSubInfos.isEmpty()) {
+ return false;
+ }
+ return true;
+ }
+
private void saveToStore() {
// Set the flag to let WifiConfigStore that we have new data to write.
mHasNewUserDataToSerialize = true;
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 9b0af36429..87d0a5b7dc 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -124,6 +124,7 @@ public class WifiConfigManager {
private final AlarmManager mAlarmManager;
private final FeatureFlags mFeatureFlags;
private boolean mBufferedWritePending;
+ private int mCellularConnectivityStatus = WifiDataStall.CELLULAR_DATA_UNKNOWN;
/** Alarm tag to use for starting alarms for buffering file writes. */
@VisibleForTesting public static final String BUFFERED_WRITE_ALARM_TAG = "WriteBufferAlarm";
/** Time interval for buffering file writes for non-forced writes */
@@ -480,8 +481,16 @@ public class WifiConfigManager {
*/
public void onCellularConnectivityChanged(@WifiDataStall.CellularDataStatusCode int status) {
localLog("onCellularConnectivityChanged:" + status);
- if (status == WifiDataStall.CELLULAR_DATA_NOT_AVAILABLE) {
+ mCellularConnectivityStatus = status;
+ }
+
+ /**
+ * Allow wifi connection if cellular data is unavailable.
+ */
+ public void considerStopRestrictingAutoJoinToSubscriptionId() {
+ if (mCellularConnectivityStatus == WifiDataStall.CELLULAR_DATA_NOT_AVAILABLE) {
stopRestrictingAutoJoinToSubscriptionId();
+ mCellularConnectivityStatus = WifiDataStall.CELLULAR_DATA_UNKNOWN;
}
}
diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
index 4421fcd08e..501a071b34 100644
--- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java
+++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
@@ -16,7 +16,11 @@
package com.android.server.wifi;
+import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_NUM;
import static android.net.wifi.WifiManager.ALL_ZEROS_MAC_ADDRESS;
+import static android.net.wifi.hotspot2.PasspointConfiguration.MAX_NUMBER_OF_OI;
+import static android.net.wifi.hotspot2.PasspointConfiguration.MAX_OI_VALUE;
+import static android.net.wifi.hotspot2.PasspointConfiguration.MAX_URL_BYTES;
import static com.android.server.wifi.util.NativeUtil.addEnclosingQuotes;
@@ -31,6 +35,7 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
+import android.net.wifi.hotspot2.PasspointConfiguration;
import android.os.PatternMatcher;
import android.text.TextUtils;
import android.util.Log;
@@ -46,8 +51,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Comparator;
+import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
/**
* WifiConfiguration utility for any {@link android.net.wifi.WifiConfiguration} related operations.
@@ -70,6 +77,7 @@ public class WifiConfigurationUtil {
private static final int PSK_SAE_HEX_LEN = 64;
private static final int WEP104_KEY_BYTES_LEN = 13;
private static final int WEP40_KEY_BYTES_LEN = 5;
+ private static final int MAX_STRING_LENGTH = 512;
@VisibleForTesting
public static final String PASSWORD_MASK = "*";
@@ -750,7 +758,8 @@ public class WifiConfigurationUtil {
if (!validateSsid(config.SSID, isAdd)) {
return false;
}
- if (!validateBssid(config.BSSID)) {
+ if (!validateBssid(config.BSSID) || !validateBssid(config.dhcpServer)
+ || !validateBssid(config.defaultGwMacAddress)) {
return false;
}
if (!validateBitSets(config)) {
@@ -759,9 +768,22 @@ public class WifiConfigurationUtil {
if (!validateKeyMgmt(config.allowedKeyManagement)) {
return false;
}
- if (config.isSecurityType(WifiConfiguration.SECURITY_TYPE_WEP)
- && config.wepKeys != null
- && !validateWepKeys(config.wepKeys, config.wepTxKeyIndex, isAdd)) {
+ if (!validateSecurityParameters(config.getSecurityParamsList())) {
+ return false;
+ }
+ if (!validatePasspoint(config)) {
+ return false;
+ }
+ if (!validateNetworkSelectionStatus(config.getNetworkSelectionStatus())) {
+ return false;
+ }
+
+ if (config.isSecurityType(WifiConfiguration.SECURITY_TYPE_WEP)) {
+ if (config.wepKeys != null
+ && !validateWepKeys(config.wepKeys, config.wepTxKeyIndex, isAdd)) {
+ return false;
+ }
+ } else if (!validateWepKeys(config.wepKeys, config.wepTxKeyIndex, false)) {
return false;
}
if (config.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK)
@@ -793,10 +815,92 @@ public class WifiConfigurationUtil {
if (!validateIpConfiguration(config.getIpConfiguration())) {
return false;
}
+
+ if (config.getDppConnector().length > MAX_URL_BYTES
+ || config.getDppCSignKey().length > MAX_URL_BYTES
+ || config.getDppPrivateEcKey().length > MAX_URL_BYTES
+ || config.getDppNetAccessKey().length > MAX_URL_BYTES) {
+ return false;
+ }
// TBD: Validate some enterprise params as well in the future here.
return true;
}
+ private static boolean validateStringField(String field, int maxLength) {
+ return field == null || field.length() <= maxLength;
+ }
+
+ private static boolean validatePasspoint(WifiConfiguration config) {
+ if (!validateStringField(config.FQDN, PasspointConfiguration.MAX_STRING_LENGTH)) {
+ return false;
+ }
+ if (!validateStringField(config.providerFriendlyName,
+ PasspointConfiguration.MAX_STRING_LENGTH)) {
+ return false;
+ }
+ if (!validateRoamingConsortiumIds(config.roamingConsortiumIds)) {
+ return false;
+ }
+ if (!validateUpdateIdentifier(config.updateIdentifier)) {
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean validateUpdateIdentifier(String updateIdentifier) {
+ if (TextUtils.isEmpty(updateIdentifier)) {
+ return true;
+ }
+ try {
+ Integer.valueOf(updateIdentifier);
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean validateNetworkSelectionStatus(
+ WifiConfiguration.NetworkSelectionStatus status) {
+ if (status == null) {
+ return false;
+ }
+ return validateStringField(status.getConnectChoice(), MAX_STRING_LENGTH)
+ && validateBssid(status.getNetworkSelectionBSSID());
+ }
+
+ private static boolean validateRoamingConsortiumIds(long[] roamingConsortiumIds) {
+ if (roamingConsortiumIds != null) {
+ if (roamingConsortiumIds.length > MAX_NUMBER_OF_OI) {
+ Log.d(TAG, "too many Roaming Consortium Organization Identifiers in the "
+ + "profile");
+ return false;
+ }
+ for (long oi : roamingConsortiumIds) {
+ if (oi < 0 || oi > MAX_OI_VALUE) {
+ Log.d(TAG, "Organization Identifiers is out of range");
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private static boolean validateSecurityParameters(List<SecurityParams> paramsList) {
+ Set<Integer> uniqueSecurityTypes = new HashSet<>(SECURITY_TYPE_NUM + 1);
+ for (SecurityParams params : paramsList) {
+ int securityType = params.getSecurityType();
+ if (securityType < 0 || securityType > SECURITY_TYPE_NUM) {
+ return false;
+ }
+ if (uniqueSecurityTypes.contains(securityType)) {
+ return false;
+ }
+ uniqueSecurityTypes.add(securityType);
+ }
+ return true;
+
+ }
+
private static boolean validateBssidPattern(
Pair<MacAddress, MacAddress> bssidPatternMatcher) {
if (bssidPatternMatcher == null) return true;
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 59d8934edf..b7e12e0686 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -25,6 +25,7 @@ import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_LO
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT;
import static com.android.server.wifi.ClientModeImpl.WIFI_WORK_SOURCE;
import static com.android.server.wifi.WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE;
+import static com.android.server.wifi.WifiMetrics.ConnectionEvent.FAILURE_NO_RESPONSE;
import static com.android.server.wifi.proto.nano.WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_EAP_FAILURE;
import android.annotation.NonNull;
@@ -52,6 +53,7 @@ import android.os.IBinder;
import android.os.PowerManager;
import android.os.Process;
import android.os.WorkSource;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -67,12 +69,14 @@ import com.android.server.wifi.hotspot2.PasspointManager;
import com.android.server.wifi.proto.WifiStatsLog;
import com.android.server.wifi.scanner.WifiScannerInternal;
import com.android.server.wifi.util.WifiPermissionsUtil;
+import com.android.wifi.flags.FeatureFlags;
import com.android.wifi.resources.R;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
@@ -180,6 +184,7 @@ public class WifiConnectivityManager {
private final WifiChannelUtilization mWifiChannelUtilization;
private final PowerManager mPowerManager;
private final DeviceConfigFacade mDeviceConfigFacade;
+ private final FeatureFlags mFeatureFlags;
private final ActiveModeWarden mActiveModeWarden;
private final FrameworkFacade mFrameworkFacade;
private final WifiPermissionsUtil mWifiPermissionsUtil;
@@ -218,9 +223,11 @@ public class WifiConnectivityManager {
private Object mDelayedPnoScanToken = new Object();
private boolean mDelayedPnoScanPending = false;
private boolean mPeriodicScanTimerSet = false;
+ private boolean mDelayedCarrierPartialScanScheduled = false;
private Object mPeriodicScanTimerToken = new Object();
private Object mDelayedStartPeriodicScanToken = new Object();
- private boolean mDelayedPartialScanTimerSet = false;
+ private Object mDelayedCarrierPartialScanToken = new Object();
+ private boolean mHighMvmtDelayedPartialScanTimerSet = false;
private boolean mWatchdogScanTimerSet = false;
private boolean mIsLocationModeEnabled;
@@ -265,6 +272,12 @@ public class WifiConnectivityManager {
private @DeviceMobilityState int mDeviceMobilityState =
WifiManager.DEVICE_MOBILITY_STATE_UNKNOWN;
+ // Cached WifiCandidate timestamps for delayed carrier network selection
+ private Map<WifiCandidates.Key, Long> mDelayedCarrierCandidateTimestamps = new HashMap<>();
+ private Set<Integer> mDelayedCarrierCandidateFrequencies = new HashSet<>();
+ private Set<Integer> mDelayedSelectionCarrierIds = new HashSet<>();
+ private long mDelayedCarrierSelectionTimeMs;
+
// A helper to log debugging information in the local log buffer, which can
// be retrieved in bugreport.
private void localLog(String log) {
@@ -312,7 +325,7 @@ public class WifiConnectivityManager {
}
};
- private final AlarmManager.OnAlarmListener mDelayedPartialScanTimerListener =
+ private final AlarmManager.OnAlarmListener mHighMvmtDelayedPartialScanListener =
new AlarmManager.OnAlarmListener() {
public void onAlarm() {
if (mCachedWifiCandidates == null
@@ -320,26 +333,46 @@ public class WifiConnectivityManager {
|| mCachedWifiCandidates.frequencies.size() == 0) {
return;
}
- ScanSettings settings = new ScanSettings();
- settings.type = WifiScanner.SCAN_TYPE_HIGH_ACCURACY;
- settings.band = getScanBand(false);
- settings.reportEvents = WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT
- | WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN;
- settings.numBssidsPerScan = 0;
- int index = 0;
- settings.channels =
- new WifiScanner.ChannelSpec[mCachedWifiCandidates.frequencies.size()];
- for (Integer freq : mCachedWifiCandidates.frequencies) {
- settings.channels[index++] = new WifiScanner.ChannelSpec(freq);
- }
- SingleScanListener singleScanListener = new SingleScanListener(false);
- mScanner.startScan(settings,
- new WifiScannerInternal.ScanListener(singleScanListener,
- mWifiThreadRunner));
- mWifiMetrics.incrementConnectivityOneshotScanCount();
+ startPartialScan(mCachedWifiCandidates.frequencies);
+ mHighMvmtDelayedPartialScanTimerSet = false;
}
};
+ private void startDelayedCarrierPartialScan() {
+ if (!mDelayedCarrierPartialScanScheduled) {
+ Log.i(TAG, "Ignoring delayed carrier partial scan");
+ return;
+ }
+ mDelayedCarrierPartialScanScheduled = false;
+
+ if (mDelayedCarrierCandidateFrequencies == null
+ || mDelayedCarrierCandidateFrequencies.isEmpty()) {
+ Log.i(TAG, "No frequencies found for the delayed carrier partial scan");
+ return;
+ }
+ Log.i(TAG, "Starting delayed carrier partial scan");
+ startPartialScan(mDelayedCarrierCandidateFrequencies);
+ }
+
+ private void startPartialScan(Set<Integer> frequencies) {
+ ScanSettings settings = new ScanSettings();
+ settings.type = WifiScanner.SCAN_TYPE_HIGH_ACCURACY;
+ settings.band = getScanBand(false);
+ settings.reportEvents = WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT
+ | WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN;
+ settings.numBssidsPerScan = 0;
+ int index = 0;
+ settings.channels = new WifiScanner.ChannelSpec[frequencies.size()];
+ for (Integer freq : frequencies) {
+ settings.channels[index++] = new WifiScanner.ChannelSpec(freq);
+ }
+ SingleScanListener singleScanListener = new SingleScanListener(false);
+ mScanner.startScan(settings,
+ new WifiScannerInternal.ScanListener(singleScanListener,
+ mWifiThreadRunner));
+ mWifiMetrics.incrementConnectivityOneshotScanCount();
+ }
+
/**
* Interface for callback from handling scan results.
*/
@@ -627,6 +660,9 @@ public class WifiConnectivityManager {
}
boolean skipSufficiencyCheck = shouldSkipSufficiencyCheck(hasExistingSecondaryCmm);
+ // If cellular is unavailable, re-enable Wi-Fi networks disabled by pinning to cell.
+ mConfigManager.considerStopRestrictingAutoJoinToSubscriptionId();
+
// Check if any blocklisted BSSIDs can be freed.
List<ScanDetail> enabledDetails =
mWifiBlocklistMonitor.tryEnablingBlockedBssids(scanDetails);
@@ -649,6 +685,12 @@ public class WifiConnectivityManager {
scanDetails, bssidBlocklist, cmmStates, mUntrustedConnectionAllowed,
mOemPaidConnectionAllowed, mOemPrivateConnectionAllowed,
mRestrictedConnectionAllowedUids, skipSufficiencyCheck);
+
+ // Filter candidates before caching to avoid reconnecting on failure
+ if (mFeatureFlags.delayedCarrierNetworkSelection()) {
+ candidates = filterDelayedCarrierSelectionCandidates(candidates, listenerName,
+ isFullScan);
+ }
mLatestCandidates = candidates;
mLatestCandidatesTimestampMs = mClock.getElapsedSinceBootMillis();
@@ -875,12 +917,102 @@ public class WifiConnectivityManager {
candidates);
localLog("Found " + candidates.size() + " candidates at high mobility state. "
+ "Re-doing scan to confirm network quality.");
- scheduleDelayedPartialScan(minimumTimeBetweenScansMs);
+ scheduleHighMvmtDelayedPartialScan(minimumTimeBetweenScansMs);
}
mWifiMetrics.incrementNumHighMovementConnectionSkipped();
return null;
}
+ /**
+ * Filter carrier candidates affected by the delayed carrier selection optimization.
+ */
+ private List<WifiCandidates.Candidate> filterDelayedCarrierSelectionCandidates(
+ List<WifiCandidates.Candidate> candidates, String listenerName, boolean isFullScan) {
+ if (mDelayedSelectionCarrierIds == null || mDelayedSelectionCarrierIds.isEmpty()) {
+ // No carrier IDs apply to this filter
+ return candidates;
+ }
+
+ boolean isNotPartialScan = isFullScan || listenerName.equals(PNO_SCAN_LISTENER);
+ if (candidates == null || candidates.isEmpty()) {
+ // No connectable networks nearby or network selection is unnecessary
+ if (isNotPartialScan) {
+ mDelayedCarrierCandidateTimestamps.clear();
+ }
+ return null;
+ }
+
+ List<WifiCandidates.Candidate> delayedCarrierCandidates = new ArrayList<>();
+ List<WifiCandidates.Candidate> nonAffectedCandidates = new ArrayList<>();
+ for (WifiCandidates.Candidate candidate : candidates) {
+ WifiConfiguration configuration =
+ mConfigManager.getConfiguredNetwork(candidate.getNetworkConfigId());
+ if (configuration != null
+ && mDelayedSelectionCarrierIds.contains(configuration.carrierId)) {
+ delayedCarrierCandidates.add(candidate);
+ } else {
+ nonAffectedCandidates.add(candidate);
+ }
+ }
+
+ if (isNotPartialScan) {
+ updateDelayedCarrierCandidateCache(delayedCarrierCandidates);
+ }
+ if (delayedCarrierCandidates.isEmpty()) {
+ return candidates;
+ }
+
+ // Include delayed carrier candidates that were first seen
+ // at least mDelayedCarrierSelectionTimeMs ago
+ long currentTimeMs = mClock.getElapsedSinceBootMillis();
+ List<WifiCandidates.Candidate> filteredCandidates = new ArrayList<>();
+ for (WifiCandidates.Candidate candidate : delayedCarrierCandidates) {
+ long firstSeenTimeMs = mDelayedCarrierCandidateTimestamps
+ .getOrDefault(candidate.getKey(), currentTimeMs);
+ if ((currentTimeMs - firstSeenTimeMs) > mDelayedCarrierSelectionTimeMs) {
+ filteredCandidates.add(candidate);
+ }
+ }
+ Log.i(TAG, filteredCandidates.size() + " of " + delayedCarrierCandidates.size()
+ + " delayed carrier candidates are eligible for network selection");
+ filteredCandidates.addAll(nonAffectedCandidates);
+ scheduleDelayedCarrierPartialScanIfNeeded(isNotPartialScan);
+ return filteredCandidates;
+ }
+
+ /**
+ * Update the first seen timestamp for all delayed carrier scan candidates,
+ * as well as the frequencies where the candidates were last seen.
+ */
+ private void updateDelayedCarrierCandidateCache(
+ List<WifiCandidates.Candidate> delayedCarrierCandidates) {
+ Map<WifiCandidates.Key, Long> updatedTimestamps = new HashMap<>();
+ Set<Integer> updatedFrequencies = new HashSet<>();
+ long currentTimeMs = mClock.getElapsedSinceBootMillis();
+ for (WifiCandidates.Candidate candidate : delayedCarrierCandidates) {
+ WifiCandidates.Key candidateKey = candidate.getKey();
+ // Use the existing first-seen time if this candidate has been seen before
+ long firstSeenTimestamp = mDelayedCarrierCandidateTimestamps.getOrDefault(
+ candidateKey, currentTimeMs);
+ updatedTimestamps.put(candidateKey, firstSeenTimestamp);
+ updatedFrequencies.add(candidate.getFrequency());
+ }
+ mDelayedCarrierCandidateTimestamps = updatedTimestamps;
+ mDelayedCarrierCandidateFrequencies = updatedFrequencies;
+ }
+
+ private void scheduleDelayedCarrierPartialScanIfNeeded(boolean isNotPartialScan) {
+ if (!isNotPartialScan || mDelayedCarrierPartialScanScheduled
+ || mWifiState == WIFI_STATE_CONNECTED) {
+ return;
+ }
+ Log.i(TAG, "Scheduling delayed carrier partial scan to run in "
+ + mDelayedCarrierSelectionTimeMs + " ms");
+ mEventHandler.postDelayed(() -> startDelayedCarrierPartialScan(),
+ mDelayedCarrierPartialScanToken, mDelayedCarrierSelectionTimeMs);
+ mDelayedCarrierPartialScanScheduled = true;
+ }
+
private void updateUserDisabledList(List<ScanDetail> scanDetails) {
List<String> results = new ArrayList<>();
List<ScanResult> passpointAp = new ArrayList<>();
@@ -1375,6 +1507,7 @@ public class WifiConnectivityManager {
mPasspointManager = passpointManager;
mMultiInternetManager = multiInternetManager;
mDeviceConfigFacade = deviceConfigFacade;
+ mFeatureFlags = mDeviceConfigFacade.getFeatureFlags();
mActiveModeWarden = activeModeWarden;
mFrameworkFacade = frameworkFacade;
mWifiGlobals = wifiGlobals;
@@ -1388,6 +1521,16 @@ public class WifiConnectivityManager {
mWifiCountryCode = wifiCountryCode;
mWifiDialogManager = wifiDialogManager;
+ mDelayedCarrierSelectionTimeMs = mContext.getResources().getInteger(
+ R.integer.config_wifiDelayedCarrierSelectionTimeMs);
+ int[] delayedSelectionCarrierIds = mContext.getResources().getIntArray(
+ R.array.config_wifiDelayedSelectionCarrierIds);
+ if (delayedSelectionCarrierIds != null && delayedSelectionCarrierIds.length != 0) {
+ for (Integer carrierId : delayedSelectionCarrierIds) {
+ mDelayedSelectionCarrierIds.add(carrierId);
+ }
+ }
+
// Listen to WifiConfigManager network update events
mEventHandler.postToFront(() ->
mConfigManager.addOnNetworkUpdateListener(new OnNetworkUpdateListener()));
@@ -1817,8 +1960,10 @@ public class WifiConnectivityManager {
// Need to connect to a different network id
// Framework specifies the connection target BSSID if firmware doesn't support
// {@link android.net.wifi.WifiManager#WIFI_FEATURE_CONTROL_ROAMING} or the
- // candidate configuration contains a specified BSSID.
+ // candidate configuration contains a specified BSSID, or the feature to set target BSSID
+ // is enabled.
if (mConnectivityHelper.isFirmwareRoamingSupported()
+ && !mWifiGlobals.isNetworkSelectionSetTargetBssid()
&& (targetNetwork.BSSID == null
|| targetNetwork.BSSID.equals(ClientModeImpl.SUPPLICANT_BSSID_ANY))) {
targetBssid = ClientModeImpl.SUPPLICANT_BSSID_ANY;
@@ -2173,7 +2318,7 @@ public class WifiConnectivityManager {
getScheduledSingleScanType(mCurrentSingleScanScheduleIndex));
// Note, initial partial scan may fail due to lack of channel history
- // Hence, we verify state before changing to AWIATING_RESPONSE
+ // Hence, we verify state before changing to AWAITING_RESPONSE
if (mInitialScanState == INITIAL_SCAN_STATE_START) {
setInitialScanState(INITIAL_SCAN_STATE_AWAITING_RESPONSE);
mWifiMetrics.incrementInitialPartialScanCount();
@@ -2540,9 +2685,12 @@ public class WifiConnectivityManager {
config.isPasspoint() ? config.FQDN : config.SSID)
|| (config.enterpriseConfig != null
&& config.enterpriseConfig.isAuthenticationSimBased()
- && config.carrierId != TelephonyManager.UNKNOWN_CARRIER_ID)
+ && config.carrierId != TelephonyManager.UNKNOWN_CARRIER_ID
&& !mWifiCarrierInfoManager.isSimReady(
- mWifiCarrierInfoManager.getBestMatchSubscriptionId(config)));
+ mWifiCarrierInfoManager.getBestMatchSubscriptionId(config)))
+ || (config.subscriptionId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
+ && !mWifiCarrierInfoManager.isCarrierNetworkOffloadEnabled(
+ config.subscriptionId, config.carrierMerged)));
return networks;
}
@@ -2710,18 +2858,22 @@ public class WifiConnectivityManager {
}
// Schedules a delayed partial scan, which will scan the frequencies in mCachedWifiCandidates.
- private void scheduleDelayedPartialScan(long delayMillis) {
+ private void scheduleHighMvmtDelayedPartialScan(long delayMillis) {
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
mClock.getElapsedSinceBootMillis() + delayMillis, DELAYED_PARTIAL_SCAN_TIMER_TAG,
- mDelayedPartialScanTimerListener, mEventHandler);
- mDelayedPartialScanTimerSet = true;
+ mHighMvmtDelayedPartialScanListener, mEventHandler);
+ mHighMvmtDelayedPartialScanTimerSet = true;
}
- // Cancel the delayed partial scan timer.
- private void cancelDelayedPartialScan() {
- if (mDelayedPartialScanTimerSet) {
- mAlarmManager.cancel(mDelayedPartialScanTimerListener);
- mDelayedPartialScanTimerSet = false;
+ // Cancel all scheduled delayed partial scans.
+ private void cancelDelayedPartialScans() {
+ if (mHighMvmtDelayedPartialScanTimerSet) {
+ mAlarmManager.cancel(mHighMvmtDelayedPartialScanListener);
+ mHighMvmtDelayedPartialScanTimerSet = false;
+ }
+ if (mDelayedCarrierPartialScanScheduled) {
+ mEventHandler.removeCallbacksAndMessages(mDelayedCarrierPartialScanToken);
+ mDelayedCarrierPartialScanScheduled = false;
}
}
@@ -2825,7 +2977,7 @@ public class WifiConnectivityManager {
// Due to b/28020168, timer based single scan will be scheduled
// to provide periodic scan in an exponential backoff fashion.
cancelPeriodicScanTimer();
- cancelDelayedPartialScan();
+ cancelDelayedPartialScans();
stopPnoScan();
}
@@ -3157,6 +3309,7 @@ public class WifiConnectivityManager {
// Only attempt to reconnect when connection on the primary CMM fails, since MBB
// CMM will be destroyed after the connection failure.
if (clientModeManager.getRole() == ROLE_CLIENT_PRIMARY
+ && failureCode != FAILURE_NO_RESPONSE // Do not retry since this is a timeout
&& !mWifiPermissionsUtil.isAdminRestrictedNetwork(config)) {
retryConnectionOnLatestCandidates(clientModeManager, bssid, config,
failureCode == FAILURE_AUTHENTICATION_FAILURE
@@ -3395,14 +3548,24 @@ public class WifiConnectivityManager {
mConnectivityHelper.getFirmwareRoamingInfo();
mWifiChannelUtilization.init(getPrimaryClientModeManager().getWifiLinkLayerStats());
clearConnectionAttemptTimeStamps(); // clear connection attempts.
-
- if (mContext.getResources().getBoolean(R.bool.config_wifiEnablePartialInitialScan)) {
- setInitialScanState(INITIAL_SCAN_STATE_START);
- }
-
mRunning = true;
mLatestCandidates = null;
mLatestCandidatesTimestampMs = 0;
+ if (mContext.getResources().getBoolean(R.bool.config_wifiEnablePartialInitialScan)) {
+ setInitialScanState(INITIAL_SCAN_STATE_START);
+ if (mScreenOn) {
+ // force trigger partial scan at start up to make sure this happens before Settings
+ // scan
+ startSingleScan(false, WIFI_WORK_SOURCE, DEFAULT_SCANNING_TYPE[0]);
+
+ // Note, initial partial scan may fail due to lack of channel history
+ // Hence, we verify state before changing to AWAITING_RESPONSE
+ if (mInitialScanState == INITIAL_SCAN_STATE_START) {
+ setInitialScanState(INITIAL_SCAN_STATE_AWAITING_RESPONSE);
+ mWifiMetrics.incrementInitialPartialScanCount();
+ }
+ }
+ }
}
/**
diff --git a/service/java/com/android/server/wifi/WifiCountryCode.java b/service/java/com/android/server/wifi/WifiCountryCode.java
index 4d4bc0bb0c..c307c010b8 100644
--- a/service/java/com/android/server/wifi/WifiCountryCode.java
+++ b/service/java/com/android/server/wifi/WifiCountryCode.java
@@ -21,7 +21,9 @@ import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_DEFAULT_COUNT
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiInfo;
+import android.net.wifi.util.WifiResourceCache;
import android.os.SystemProperties;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -65,7 +67,7 @@ public class WifiCountryCode {
static final int MAX_DURATION_SINCE_LAST_UPDATE_TIME_MS = 500_000;
static final int MIN_SCAN_RSSI_DBM = -85;
private final String mWorldModeCountryCode;
- private final Context mContext;
+ private final WifiContext mContext;
private final TelephonyManager mTelephonyManager;
private final ActiveModeWarden mActiveModeWarden;
private final WifiP2pMetrics mWifiP2pMetrics;
@@ -74,6 +76,7 @@ public class WifiCountryCode {
private final Clock mClock;
private final WifiPermissionsUtil mWifiPermissionsUtil;
private final WifiCarrierInfoManager mWifiCarrierInfoManager;
+ private final WifiResourceCache mResourceCache;
private List<ChangeListener> mListeners = new ArrayList<>();
private boolean mVerboseLoggingEnabled = false;
private boolean mIsCountryCodePendingToUpdateToCmm = true; // default to true for first update.
@@ -199,7 +202,7 @@ public class WifiCountryCode {
}
public WifiCountryCode(
- Context context,
+ WifiContext context,
ActiveModeWarden activeModeWarden,
WifiP2pMetrics wifiP2pMetrics,
ClientModeImplMonitor clientModeImplMonitor,
@@ -217,12 +220,13 @@ public class WifiCountryCode {
mClock = clock;
mWifiPermissionsUtil = wifiPermissionsUtil;
mWifiCarrierInfoManager = wifiCarrierInfoManager;
+ mResourceCache = mContext.getResourceCache();
mActiveModeWarden.registerModeChangeCallback(new ModeChangeCallbackInternal());
clientModeImplMonitor.registerListener(new ClientModeListenerInternal());
mWifiNative.registerCountryCodeEventListener(new CountryChangeListenerInternal());
- mWorldModeCountryCode = mContext.getResources()
+ mWorldModeCountryCode = mResourceCache
.getString(R.string.config_wifiDriverWorldModeCountryCode);
Log.d(TAG, "Default country code from system property "
@@ -383,7 +387,7 @@ public class WifiCountryCode {
// Empty country code.
if (TextUtils.isEmpty(countryCode)) {
- if (mContext.getResources()
+ if (mResourceCache
.getBoolean(R.bool.config_wifi_revert_country_code_on_cellular_loss)) {
Log.d(TAG, "Received empty country code, reset to default country code");
mTelephonyCountryCode = null;
@@ -457,7 +461,7 @@ public class WifiCountryCode {
}
private boolean isCcUpdateGenericEnabled() {
- return mContext.getResources().getBoolean(
+ return mResourceCache.getBoolean(
R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric);
}
@@ -587,7 +591,7 @@ public class WifiCountryCode {
*/
public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("mRevertCountryCodeOnCellularLoss: "
- + mContext.getResources().getBoolean(
+ + mResourceCache.getBoolean(
R.bool.config_wifi_revert_country_code_on_cellular_loss));
pw.println("DefaultCountryCode(system property): " + getOemDefaultCountryCode());
pw.println("DefaultCountryCode(config store): "
@@ -612,7 +616,7 @@ public class WifiCountryCode {
}
private boolean isDriverSupportedRegChangedEvent() {
- return mContext.getResources().getBoolean(
+ return mResourceCache.getBoolean(
R.bool.config_wifiDriverSupportedNl80211RegChangedEvent);
}
@@ -664,7 +668,7 @@ public class WifiCountryCode {
Set<ActiveModeManager> amms = mAmmToReadyForChangeMap.keySet();
boolean isConcreteClientModeManagerUpdated = false;
boolean anyAmmConfigured = false;
- final boolean isNeedToUpdateCCToSta = mContext.getResources()
+ final boolean isNeedToUpdateCCToSta = mResourceCache
.getBoolean(R.bool.config_wifiStaDynamicCountryCodeUpdateSupported)
|| isAllCmmReady();
if (!isNeedToUpdateCCToSta) {
@@ -674,13 +678,11 @@ public class WifiCountryCode {
boolean isCountryCodeChanged = !TextUtils.equals(mDriverCountryCode, country);
Log.d(TAG, "setCountryCodeNative: " + country + ", isClientModeOnly: " + isClientModeOnly
+ " mDriverCountryCode: " + mDriverCountryCode);
+ // We intend to change Country code, assume to pending to update for Cmm first.
+ mIsCountryCodePendingToUpdateToCmm = true;
for (ActiveModeManager am : amms) {
- if (!isConcreteClientModeManagerUpdated
+ if (isNeedToUpdateCCToSta && !isConcreteClientModeManagerUpdated
&& am instanceof ConcreteClientModeManager) {
- mIsCountryCodePendingToUpdateToCmm = !isNeedToUpdateCCToSta;
- if (!isNeedToUpdateCCToSta) {
- continue;
- }
// Set the country code using one of the active mode managers. Since
// country code is a chip level global setting, it can be set as long
// as there is at least one active interface to communicate to Wifi chip
@@ -696,6 +698,8 @@ public class WifiCountryCode {
if (!SdkLevel.isAtLeastS() && !isDriverSupportedRegChangedEvent()) {
handleCountryCodeChanged(country);
}
+ // Country code was updated to cmmm succeeded, change pending to false.
+ mIsCountryCodePendingToUpdateToCmm = false;
}
} else if (!isClientModeOnly && am instanceof SoftApManager) {
SoftApManager sm = (SoftApManager) am;
diff --git a/service/java/com/android/server/wifi/WifiDataStall.java b/service/java/com/android/server/wifi/WifiDataStall.java
index 64e370bd9e..97131f0c96 100644
--- a/service/java/com/android/server/wifi/WifiDataStall.java
+++ b/service/java/com/android/server/wifi/WifiDataStall.java
@@ -306,6 +306,43 @@ public class WifiDataStall {
return mRxTputKbps;
}
+ public static class Speeds {
+ public int DownstreamKbps = INVALID_THROUGHPUT;
+ public int UpstreamKbps = INVALID_THROUGHPUT;
+ }
+
+ /**
+ * Returns link capacity estimate derived from ThrouhgputPredictor.
+ */
+ public Speeds getThrouhgputPredictorSpeeds(
+ WifiInfo wifiInfo,
+ ConnectionCapabilities connectionCapabilities) {
+ // Defaults to INVALID_THROUGHPUT.
+ Speeds speeds = new Speeds();
+
+ if (wifiInfo == null) {
+ return speeds;
+ }
+ int currFrequency = wifiInfo.getFrequency();
+ int rssi = wifiInfo.getRssi();
+ if (rssi == WifiInfo.INVALID_RSSI) {
+ return speeds;
+ }
+
+ if (connectionCapabilities == null) {
+ return speeds;
+ }
+
+ int ccaLevel = mWifiChannelUtilization.getUtilizationRatio(currFrequency);
+
+ speeds.DownstreamKbps = mThroughputPredictor.predictRxThroughput(connectionCapabilities,
+ rssi, currFrequency, ccaLevel) * 1000;
+ speeds.UpstreamKbps = mThroughputPredictor.predictTxThroughput(connectionCapabilities,
+ rssi, currFrequency, ccaLevel) * 1000;
+
+ return speeds;
+ }
+
/**
* Update data stall detection, check throughput sufficiency and report wifi health stat
* with the latest link layer stats
diff --git a/service/java/com/android/server/wifi/WifiGlobals.java b/service/java/com/android/server/wifi/WifiGlobals.java
index f83dd79ef8..1b37c07f91 100644
--- a/service/java/com/android/server/wifi/WifiGlobals.java
+++ b/service/java/com/android/server/wifi/WifiGlobals.java
@@ -52,50 +52,22 @@ public class WifiGlobals {
private final WifiResourceCache mWifiResourceCache;
private final AtomicInteger mPollRssiIntervalMillis = new AtomicInteger(-1);
+ private final AtomicInteger mPollRssiShortIntervalMillis = new AtomicInteger();
+ private final AtomicInteger mPollRssiLongIntervalMillis = new AtomicInteger();
+ private boolean mIsPollRssiIntervalOverridden = false;
private final AtomicBoolean mIpReachabilityDisconnectEnabled = new AtomicBoolean(true);
private final AtomicBoolean mIsBluetoothConnected = new AtomicBoolean(false);
// Set default to false to check if the value will be overridden by WifiSettingConfigStore.
private final AtomicBoolean mIsWepAllowed = new AtomicBoolean(false);
private final AtomicBoolean mIsD2dStaConcurrencySupported = new AtomicBoolean(false);
private final AtomicInteger mSendDhcpHostnameRestriction = new AtomicInteger();
-
- // These are read from the overlay, cache them after boot up.
- private final boolean mIsWpa3SaeUpgradeEnabled;
private boolean mIsWpa3SaeUpgradeOffloadEnabled;
- private final boolean mIsOweUpgradeEnabled;
- private final boolean mFlushAnqpCacheOnWifiToggleOffEvent;
- private final boolean mIsWpa3SaeH2eSupported;
- private final String mP2pDeviceNamePrefix;
- private final int mP2pDeviceNamePostfixNumDigits;
- private final int mClientModeImplNumLogRecs;
- private final boolean mSaveFactoryMacToConfigStoreEnabled;
- private final int mWifiLowConnectedScoreThresholdToTriggerScanForMbb;
- private final int mWifiLowConnectedScoreScanPeriodSeconds;
- private final boolean mWifiAllowInsecureEnterpriseConfiguration;
- private final boolean mIsP2pMacRandomizationSupported;
- private final int mPollRssiShortIntervalMillis;
- private final int mPollRssiLongIntervalMillis;
- private final int mClientRssiMonitorThresholdDbm;
- private final int mClientRssiMonitorHysteresisDb;
+ private boolean mIsWpa3SaeH2eSupported;
private boolean mDisableFirmwareRoamingInIdleMode = false;
- private final boolean mIsSupportMultiInternetDual5G;
- private final int mRepeatedNudFailuresThreshold;
- private final int mRepeatedNudFailuresWindowMs;
- private final boolean mAdjustPollRssiIntervalEnabled;
- private final boolean mWifiInterfaceAddedSelfRecoveryEnabled;
- private final int mNetworkNotFoundEventThreshold;
- private boolean mIsSwPnoEnabled;
- private boolean mWepAllowedControlSupported;
- private final boolean mIsWpaPersonalDeprecated;
private final Map<String, List<String>> mCountryCodeToAfcServers;
- private final long mWifiConfigMaxDisableDurationMs;
// This is set by WifiManager#setVerboseLoggingEnabled(int).
private int mVerboseLoggingLevel = WifiManager.VERBOSE_LOGGING_LEVEL_DISABLED;
private boolean mIsUsingExternalScorer = false;
- private boolean mDisableUnwantedNetworkOnLowRssi = false;
- private final boolean mIsAfcSupportedOnDevice;
- private boolean mDisableNudDisconnectsForWapiInSpecificCc = false;
- private boolean mD2dAllowedControlSupportedWhenInfraStaDisabled = false;
private Set<String> mMacRandomizationUnsupportedSsidPrefixes = new ArraySet<>();
private SparseArray<SparseArray<CarrierSpecificEapFailureConfig>>
@@ -105,74 +77,17 @@ public class WifiGlobals {
public WifiGlobals(WifiContext context) {
mContext = context;
mWifiResourceCache = context.getResourceCache();
- mIsWpa3SaeUpgradeEnabled = mContext.getResources()
- .getBoolean(R.bool.config_wifiSaeUpgradeEnabled);
- mIsWpa3SaeUpgradeOffloadEnabled = mContext.getResources()
+ mIsWpa3SaeUpgradeOffloadEnabled = mWifiResourceCache
.getBoolean(R.bool.config_wifiSaeUpgradeOffloadEnabled);
- mIsOweUpgradeEnabled = mContext.getResources()
- .getBoolean(R.bool.config_wifiOweUpgradeEnabled);
- mFlushAnqpCacheOnWifiToggleOffEvent = mContext.getResources()
- .getBoolean(R.bool.config_wifiFlushAnqpCacheOnWifiToggleOffEvent);
- mIsWpa3SaeH2eSupported = mContext.getResources()
- .getBoolean(R.bool.config_wifiSaeH2eSupported);
- mP2pDeviceNamePrefix = mContext.getResources()
- .getString(R.string.config_wifiP2pDeviceNamePrefix);
- mP2pDeviceNamePostfixNumDigits = mContext.getResources()
- .getInteger(R.integer.config_wifiP2pDeviceNamePostfixNumDigits);
- mClientModeImplNumLogRecs = mContext.getResources()
- .getInteger(R.integer.config_wifiClientModeImplNumLogRecs);
- mSaveFactoryMacToConfigStoreEnabled = mContext.getResources()
- .getBoolean(R.bool.config_wifiSaveFactoryMacToWifiConfigStore);
- mWifiLowConnectedScoreThresholdToTriggerScanForMbb = mContext.getResources().getInteger(
- R.integer.config_wifiLowConnectedScoreThresholdToTriggerScanForMbb);
- mWifiLowConnectedScoreScanPeriodSeconds = mContext.getResources().getInteger(
- R.integer.config_wifiLowConnectedScoreScanPeriodSeconds);
- mWifiAllowInsecureEnterpriseConfiguration = mContext.getResources().getBoolean(
- R.bool.config_wifiAllowInsecureEnterpriseConfigurationsForSettingsAndSUW);
- mIsP2pMacRandomizationSupported = mContext.getResources().getBoolean(
- R.bool.config_wifi_p2p_mac_randomization_supported);
- mPollRssiIntervalMillis.set(mContext.getResources().getInteger(
+ mPollRssiIntervalMillis.set(mWifiResourceCache.getInteger(
R.integer.config_wifiPollRssiIntervalMilliseconds));
- mPollRssiShortIntervalMillis = mContext.getResources().getInteger(
- R.integer.config_wifiPollRssiIntervalMilliseconds);
- mPollRssiLongIntervalMillis = mContext.getResources().getInteger(
- R.integer.config_wifiPollRssiLongIntervalMilliseconds);
- mClientRssiMonitorThresholdDbm = mContext.getResources().getInteger(
- R.integer.config_wifiClientRssiMonitorThresholdDbm);
- mClientRssiMonitorHysteresisDb = mContext.getResources().getInteger(
- R.integer.config_wifiClientRssiMonitorHysteresisDb);
- mAdjustPollRssiIntervalEnabled = mContext.getResources().getBoolean(
- R.bool.config_wifiAdjustPollRssiIntervalEnabled);
- mDisableFirmwareRoamingInIdleMode = mContext.getResources()
- .getBoolean(R.bool.config_wifiDisableFirmwareRoamingInIdleMode);
- mIsSupportMultiInternetDual5G = mContext.getResources().getBoolean(
- R.bool.config_wifiAllowMultiInternetConnectDual5GFrequency);
- mRepeatedNudFailuresThreshold = mContext.getResources()
- .getInteger(R.integer.config_wifiDisableReasonRepeatedNudFailuresThreshold);
- mRepeatedNudFailuresWindowMs = mContext.getResources()
- .getInteger(R.integer.config_wifiDisableReasonRepeatedNudFailuresWindowMs);
- mWifiInterfaceAddedSelfRecoveryEnabled = mContext.getResources().getBoolean(
- R.bool.config_wifiInterfaceAddedSelfRecoveryEnabled);
- mDisableUnwantedNetworkOnLowRssi = mContext.getResources().getBoolean(
- R.bool.config_wifiDisableUnwantedNetworkOnLowRssi);
- mDisableNudDisconnectsForWapiInSpecificCc = mContext.getResources().getBoolean(
- R.bool.config_wifiDisableNudDisconnectsForWapiInSpecificCc);
- mNetworkNotFoundEventThreshold = mContext.getResources().getInteger(
- R.integer.config_wifiNetworkNotFoundEventThreshold);
- mIsSwPnoEnabled = mContext.getResources()
- .getBoolean(R.bool.config_wifiSwPnoEnabled);
- mWepAllowedControlSupported = mContext.getResources()
- .getBoolean(R.bool.config_wifiWepAllowedControlSupported);
- mIsWpaPersonalDeprecated = mContext.getResources()
- .getBoolean(R.bool.config_wifiWpaPersonalDeprecated);
- mIsAfcSupportedOnDevice = mContext.getResources().getBoolean(R.bool.config_wifiAfcSupported)
- && mContext.getResources().getBoolean(R.bool.config_wifiSoftap6ghzSupported)
- && mContext.getResources().getBoolean(R.bool.config_wifi6ghzSupport);
- mWifiConfigMaxDisableDurationMs = mContext.getResources()
- .getInteger(R.integer.config_wifiDisableTemporaryMaximumDurationMs);
- mD2dAllowedControlSupportedWhenInfraStaDisabled = mContext.getResources()
- .getBoolean(R.bool.config_wifiD2dAllowedControlSupportedWhenInfraStaDisabled);
- Set<String> unsupportedSsidPrefixes = new ArraySet<>(mContext.getResources().getStringArray(
+ mPollRssiShortIntervalMillis.set(mWifiResourceCache.getInteger(
+ R.integer.config_wifiPollRssiIntervalMilliseconds));
+ mPollRssiLongIntervalMillis.set(mWifiResourceCache.getInteger(
+ R.integer.config_wifiPollRssiLongIntervalMilliseconds));
+ mIsWpa3SaeH2eSupported = mWifiResourceCache
+ .getBoolean(R.bool.config_wifiSaeH2eSupported);
+ Set<String> unsupportedSsidPrefixes = new ArraySet<>(mWifiResourceCache.getStringArray(
R.array.config_wifiForceDisableMacRandomizationSsidPrefixList));
mCountryCodeToAfcServers = getCountryCodeToAfcServersMap();
if (!unsupportedSsidPrefixes.isEmpty()) {
@@ -209,7 +124,7 @@ public class WifiGlobals {
}
private void loadCarrierSpecificEapFailureConfigMap() {
- String[] eapFailureOverrides = mContext.getResources().getStringArray(
+ String[] eapFailureOverrides = mWifiResourceCache.getStringArray(
R.array.config_wifiEapFailureConfig);
if (eapFailureOverrides == null) {
return;
@@ -248,7 +163,7 @@ public class WifiGlobals {
private Map<String, List<String>> getCountryCodeToAfcServersMap() {
Map<String, List<String>> countryCodeToAfcServers = new HashMap<>();
- String[] countryCodeToAfcServersFromConfig = mContext.getResources().getStringArray(
+ String[] countryCodeToAfcServersFromConfig = mWifiResourceCache.getStringArray(
R.array.config_wifiAfcServerUrlsForCountry);
if (countryCodeToAfcServersFromConfig == null) {
@@ -300,7 +215,9 @@ public class WifiGlobals {
* Returns whether this device supports AFC.
*/
public boolean isAfcSupportedOnDevice() {
- return mIsAfcSupportedOnDevice;
+ return mWifiResourceCache.getBoolean(R.bool.config_wifiAfcSupported)
+ && mWifiResourceCache.getBoolean(R.bool.config_wifiSoftap6ghzSupported)
+ && mWifiResourceCache.getBoolean(R.bool.config_wifi6ghzSupport);
}
/** Sets whether CMD_IP_REACHABILITY_LOST events should trigger disconnects. */
@@ -335,7 +252,7 @@ public class WifiGlobals {
* @return boolean true if Connected MAC randomization is supported, false otherwise
*/
public boolean isConnectedMacRandomizationEnabled() {
- return mContext.getResources().getBoolean(
+ return mWifiResourceCache.getBoolean(
R.bool.config_wifi_connected_mac_randomization_supported);
}
@@ -345,9 +262,9 @@ public class WifiGlobals {
* @return boolean true if WEP networks are deprecated, false otherwise.
*/
public boolean isWepDeprecated() {
- return mWifiResourceCache.getBoolean(R.bool.config_wifiWepDeprecated,
- "config_wifiWepDeprecated")
- || (mWepAllowedControlSupported && !mIsWepAllowed.get());
+ return mWifiResourceCache.getBoolean(R.bool.config_wifiWepDeprecated)
+ || (mWifiResourceCache.getBoolean(R.bool.config_wifiWepAllowedControlSupported)
+ && !mIsWepAllowed.get());
}
/**
@@ -356,8 +273,8 @@ public class WifiGlobals {
* @return boolean true if WEP networks are supported, false otherwise.
*/
public boolean isWepSupported() {
- return !mWifiResourceCache.getBoolean(R.bool.config_wifiWepDeprecated,
- "config_wifiWepDeprecated");
+ return !mWifiResourceCache.getBoolean(R.bool.config_wifiWepDeprecated
+ );
}
/**
@@ -366,7 +283,8 @@ public class WifiGlobals {
* @return boolean true if WPA-Personal networks are deprecated, false otherwise.
*/
public boolean isWpaPersonalDeprecated() {
- return mIsWpaPersonalDeprecated;
+ return mWifiResourceCache
+ .getBoolean(R.bool.config_wifiWpaPersonalDeprecated);
}
/**
@@ -374,7 +292,8 @@ public class WifiGlobals {
* @return if the device should disable firmware roaming in idle mode.
*/
public boolean isDisableFirmwareRoamingInIdleMode() {
- return mDisableFirmwareRoamingInIdleMode;
+ return mWifiResourceCache
+ .getBoolean(R.bool.config_wifiDisableFirmwareRoamingInIdleMode);
}
/**
@@ -382,21 +301,24 @@ public class WifiGlobals {
* connect simultaneously to both 5GHz high and 5GHz low.
*/
public boolean isSupportMultiInternetDual5G() {
- return mIsSupportMultiInternetDual5G;
+ return mWifiResourceCache.getBoolean(
+ R.bool.config_wifiAllowMultiInternetConnectDual5GFrequency);
}
/**
* Get number of repeated NUD failures needed to disable a network.
*/
public int getRepeatedNudFailuresThreshold() {
- return mRepeatedNudFailuresThreshold;
+ return mWifiResourceCache
+ .getInteger(R.integer.config_wifiDisableReasonRepeatedNudFailuresThreshold);
}
/**
* Get the time window in millis to count for repeated NUD failures.
*/
public int getRepeatedNudFailuresWindowMs() {
- return mRepeatedNudFailuresWindowMs;
+ return mWifiResourceCache
+ .getInteger(R.integer.config_wifiDisableReasonRepeatedNudFailuresWindowMs);
}
/**
@@ -422,7 +344,8 @@ public class WifiGlobals {
* @return boolean true if auto-upgrade is enabled, false otherwise.
*/
public boolean isWpa3SaeUpgradeEnabled() {
- return mIsWpa3SaeUpgradeEnabled;
+ return mWifiResourceCache
+ .getBoolean(R.bool.config_wifiSaeUpgradeEnabled);
}
/**
@@ -451,7 +374,8 @@ public class WifiGlobals {
*/
public boolean isOweUpgradeEnabled() {
// OWE auto-upgrade is supported on S or newer releases.
- return SdkLevel.isAtLeastS() && mIsOweUpgradeEnabled;
+ return SdkLevel.isAtLeastS() && mWifiResourceCache
+ .getBoolean(R.bool.config_wifiOweUpgradeEnabled);
}
/**
@@ -460,7 +384,8 @@ public class WifiGlobals {
* @return boolean true to flush ANQP cache on Wi-Fi toggle off event, false otherwise.
*/
public boolean flushAnqpCacheOnWifiToggleOffEvent() {
- return mFlushAnqpCacheOnWifiToggleOffEvent;
+ return mWifiResourceCache
+ .getBoolean(R.bool.config_wifiFlushAnqpCacheOnWifiToggleOffEvent);
}
/*
@@ -473,6 +398,14 @@ public class WifiGlobals {
}
/**
+ * Helper method to enable WPA3 SAE Hash-to-Element support based on the supplicant aidl
+ * version.
+ */
+ public void enableWpa3SaeH2eSupport() {
+ mIsWpa3SaeH2eSupported = true;
+ }
+
+ /**
* Record the verbose logging level
*/
public void setVerboseLoggingLevel(int level) {
@@ -501,47 +434,59 @@ public class WifiGlobals {
/** Get the prefix of the default wifi p2p device name. */
public String getWifiP2pDeviceNamePrefix() {
- return mP2pDeviceNamePrefix;
+ return mWifiResourceCache
+ .getString(R.string.config_wifiP2pDeviceNamePrefix);
}
/** Get the number of the default wifi p2p device name postfix digit. */
public int getWifiP2pDeviceNamePostfixNumDigits() {
- return mP2pDeviceNamePostfixNumDigits;
+ return mWifiResourceCache
+ .getInteger(R.integer.config_wifiP2pDeviceNamePostfixNumDigits);
}
/** Get the number of log records to maintain. */
public int getClientModeImplNumLogRecs() {
- return mClientModeImplNumLogRecs;
+ return mWifiResourceCache.getInteger(R.integer.config_wifiClientModeImplNumLogRecs);
}
/** Get whether to use the saved factory MAC address when available **/
public boolean isSaveFactoryMacToConfigStoreEnabled() {
- return mSaveFactoryMacToConfigStoreEnabled;
+ return mWifiResourceCache
+ .getBoolean(R.bool.config_wifiSaveFactoryMacToWifiConfigStore);
}
/** Get the low score threshold to do scan for MBB when external scorer is not used. **/
public int getWifiLowConnectedScoreThresholdToTriggerScanForMbb() {
- return mWifiLowConnectedScoreThresholdToTriggerScanForMbb;
+ return mWifiResourceCache.getInteger(
+ R.integer.config_wifiLowConnectedScoreThresholdToTriggerScanForMbb);
}
/** Get the minimum period between the extra scans triggered for MBB when score is low **/
public int getWifiLowConnectedScoreScanPeriodSeconds() {
- return mWifiLowConnectedScoreScanPeriodSeconds;
+ return mWifiResourceCache.getInteger(
+ R.integer.config_wifiLowConnectedScoreScanPeriodSeconds);
}
/** Get whether or not insecure enterprise configuration is allowed. */
public boolean isInsecureEnterpriseConfigurationAllowed() {
- return mWifiAllowInsecureEnterpriseConfiguration;
+ return mWifiResourceCache.getBoolean(
+ R.bool.config_wifiAllowInsecureEnterpriseConfigurationsForSettingsAndSUW);
}
/** Get whether or not P2P MAC randomization is supported */
public boolean isP2pMacRandomizationSupported() {
- return mIsP2pMacRandomizationSupported;
+ return mWifiResourceCache.getBoolean(
+ R.bool.config_wifi_p2p_mac_randomization_supported);
}
/** Get the regular (short) interval between RSSI polls, in milliseconds. */
public int getPollRssiShortIntervalMillis() {
- return mPollRssiShortIntervalMillis;
+ return mPollRssiShortIntervalMillis.get();
+ }
+
+ /** Set the regular (short) interval between RSSI polls, in milliseconds. */
+ public void setPollRssiShortIntervalMillis(int newPollIntervalMillis) {
+ mPollRssiShortIntervalMillis.set(newPollIntervalMillis);
}
/**
@@ -550,7 +495,16 @@ public class WifiGlobals {
* interval.
*/
public int getPollRssiLongIntervalMillis() {
- return mPollRssiLongIntervalMillis;
+ return mPollRssiLongIntervalMillis.get();
+ }
+
+ /**
+ * Set the long interval between RSSI polls, in milliseconds. The long interval is to
+ * reduce power consumption of the polls. This value should be greater than the regular
+ * interval.
+ */
+ public void setPollRssiLongIntervalMillis(int newPollIntervalMillis) {
+ mPollRssiLongIntervalMillis.set(newPollIntervalMillis);
}
/**
@@ -560,7 +514,8 @@ public class WifiGlobals {
* Threshold, set regular interval and disable RSSI monitoring.
*/
public int getClientRssiMonitorThresholdDbm() {
- return mClientRssiMonitorThresholdDbm;
+ return mWifiResourceCache.getInteger(
+ R.integer.config_wifiClientRssiMonitorThresholdDbm);
}
/**
@@ -568,7 +523,8 @@ public class WifiGlobals {
* frequent switch between regular and long polling intervals.
*/
public int getClientRssiMonitorHysteresisDb() {
- return mClientRssiMonitorHysteresisDb;
+ return mWifiResourceCache.getInteger(
+ R.integer.config_wifiClientRssiMonitorHysteresisDb);
}
/**
@@ -576,14 +532,26 @@ public class WifiGlobals {
* is enabled.
*/
public boolean isAdjustPollRssiIntervalEnabled() {
- return mAdjustPollRssiIntervalEnabled;
+ return mWifiResourceCache.getBoolean(
+ R.bool.config_wifiAdjustPollRssiIntervalEnabled);
+ }
+
+ /** Set whether the RSSI polling interval is overridden to a fixed value **/
+ public void setPollRssiIntervalOverridden(boolean isPollRssiIntervalOverridden) {
+ mIsPollRssiIntervalOverridden = isPollRssiIntervalOverridden;
+ }
+
+ /** Get whether the RSSI polling interval is overridden to a fixed value **/
+ public boolean isPollRssiIntervalOverridden() {
+ return mIsPollRssiIntervalOverridden;
}
/**
* Get whether hot-plugging an interface will trigger a restart of the wifi stack.
*/
public boolean isWifiInterfaceAddedSelfRecoveryEnabled() {
- return mWifiInterfaceAddedSelfRecoveryEnabled;
+ return mWifiResourceCache.getBoolean(
+ R.bool.config_wifiInterfaceAddedSelfRecoveryEnabled);
}
/**
@@ -591,36 +559,40 @@ public class WifiGlobals {
*/
public boolean isBackgroundScanSupported() {
return mWifiResourceCache
- .getBoolean(R.bool.config_wifi_background_scan_support,
- "config_wifi_background_scan_support");
+ .getBoolean(R.bool.config_wifi_background_scan_support
+ );
};
/**
* Get whether software pno is enabled.
*/
public boolean isSwPnoEnabled() {
- return mIsSwPnoEnabled;
+ return mWifiResourceCache
+ .getBoolean(R.bool.config_wifiSwPnoEnabled);
};
/**
* Get whether to temporarily disable a unwanted network that has low RSSI.
*/
public boolean disableUnwantedNetworkOnLowRssi() {
- return mDisableUnwantedNetworkOnLowRssi;
+ return mWifiResourceCache.getBoolean(
+ R.bool.config_wifiDisableUnwantedNetworkOnLowRssi);
}
/**
* Get whether to disable NUD disconnects for WAPI configurations in a specific CC.
*/
public boolean disableNudDisconnectsForWapiInSpecificCc() {
- return mDisableNudDisconnectsForWapiInSpecificCc;
+ return mWifiResourceCache.getBoolean(
+ R.bool.config_wifiDisableNudDisconnectsForWapiInSpecificCc);
}
/**
* Get the threshold to use for blocking a network due to NETWORK_NOT_FOUND_EVENT failure.
*/
public int getNetworkNotFoundEventThreshold() {
- return mNetworkNotFoundEventThreshold;
+ return mWifiResourceCache.getInteger(
+ R.integer.config_wifiNetworkNotFoundEventThreshold);
}
/**
@@ -648,10 +620,15 @@ public class WifiGlobals {
* Returns whether the device supports device-to-device when infra STA is disabled.
*/
public boolean isD2dSupportedWhenInfraStaDisabled() {
- return mD2dAllowedControlSupportedWhenInfraStaDisabled
+ return mWifiResourceCache
+ .getBoolean(R.bool.config_wifiD2dAllowedControlSupportedWhenInfraStaDisabled)
&& !mIsD2dStaConcurrencySupported.get();
}
+ public boolean isNetworkSelectionSetTargetBssid() {
+ return mWifiResourceCache.getBoolean(R.bool.config_wifiNetworkSelectionSetTargetBssid);
+ }
+
/**
* Set the global dhcp hostname restriction.
*/
@@ -672,50 +649,27 @@ public class WifiGlobals {
* Get the maximum Wifi temporary disable duration.
*/
public long getWifiConfigMaxDisableDurationMs() {
- return mWifiConfigMaxDisableDurationMs;
+ return mWifiResourceCache
+ .getInteger(R.integer.config_wifiDisableTemporaryMaximumDurationMs);
}
/** Dump method for debugging */
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("Dump of WifiGlobals");
pw.println("mPollRssiIntervalMillis=" + mPollRssiIntervalMillis.get());
+ pw.println("mIsPollRssiIntervalOverridden=" + mIsPollRssiIntervalOverridden);
+ pw.println("mPollRssiShortIntervalMillis=" + mPollRssiShortIntervalMillis.get());
+ pw.println("mPollRssiLongIntervalMillis=" + mPollRssiLongIntervalMillis.get());
pw.println("mIpReachabilityDisconnectEnabled=" + mIpReachabilityDisconnectEnabled.get());
pw.println("mIsBluetoothConnected=" + mIsBluetoothConnected.get());
- pw.println("mIsWpa3SaeUpgradeEnabled=" + mIsWpa3SaeUpgradeEnabled);
pw.println("mIsWpa3SaeUpgradeOffloadEnabled=" + mIsWpa3SaeUpgradeOffloadEnabled);
- pw.println("mIsOweUpgradeEnabled=" + mIsOweUpgradeEnabled);
- pw.println("mFlushAnqpCacheOnWifiToggleOffEvent=" + mFlushAnqpCacheOnWifiToggleOffEvent);
- pw.println("mIsWpa3SaeH2eSupported=" + mIsWpa3SaeH2eSupported);
- pw.println("mP2pDeviceNamePrefix=" + mP2pDeviceNamePrefix);
- pw.println("mP2pDeviceNamePostfixNumDigits=" + mP2pDeviceNamePostfixNumDigits);
- pw.println("mClientModeImplNumLogRecs=" + mClientModeImplNumLogRecs);
- pw.println("mSaveFactoryMacToConfigStoreEnabled=" + mSaveFactoryMacToConfigStoreEnabled);
- pw.println("mWifiLowConnectedScoreThresholdToTriggerScanForMbb="
- + mWifiLowConnectedScoreThresholdToTriggerScanForMbb);
- pw.println("mWifiLowConnectedScoreScanPeriodSeconds="
- + mWifiLowConnectedScoreScanPeriodSeconds);
pw.println("mIsUsingExternalScorer="
+ mIsUsingExternalScorer);
- pw.println("mWifiAllowInsecureEnterpriseConfiguration="
- + mWifiAllowInsecureEnterpriseConfiguration);
- pw.println("mIsP2pMacRandomizationSupported" + mIsP2pMacRandomizationSupported);
- pw.println("mWifiInterfaceAddedSelfRecoveryEnabled="
- + mWifiInterfaceAddedSelfRecoveryEnabled);
- pw.println("mDisableUnwantedNetworkOnLowRssi=" + mDisableUnwantedNetworkOnLowRssi);
- pw.println("mNetworkNotFoundEventThreshold=" + mNetworkNotFoundEventThreshold);
- pw.println("mIsSwPnoEnabled=" + mIsSwPnoEnabled);
- pw.println("mIsWpaPersonalDeprecated=" + mIsWpaPersonalDeprecated);
pw.println("mIsWepAllowed=" + mIsWepAllowed.get());
- pw.println("mWepAllowedControlSupported=" + mWepAllowedControlSupported);
pw.println("mDisableFirmwareRoamingInIdleMode=" + mDisableFirmwareRoamingInIdleMode);
- pw.println("mRepeatedNudFailuresThreshold=" + mRepeatedNudFailuresThreshold);
- pw.println("mRepeatedNudFailuresWindowMs=" + mRepeatedNudFailuresWindowMs);
- pw.println("mCarrierSpecificEapFailureConfigMapPerCarrierId mapping below:");
- pw.println("mWifiConfigMaxDisableDurationMs=" + mWifiConfigMaxDisableDurationMs);
- pw.println("mD2dAllowedControlSupportedWhenInfraStaDisabled="
- + mD2dAllowedControlSupportedWhenInfraStaDisabled);
pw.println("IsD2dSupportedWhenInfraStaDisabled="
+ isD2dSupportedWhenInfraStaDisabled());
+ pw.println("mIsWpa3SaeH2eSupported=" + mIsWpa3SaeH2eSupported);
for (int i = 0; i < mCarrierSpecificEapFailureConfigMapPerCarrierId.size(); i++) {
int carrierId = mCarrierSpecificEapFailureConfigMapPerCarrierId.keyAt(i);
SparseArray<CarrierSpecificEapFailureConfig> perFailureMap =
@@ -729,7 +683,6 @@ public class WifiGlobals {
+ ", durationMs=" + perFailureMap.valueAt(j).durationMs);
}
}
- pw.println("mIsSupportMultiInternetDual5G=" + mIsSupportMultiInternetDual5G);
pw.println("mSendDhcpHostnameRestriction=" + mSendDhcpHostnameRestriction.get());
}
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 9553434380..ddb7a0f48a 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -269,6 +269,7 @@ public class WifiInjector {
private final WifiRoamingModeManager mWifiRoamingModeManager;
private final TwtManager mTwtManager;
private final WifiVoipDetector mWifiVoipDetector;
+ private final boolean mHasActiveModem;
public WifiInjector(WifiContext context) {
if (context == null) {
@@ -623,12 +624,13 @@ public class WifiInjector {
mTwtManager = new TwtManager(this, mCmiMonitor, mWifiNative, wifiHandler, mClock,
WifiTwtSession.MAX_TWT_SESSIONS, 1);
mBackupRestoreController = new BackupRestoreController(mWifiSettingsBackupRestore, mClock);
- if (mFeatureFlags.voipDetection() && SdkLevel.isAtLeastV()) {
+ if (mFeatureFlags.voipDetectionBugfix() && SdkLevel.isAtLeastV()) {
mWifiVoipDetector = new WifiVoipDetector(mContext, wifiHandler, this,
mWifiCarrierInfoManager);
} else {
mWifiVoipDetector = null;
}
+ mHasActiveModem = makeTelephonyManager().getActiveModemCount() > 0;
}
/**
@@ -1295,4 +1297,11 @@ public class WifiInjector {
public WifiVoipDetector getWifiVoipDetector() {
return mWifiVoipDetector;
}
+
+ /**
+ * Return true if there is any active modem on the device.
+ */
+ public boolean hasActiveModem() {
+ return mHasActiveModem;
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index 93cb2ab8d8..45c636e115 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -21,6 +21,29 @@ import static android.net.wifi.WifiConfiguration.MeteredOverride;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY;
import static com.android.server.wifi.proto.WifiStatsLog.WIFI_CONFIG_SAVED;
import static com.android.server.wifi.proto.WifiStatsLog.WIFI_IS_UNUSABLE_REPORTED;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_CELLULAR_MODEM;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_SIM_INSERTED;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_SCORING_DISABLED;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_CELLULAR_OFF;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_CELLULAR_UNAVAILABLE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_OTHERS;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__TRUE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__FALSE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__TRUE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__FALSE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__TRUE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__FALSE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__TRUE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__FALSE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_FRAMEWORK_DATA_STALL;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_FIRMWARE_ALERT;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_IP_REACHABILITY_LOST;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_NONE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_AWAKENING;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_CONNECTED;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_LINGERING;
+
import static java.lang.StrictMath.toIntExact;
@@ -32,6 +55,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.net.ConnectivityManager;
+import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.wifi.EAPConstants;
import android.net.wifi.IOnWifiUsabilityStatsListener;
@@ -79,6 +104,7 @@ import android.util.SparseIntArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.SupplicantStaIfaceHal.StaIfaceReasonCode;
import com.android.server.wifi.SupplicantStaIfaceHal.StaIfaceStatusCode;
+import com.android.server.wifi.WifiNative.ConnectionCapabilities;
import com.android.server.wifi.aware.WifiAwareMetrics;
import com.android.server.wifi.hotspot2.ANQPNetworkKey;
import com.android.server.wifi.hotspot2.NetworkDetail;
@@ -138,6 +164,7 @@ import com.android.server.wifi.util.IntHistogram;
import com.android.server.wifi.util.MetricsUtils;
import com.android.server.wifi.util.ObjectCounter;
import com.android.server.wifi.util.StringUtil;
+import com.android.wifi.flags.Flags;
import com.android.wifi.resources.R;
import org.json.JSONArray;
@@ -243,6 +270,9 @@ public class WifiMetrics {
// Number of WME Access Categories
private static final int NUM_WME_ACCESS_CATEGORIES = 4;
private static final int MBB_LINGERING_DURATION_MAX_SECONDS = 30;
+ public static final int MIN_DOWNSTREAM_BANDWIDTH_KBPS = 1000;
+ public static final int MIN_UPSTREAM_BANDWIDTH_KBPS = 1000;
+ public static final int INVALID_SPEED = -1;
private Clock mClock;
private boolean mScreenOn;
@@ -267,7 +297,8 @@ public class WifiMetrics {
private WifiHealthMonitor mWifiHealthMonitor;
private WifiScoreCard mWifiScoreCard;
private SessionData mPreviousSession;
- private SessionData mCurrentSession;
+ @VisibleForTesting
+ public SessionData mCurrentSession;
private String mLastBssid;
private int mLastFrequency = -1;
private int mSeqNumInsideFramework = 0;
@@ -301,6 +332,8 @@ public class WifiMetrics {
private boolean mFirstConnectionAfterBoot = true;
private long mLastTotalBeaconRx = 0;
private int mScorerUid = Process.WIFI_UID;
+ @VisibleForTesting
+ int mUnusableEventType = WifiIsUnusableEvent.TYPE_UNKNOWN;
/**
* Wi-Fi usability state per interface as predicted by the network scorer.
@@ -488,7 +521,7 @@ public class WifiMetrics {
/** WifiConfigStore write duration histogram. */
private SparseIntArray mWifiConfigStoreWriteDurationHistogram = new SparseIntArray();
- /** New API surface metrics */
+ /** New API surface metrics */
private final WifiNetworkRequestApiLog mWifiNetworkRequestApiLog =
new WifiNetworkRequestApiLog();
private static final int[] NETWORK_REQUEST_API_MATCH_SIZE_HISTOGRAM_BUCKETS =
@@ -612,6 +645,12 @@ public class WifiMetrics {
private final WifiToWifiSwitchStats mWifiToWifiSwitchStats = new WifiToWifiSwitchStats();
+ private long mLastScreenOnTimeMillis = 0;
+ @VisibleForTesting
+ long mLastScreenOffTimeMillis = 0;
+ @VisibleForTesting
+ long mLastIgnoredPollTimeMillis = 0;
+
/** Wi-Fi link specific metrics (MLO). */
public static class LinkMetrics {
private long mTotalBeaconRx = 0;
@@ -660,13 +699,15 @@ public class WifiMetrics {
}
}
- private static class SessionData {
+ @VisibleForTesting
+ public static class SessionData {
private String mSsid;
- private long mSessionStartTimeMillis;
+ @VisibleForTesting
+ public long mSessionStartTimeMillis;
private long mSessionEndTimeMillis;
private int mBand;
private int mAuthType;
- private ConnectionEvent mConnectionEvent;
+ public ConnectionEvent mConnectionEvent;
private long mLastRoamCompleteMillis;
SessionData(ConnectionEvent connectionEvent, String ssid, long sessionStartTimeMillis,
@@ -1184,7 +1225,8 @@ public class WifiMetrics {
private int mPasspointRoamingType;
private int mTofuConnectionState;
- private ConnectionEvent() {
+ @VisibleForTesting
+ ConnectionEvent() {
mConnectionEvent = new WifiMetricsProto.ConnectionEvent();
mRouterFingerPrint = new RouterFingerPrint();
mConnectionEvent.routerFingerprint = mRouterFingerPrint.mRouterFingerPrintProto;
@@ -1650,7 +1692,7 @@ public class WifiMetrics {
new WifiDeviceStateChangeManager.StateChangeCallback() {
@Override
public void onScreenStateChanged(boolean screenOn) {
- setScreenState(screenOn);
+ handleScreenStateChanged(screenOn);
}
});
}
@@ -6049,11 +6091,16 @@ public class WifiMetrics {
}
/**
- * Set screen state (On/Off)
+ * Handle screen state changing.
*/
- private void setScreenState(boolean screenOn) {
+ private void handleScreenStateChanged(boolean screenOn) {
synchronized (mLock) {
mScreenOn = screenOn;
+ if (screenOn) {
+ mLastScreenOnTimeMillis = mClock.getElapsedSinceBootMillis();
+ } else {
+ mLastScreenOffTimeMillis = mClock.getElapsedSinceBootMillis();
+ }
}
}
@@ -6936,6 +6983,7 @@ public class WifiMetrics {
WifiIsUnusableEvent event = new WifiIsUnusableEvent();
event.type = triggerType;
+ mUnusableEventType = triggerType;
if (triggerType == WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT) {
event.firmwareAlertCode = firmwareAlertCode;
}
@@ -6995,6 +7043,10 @@ public class WifiMetrics {
}
}
+ public boolean isWiFiScorerNewStatsCollected() {
+ return Flags.wifiScorerNewStatsCollection();
+ }
+
/**
* Extract data from |info| and |stats| to build a WifiUsabilityStatsEntry and then adds it
* into an internal ring buffer.
@@ -8770,6 +8822,243 @@ public class WifiMetrics {
}
}
+ @VisibleForTesting
+ int getDeviceStateForScorer(boolean hasActiveModem, boolean hasActiveSubInfo,
+ boolean isMobileDataEnabled, boolean isCellularDataAvailable,
+ boolean adaptiveConnectivityEnabled) {
+ if (!hasActiveModem) {
+ return SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_CELLULAR_MODEM;
+ }
+ if (!hasActiveSubInfo) {
+ return SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_SIM_INSERTED;
+ }
+ if (!adaptiveConnectivityEnabled) {
+ return SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_SCORING_DISABLED;
+ }
+ if (!isMobileDataEnabled) {
+ return SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_CELLULAR_OFF;
+ }
+ if (!isCellularDataAvailable) {
+ return SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_CELLULAR_UNAVAILABLE;
+ }
+ return SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_OTHERS;
+ }
+
+ @VisibleForTesting
+ int convertWifiUnusableTypeForScorer(int triggerType) {
+ switch (triggerType) {
+ case WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX:
+ case WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX:
+ case WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH:
+ return SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_FRAMEWORK_DATA_STALL;
+ case WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT:
+ return SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_FIRMWARE_ALERT;
+ case WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST:
+ return SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_IP_REACHABILITY_LOST;
+ default:
+ return SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_NONE;
+ }
+ }
+
+ @VisibleForTesting
+ int getFrameworkStateForScorer(boolean lingering) {
+ // The first poll after the screen turns on is termed the AWAKENING state.
+ if (mLastIgnoredPollTimeMillis <= mLastScreenOffTimeMillis) {
+ mLastIgnoredPollTimeMillis = mClock.getElapsedSinceBootMillis();
+ return SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_AWAKENING;
+ }
+ if (lingering) {
+ return SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_LINGERING;
+ }
+ return SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_CONNECTED;
+ }
+
+ private class ConnectivityManagerCache {
+ ConnectivityManagerCache() { }
+
+ private ConnectivityManager mConnectivityManager;
+
+ /**
+ * Returns the cached ConnectivityManager or performs a system call to fetch it before
+ * returning.
+ *
+ * Note that this function can still return null if getSystemService cannot find the
+ * connectivity manager.
+ */
+ public ConnectivityManager getConnectivityManager() {
+ if (mConnectivityManager == null) {
+ mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
+ }
+ return mConnectivityManager;
+ }
+ }
+ private final ConnectivityManagerCache mConnectivityManagerCache =
+ new ConnectivityManagerCache();
+
+ @VisibleForTesting
+ public static class Speeds {
+ public int DownstreamKbps = INVALID_SPEED;
+ public int UpstreamKbps = INVALID_SPEED;
+ }
+
+ /**
+ * Returns the NetworkCapabilites based link capacity estimates.
+ */
+ Speeds getNetworkCapabilitiesSpeeds() {
+ Speeds speeds = new Speeds();
+
+ ConnectivityManager connectivityManager =
+ mConnectivityManagerCache.getConnectivityManager();
+ if (connectivityManager == null) {
+ return speeds;
+ }
+
+ Network activeNetwork = connectivityManager.getActiveNetwork();
+ if (activeNetwork == null) {
+ return speeds;
+ }
+
+ NetworkCapabilities networkCapabilities =
+ connectivityManager.getNetworkCapabilities(activeNetwork);
+ if (networkCapabilities == null) {
+ return speeds;
+ }
+
+ // Normally, we will not get called when WiFi is not active. This deals with a corner case
+ // where we have switched to cellular but we end up getting called one last time.
+ if (!networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
+ return speeds;
+ }
+
+ speeds.DownstreamKbps = networkCapabilities.getLinkDownstreamBandwidthKbps();
+ speeds.UpstreamKbps = networkCapabilities.getLinkUpstreamBandwidthKbps();
+
+ return speeds;
+ }
+
+ @VisibleForTesting
+ public static class SpeedSufficient {
+ // Note the default value of 0 maps to '.*UNKNOWN' for the speed sufficient enums that we
+ // use below. Specifically they map to 0 for:
+ // SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__UNKNOWN
+ // SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__UNKNOWN
+ // SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__UNKNOWN
+ // SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__UNKNOWN
+ public int Downstream = 0;
+ public int Upstream = 0;
+ }
+
+ @VisibleForTesting
+ SpeedSufficient calcSpeedSufficientNetworkCapabilities(Speeds speeds) {
+ SpeedSufficient speedSufficient = new SpeedSufficient();
+
+ if (speeds == null) {
+ return speedSufficient;
+ }
+
+ if (speeds.DownstreamKbps != INVALID_SPEED) {
+ speedSufficient.Downstream = (speeds.DownstreamKbps < MIN_DOWNSTREAM_BANDWIDTH_KBPS)
+ ? SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__FALSE
+ : SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__TRUE;
+
+ }
+
+ if (speeds.UpstreamKbps != INVALID_SPEED) {
+ speedSufficient.Upstream = (speeds.UpstreamKbps < MIN_UPSTREAM_BANDWIDTH_KBPS)
+ ? SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__FALSE
+ : SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__TRUE;
+ }
+
+ return speedSufficient;
+ }
+
+ @VisibleForTesting
+ SpeedSufficient calcSpeedSufficientThroughputPredictor(WifiDataStall.Speeds speeds) {
+ SpeedSufficient speedSufficient = new SpeedSufficient();
+
+ if (speeds == null) {
+ return speedSufficient;
+ }
+
+ if (speeds.DownstreamKbps != WifiDataStall.INVALID_THROUGHPUT) {
+ speedSufficient.Downstream = (speeds.DownstreamKbps < MIN_DOWNSTREAM_BANDWIDTH_KBPS)
+ ? SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__FALSE
+ : SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__TRUE;
+
+ }
+
+ if (speeds.UpstreamKbps != WifiDataStall.INVALID_THROUGHPUT) {
+ speedSufficient.Upstream = (speeds.UpstreamKbps < MIN_UPSTREAM_BANDWIDTH_KBPS)
+ ? SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__FALSE
+ : SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__TRUE;
+ }
+
+ return speedSufficient;
+ }
+
+ /**
+ * Log a ScorerPredictionResultReported atom.
+ */
+ public void logScorerPredictionResult(boolean hasActiveModem,
+ boolean hasActiveSubInfo,
+ boolean isMobileDataEnabled,
+ int pollingIntervalMs,
+ int aospScorerPrediction,
+ int externalScorerPrediction,
+ boolean lingering,
+ WifiInfo wifiInfo,
+ ConnectionCapabilities connectionCapabilities
+ ) {
+ boolean isCellularDataAvailable = mWifiDataStall.isCellularDataAvailable();
+ boolean isThroughputSufficient = mWifiDataStall.isThroughputSufficient();
+ int deviceState = getDeviceStateForScorer(
+ hasActiveModem,
+ hasActiveSubInfo, isMobileDataEnabled, isCellularDataAvailable,
+ mAdaptiveConnectivityEnabled);
+ int scorerUnusableEvent = convertWifiUnusableTypeForScorer(mUnusableEventType);
+ int wifiFrameworkState = getFrameworkStateForScorer(lingering);
+ Speeds speedsNetworkCapabilities = getNetworkCapabilitiesSpeeds();
+ SpeedSufficient speedSufficientNetworkCapabilities =
+ calcSpeedSufficientNetworkCapabilities(speedsNetworkCapabilities);
+ WifiDataStall.Speeds speedsThroughputPredictor = mWifiDataStall.getThrouhgputPredictorSpeeds(
+ wifiInfo, connectionCapabilities);
+ SpeedSufficient speedSufficientThroughputPredictor =
+ calcSpeedSufficientThroughputPredictor(speedsThroughputPredictor);
+
+ WifiStatsLog.write_non_chained(SCORER_PREDICTION_RESULT_REPORTED,
+ Process.WIFI_UID,
+ null,
+ aospScorerPrediction,
+ scorerUnusableEvent,
+ isThroughputSufficient, deviceState, pollingIntervalMs,
+ wifiFrameworkState, speedSufficientNetworkCapabilities.Downstream,
+ speedSufficientNetworkCapabilities.Upstream,
+ speedSufficientThroughputPredictor.Downstream,
+ speedSufficientThroughputPredictor.Upstream);
+ if (mScorerUid != Process.WIFI_UID) {
+ WifiStatsLog.write_non_chained(SCORER_PREDICTION_RESULT_REPORTED,
+ mScorerUid,
+ null, // TODO(b/354737760): log the attribution tag
+ externalScorerPrediction,
+ scorerUnusableEvent,
+ isThroughputSufficient, deviceState, pollingIntervalMs,
+ wifiFrameworkState, speedSufficientNetworkCapabilities.Downstream,
+ speedSufficientNetworkCapabilities.Upstream,
+ speedSufficientThroughputPredictor.Downstream,
+ speedSufficientThroughputPredictor.Upstream);
+ }
+
+ // We'd better reset to TYPE_NONE if it is defined in the future.
+ mUnusableEventType = WifiIsUnusableEvent.TYPE_UNKNOWN;
+ }
+
+ /**
+ * Clear the saved unusable event type.
+ */
+ public void resetWifiUnusableEvent() {
+ mUnusableEventType = WifiIsUnusableEvent.TYPE_UNKNOWN;
+ }
+
/**
* Get total beacon receive count
*/
@@ -9448,7 +9737,8 @@ public class WifiMetrics {
boolean isStaApSupported,
boolean isStaDbsSupported,
int staFreqMhz,
- @SoftApConfiguration.SecurityType int securityType) {
+ @SoftApConfiguration.SecurityType int securityType,
+ WorkSource source) {
WifiStatsLog.write(WifiStatsLog.SOFT_AP_STARTED,
getSoftApStartedStartResult(startResult),
getSoftApStartedRole(role),
@@ -9457,7 +9747,8 @@ public class WifiMetrics {
isDbsSupported,
getSoftApStartedStaApConcurrency(isStaApSupported, isStaDbsSupported),
getSoftApStartedStaStatus(staFreqMhz),
- getSoftApStartedAuthType(securityType));
+ getSoftApStartedAuthType(securityType),
+ source.getUid(0));
if (startResult == SoftApManager.START_RESULT_SUCCESS) {
WifiStatsLog.write(WifiStatsLog.SOFT_AP_STATE_CHANGED,
WifiStatsLog.SOFT_AP_STATE_CHANGED__HOTSPOT_ON__STATE_ON);
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 9ec97ee493..aa1d3398e9 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -21,11 +21,15 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDGE;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_NAN;
-import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_STA;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_P2P;
+import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_STA;
+import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_NATIVE_EXTENDED_SUPPORTED_FEATURES;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_NATIVE_SUPPORTED_FEATURES;
import static com.android.server.wifi.p2p.WifiP2pNative.P2P_IFACE_NAME;
import static com.android.server.wifi.p2p.WifiP2pNative.P2P_INTERFACE_PROPERTY;
+import static com.android.server.wifi.util.GeneralUtil.bitsetToLong;
+import static com.android.server.wifi.util.GeneralUtil.longToBitset;
+import static com.android.wifi.flags.Flags.rsnOverriding;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -134,12 +138,13 @@ public class WifiNative {
private NetdWrapper mNetdWrapper;
private boolean mVerboseLoggingEnabled = false;
private boolean mIsEnhancedOpenSupported = false;
+ @VisibleForTesting boolean mIsRsnOverridingSupported = false;
private final List<CoexUnsafeChannel> mCachedCoexUnsafeChannels = new ArrayList<>();
private int mCachedCoexRestrictions;
private CountryCodeChangeListenerInternal mCountryCodeChangeListener;
private boolean mUseFakeScanDetails;
private final ArrayList<ScanDetail> mFakeScanDetails = new ArrayList<>();
- private long mCachedFeatureSet;
+ private BitSet mCachedFeatureSet = null;
private boolean mQosPolicyFeatureEnabled = false;
private final Map<String, String> mWifiCondIfacesForBridgedAp = new ArrayMap<>();
private MockWifiServiceUtil mMockWifiModem = null;
@@ -1557,6 +1562,8 @@ public class WifiNative {
iface.featureSet = getSupportedFeatureSetInternal(iface.name);
updateSupportedBandForStaInternal(iface);
+ mIsRsnOverridingSupported = mContext.getResources().getBoolean(
+ R.bool.config_wifiRsnOverridingEnabled) && rsnOverriding();
mWifiVendorHal.enableStaChannelForPeerNetwork(mContext.getResources().getBoolean(
R.bool.config_wifiEnableStaIndoorChannelForPeerNetwork),
@@ -2090,6 +2097,7 @@ public class WifiNative {
ies,
result.getCapabilities(),
mIsEnhancedOpenSupported,
+ mIsRsnOverridingSupported,
result.getFrequencyMhz(),
mUnknownAkmMap);
String flags = capabilities.generateCapabilitiesString();
@@ -3618,6 +3626,11 @@ public class WifiNative {
* See WifiScanner.REASON_* for possible values.
*/
void onScanRequestFailed(int errorCode);
+
+ /**
+ * Callback for all APs ScanResult
+ */
+ void onFullScanResults(List<ScanResult> fullScanResult, int bucketsScanned);
}
/**
@@ -3936,7 +3949,7 @@ public class WifiNative {
long featureSet = 0;
// First get the complete feature set stored in config store when supplicant was
// started
- featureSet = getCompleteFeatureSetFromConfigStore();
+ featureSet = bitsetToLong(getCompleteFeatureSetFromConfigStore());
// Include the feature set saved in interface class. This is to make sure that
// framework is returning the feature set for SoftAp only products and multi-chip
// products.
@@ -3973,9 +3986,10 @@ public class WifiNative {
* @return bitmask defined by WifiManager.WIFI_FEATURE_*
*/
private long getSupportedFeatureSetInternal(@NonNull String ifaceName) {
- long featureSet = mSupplicantStaIfaceHal.getAdvancedCapabilities(ifaceName)
- | mWifiVendorHal.getSupportedFeatureSet(ifaceName)
- | mSupplicantStaIfaceHal.getWpaDriverFeatureSet(ifaceName);
+ BitSet featureBitset = mSupplicantStaIfaceHal.getAdvancedCapabilities(ifaceName);
+ featureBitset.or(mSupplicantStaIfaceHal.getWpaDriverFeatureSet(ifaceName));
+ featureBitset.or(mWifiVendorHal.getSupportedFeatureSet(ifaceName));
+ long featureSet = bitsetToLong(featureBitset);
if (SdkLevel.isAtLeastT()) {
if (((featureSet & WifiManager.WIFI_FEATURE_DPP) != 0)
&& mContext.getResources().getBoolean(R.bool.config_wifiDppAkmSupported)) {
@@ -5159,12 +5173,13 @@ public class WifiNative {
* Save the complete list of features retrieved from WiFi HAL and Supplicant HAL in
* config store.
*/
- private void saveCompleteFeatureSetInConfigStoreIfNecessary(long featureSet) {
- long cachedFeatureSet = getCompleteFeatureSetFromConfigStore();
- if (cachedFeatureSet != featureSet) {
+ private void saveCompleteFeatureSetInConfigStoreIfNecessary(long featureSetLong) {
+ BitSet featureSet = longToBitset(featureSetLong);
+ BitSet cachedFeatureSet = getCompleteFeatureSetFromConfigStore();
+ if (!cachedFeatureSet.equals(featureSet)) {
mCachedFeatureSet = featureSet;
mWifiInjector.getSettingsConfigStore()
- .put(WIFI_NATIVE_SUPPORTED_FEATURES, mCachedFeatureSet);
+ .put(WIFI_NATIVE_EXTENDED_SUPPORTED_FEATURES, mCachedFeatureSet.toLongArray());
Log.i(TAG, "Supported features is updated in config store: " + mCachedFeatureSet);
}
}
@@ -5172,10 +5187,18 @@ public class WifiNative {
/**
* Get the feature set from cache/config store
*/
- private long getCompleteFeatureSetFromConfigStore() {
- if (mCachedFeatureSet == 0) {
- mCachedFeatureSet = mWifiInjector.getSettingsConfigStore()
- .get(WIFI_NATIVE_SUPPORTED_FEATURES);
+ private BitSet getCompleteFeatureSetFromConfigStore() {
+ if (mCachedFeatureSet == null) {
+ long[] extendedFeatures = mWifiInjector.getSettingsConfigStore()
+ .get(WIFI_NATIVE_EXTENDED_SUPPORTED_FEATURES);
+ if (extendedFeatures == null || extendedFeatures.length == 0) {
+ // Retrieve the legacy feature set if the extended features are not available
+ long legacyFeatures = mWifiInjector.getSettingsConfigStore()
+ .get(WIFI_NATIVE_SUPPORTED_FEATURES);
+ mCachedFeatureSet = longToBitset(legacyFeatures);
+ } else {
+ mCachedFeatureSet = BitSet.valueOf(extendedFeatures);
+ }
}
return mCachedFeatureSet;
}
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index dc58ee4154..bdb3309656 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -77,6 +77,7 @@ import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
import com.android.server.wifi.util.ActionListenerWrapper;
import com.android.server.wifi.util.WifiPermissionsUtil;
+import com.android.wifi.flags.FeatureFlags;
import com.android.wifi.resources.R;
import java.io.FileDescriptor;
@@ -151,6 +152,7 @@ public class WifiNetworkFactory extends NetworkFactory {
private final FrameworkFacade mFacade;
private final MultiInternetManager mMultiInternetManager;
private final NetworkCapabilities mCapabilitiesFilter;
+ private final FeatureFlags mFeatureFlags;
private RemoteCallbackList<INetworkRequestMatchCallback> mRegisteredCallbacks;
// Store all user approved access points for apps.
@VisibleForTesting
@@ -589,6 +591,7 @@ public class WifiNetworkFactory extends NetworkFactory {
// Create the scan settings.
mScanSettings = new WifiScanner.ScanSettings();
mScanSettings.type = WifiScanner.SCAN_TYPE_HIGH_ACCURACY;
+ mScanSettings.channels = new WifiScanner.ChannelSpec[0];
mScanSettings.band = WifiScanner.WIFI_BAND_ALL;
mScanSettings.reportEvents = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN;
mScanListener = new NetworkFactoryScanListener();
@@ -598,6 +601,7 @@ public class WifiNetworkFactory extends NetworkFactory {
mFacade = facade;
mMultiInternetManager = multiInternetManager;
mCapabilitiesFilter = nc;
+ mFeatureFlags = mWifiInjector.getDeviceConfigFacade().getFeatureFlags();
// register the data store for serializing/deserializing data.
configStore.registerStoreData(
@@ -1163,9 +1167,10 @@ public class WifiNetworkFactory extends NetworkFactory {
networkToConnect.BSSID = network.BSSID;
} else {
// If not pre-approved, find the best bssid matching the request.
- networkToConnect.BSSID =
- findBestBssidFromActiveMatchedScanResultsForNetwork(
- ScanResultMatchInfo.fromWifiConfiguration(networkToConnect));
+ ScanResult bestScanResult = findBestScanResultFromActiveMatchedScanResultsForNetwork(
+ ScanResultMatchInfo.fromWifiConfiguration(networkToConnect));
+ networkToConnect.BSSID = bestScanResult != null ? bestScanResult.BSSID : null;
+
}
networkToConnect.ephemeral = true;
// Mark it user private to avoid conflicting with any saved networks the user might have.
@@ -1210,7 +1215,8 @@ public class WifiNetworkFactory extends NetworkFactory {
private void handleConnectToNetworkUserSelection(WifiConfiguration network,
boolean didUserSeeUi) {
- Log.d(TAG, "User initiated connect to network: " + network.SSID);
+ Log.d(TAG, "User initiated connect to network: " + network.SSID + " (apChannel:"
+ + network.apChannel + ")");
// Cancel the ongoing scans after user selection.
cancelPeriodicScans();
@@ -1225,6 +1231,14 @@ public class WifiNetworkFactory extends NetworkFactory {
private void handleRejectUserSelection() {
Log.w(TAG, "User dismissed notification, cancelling " + mActiveSpecificNetworkRequest);
+ if (mFeatureFlags.localOnlyConnectionOptimization()
+ && mActiveSpecificNetworkRequestSpecifier != null
+ && mActiveSpecificNetworkRequest != null) {
+ sendConnectionFailureIfAllowed(mActiveSpecificNetworkRequest.getRequestorPackageName(),
+ mActiveSpecificNetworkRequest.getRequestorUid(),
+ mActiveSpecificNetworkRequestSpecifier,
+ WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_USER_REJECT);
+ }
teardownForActiveRequest();
mWifiMetrics.incrementNetworkRequestApiNumUserReject();
}
@@ -1323,7 +1337,8 @@ public class WifiNetworkFactory extends NetworkFactory {
}
sendConnectionFailureIfAllowed(mActiveSpecificNetworkRequest.getRequestorPackageName(),
mActiveSpecificNetworkRequest.getRequestorUid(),
- mActiveSpecificNetworkRequestSpecifier, failureCode);
+ mActiveSpecificNetworkRequestSpecifier,
+ internalConnectionEventToLocalOnlyFailureCode(failureCode));
teardownForActiveRequest();
}
@@ -1641,8 +1656,8 @@ public class WifiNetworkFactory extends NetworkFactory {
mUserApprovedScanRetryCount++;
// Create a worksource using the caller's UID.
WorkSource workSource = new WorkSource(mActiveSpecificNetworkRequest.getRequestorUid());
- mWifiScanner.startScan(
- mScanSettings, new HandlerExecutor(mHandler), mScanListener, workSource);
+ mWifiScanner.startScan(new WifiScanner.ScanSettings(mScanSettings),
+ new HandlerExecutor(mHandler), mScanListener, workSource);
}
private boolean doesScanResultMatchWifiNetworkSpecifier(
@@ -1780,13 +1795,13 @@ public class WifiNetworkFactory extends NetworkFactory {
return false;
}
- // Will return the best bssid to use for the current request's connection.
+ // Will return the best scan result to use for the current request's connection.
//
// Note: This will never return null, unless there is some internal error.
// For ex:
// i) The latest scan results were empty.
// ii) The latest scan result did not contain any BSSID for the SSID user chose.
- private @Nullable String findBestBssidFromActiveMatchedScanResultsForNetwork(
+ private @Nullable ScanResult findBestScanResultFromActiveMatchedScanResultsForNetwork(
@NonNull ScanResultMatchInfo scanResultMatchInfo) {
if (mActiveSpecificNetworkRequestSpecifier == null
|| mActiveMatchedScanResults == null) return null;
@@ -1805,7 +1820,7 @@ public class WifiNetworkFactory extends NetworkFactory {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Best bssid selected for the request " + selectedScanResult);
}
- return selectedScanResult.BSSID;
+ return selectedScanResult;
}
private boolean isAccessPointApprovedInInternalApprovalList(
@@ -2014,10 +2029,13 @@ public class WifiNetworkFactory extends NetworkFactory {
WifiConfiguration config = mActiveSpecificNetworkRequestSpecifier.wifiConfiguration;
config.SSID = "\""
+ mActiveSpecificNetworkRequestSpecifier.ssidPatternMatcher.getPath() + "\"";
- config.BSSID = findBestBssidFromActiveMatchedScanResultsForNetwork(
+ ScanResult bestScanResult = findBestScanResultFromActiveMatchedScanResultsForNetwork(
ScanResultMatchInfo.fromWifiConfiguration(config));
+ config.BSSID = bestScanResult != null ? bestScanResult.BSSID : null;
+ config.apChannel = bestScanResult != null ? bestScanResult.frequency : 0;
Log.v(TAG, "Bypassing user dialog for connection to SSID="
- + config.SSID + ", BSSID=" + config.BSSID);
+ + config.SSID + ", BSSID=" + config.BSSID + ", apChannel="
+ + config.apChannel);
handleConnectToNetworkUserSelection(config, false);
}
}
@@ -2121,7 +2139,8 @@ public class WifiNetworkFactory extends NetworkFactory {
}
private void sendConnectionFailureIfAllowed(String packageName,
- int uid, @NonNull WifiNetworkSpecifier networkSpecifier, int connectionEvent) {
+ int uid, @NonNull WifiNetworkSpecifier networkSpecifier,
+ @WifiManager.LocalOnlyConnectionStatusCode int failureReason) {
RemoteCallbackList<ILocalOnlyConnectionStatusListener> listenersTracker =
mLocalOnlyStatusListenerPerApp.get(packageName);
if (listenersTracker == null || listenersTracker.getRegisteredCallbackCount() == 0) {
@@ -2135,7 +2154,7 @@ public class WifiNetworkFactory extends NetworkFactory {
for (int i = 0; i < n; i++) {
try {
listenersTracker.getBroadcastItem(i).onConnectionStatus(networkSpecifier,
- internalConnectionEventToLocalOnlyFailureCode(connectionEvent));
+ failureReason);
} catch (RemoteException e) {
Log.e(TAG, "sendNetworkCallback: remote exception -- " + e);
}
diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java
index 12598a5d7b..7686e226f7 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java
@@ -1129,7 +1129,7 @@ public class WifiNetworkSelector {
String currentBssid = cmmState.wifiInfo.getBSSID();
WifiConfiguration currentNetwork =
mWifiConfigManager.getConfiguredNetwork(cmmState.wifiInfo.getNetworkId());
- if (currentNetwork != null) {
+ if (currentNetwork != null && currentBssid != null) {
wifiCandidates.setCurrent(currentNetwork.networkId, currentBssid);
// We always want the current network to be a candidate so that it can
// participate.
diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
index 60f4d948cb..9fa6113b1f 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
@@ -380,7 +380,7 @@ public class WifiNetworkSuggestionsManager {
config.allowAutojoin = isAutojoinEnabled;
if (config.enterpriseConfig
!= null && config.enterpriseConfig.isAuthenticationSimBased()
- && anonymousIdentity != null) {
+ && !TextUtils.isEmpty(anonymousIdentity)) {
config.enterpriseConfig.setAnonymousIdentity(anonymousIdentity);
}
config.getNetworkSelectionStatus().setConnectChoice(connectChoice);
@@ -1946,13 +1946,6 @@ public class WifiNetworkSuggestionsManager {
*/
public @NonNull List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
List<ScanResult> scanResults) {
- // Create a temporary look-up table.
- // As they are all single type configurations, they should have unique keys.
- Map<String, WifiConfiguration> wifiConfigMap = new HashMap<>();
- WifiConfigurationUtil.convertMultiTypeConfigsToLegacyConfigs(
- mWifiConfigManager.getConfiguredNetworks(), true)
- .forEach(c -> wifiConfigMap.put(c.getProfileKey(), c));
-
// Create a HashSet to avoid return multiple result for duplicate ScanResult.
Set<String> networkKeys = new HashSet<>();
List<WifiConfiguration> sharedWifiConfigs = new ArrayList<>();
@@ -1996,7 +1989,8 @@ public class WifiNetworkSuggestionsManager {
config, ewns.perAppInfo.packageName)) {
continue;
}
- WifiConfiguration wCmWifiConfig = wifiConfigMap.get(config.getProfileKey());
+ WifiConfiguration wCmWifiConfig = mWifiConfigManager
+ .getConfiguredNetwork(config.getProfileKey());
if (wCmWifiConfig == null) {
continue;
}
@@ -2747,6 +2741,11 @@ public class WifiNetworkSuggestionsManager {
}
for (ExtendedWifiNetworkSuggestion ewns : matchedSuggestionSet) {
ewns.anonymousIdentity = config.enterpriseConfig.getAnonymousIdentity();
+ if (TextUtils.isEmpty(ewns.anonymousIdentity)) {
+ // Update WifiConfig with App set AnonymousIdentity
+ updateWifiConfigInWcmIfPresent(ewns.createInternalWifiConfiguration(
+ mWifiCarrierInfoManager), ewns.perAppInfo.uid, ewns.perAppInfo.packageName);
+ }
}
saveToStore();
}
diff --git a/service/java/com/android/server/wifi/WifiScoreReport.java b/service/java/com/android/server/wifi/WifiScoreReport.java
index 107a6449bd..c3c4a0fc34 100644
--- a/service/java/com/android/server/wifi/WifiScoreReport.java
+++ b/service/java/com/android/server/wifi/WifiScoreReport.java
@@ -36,6 +36,7 @@ import android.os.Build;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
+import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.RequiresApi;
@@ -43,6 +44,7 @@ import androidx.annotation.RequiresApi;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.ActiveModeManager.ClientRole;
+import com.android.server.wifi.proto.WifiStatsLog;
import com.android.server.wifi.util.RssiUtil;
import com.android.server.wifi.util.StringUtil;
import com.android.wifi.resources.R;
@@ -85,6 +87,10 @@ public class WifiScoreReport {
private int mLegacyIntScore = ConnectedScore.WIFI_INITIAL_SCORE;
// Cache of the last usability status
private boolean mIsUsable = true;
+ private int mExternalScorerPredictionStatusForEvaluation =
+ WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_NONE;
+ private int mAospScorerPredictionStatusForEvaluation =
+ WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_NONE;
/**
* If true, indicates that the associated {@link ClientModeImpl} instance is lingering
@@ -145,6 +151,9 @@ public class WifiScoreReport {
+ " score=" + score);
return;
}
+ if (mIsExternalScorerDryRun) {
+ return;
+ }
long millis = mClock.getWallClockMillis();
if (SdkLevel.isAtLeastS()) {
mLegacyIntScore = score;
@@ -198,6 +207,9 @@ public class WifiScoreReport {
+ " interfaceName=" + mInterfaceName);
return;
}
+ if (mIsExternalScorerDryRun) {
+ return;
+ }
WifiLinkLayerStats stats = mWifiNative.getWifiLinkLayerStats(mInterfaceName);
// update mWifiInfo
@@ -257,6 +269,11 @@ public class WifiScoreReport {
+ " isUsable=" + isUsable);
return;
}
+ mExternalScorerPredictionStatusForEvaluation =
+ convertToPredictionStatusForEvaluation(isUsable);
+ if (mIsExternalScorerDryRun) {
+ return;
+ }
if (mNetworkAgent == null) {
return;
}
@@ -310,6 +327,9 @@ public class WifiScoreReport {
+ " currentSessionId=" + getCurrentSessionId());
return;
}
+ if (mIsExternalScorerDryRun) {
+ return;
+ }
if (!mAdaptiveConnectivityEnabledSettingObserver.get()
|| !mWifiSettingsStore.isWifiScoringEnabled()) {
if (mVerboseLoggingEnabled) {
@@ -330,6 +350,9 @@ public class WifiScoreReport {
+ " mSessionIdNoReset=" + mSessionIdNoReset);
return;
}
+ if (mIsExternalScorerDryRun) {
+ return;
+ }
if (!mAdaptiveConnectivityEnabledSettingObserver.get()
|| !mWifiSettingsStore.isWifiScoringEnabled()) {
if (mVerboseLoggingEnabled) {
@@ -379,6 +402,7 @@ public class WifiScoreReport {
return;
}
if (mWifiConnectedNetworkScorerHolder != null
+ && !mIsExternalScorerDryRun
&& mContext.getResources().getBoolean(
R.bool.config_wifiMinConfirmationDurationSendNetworkScoreEnabled)
/// Turn off hysteresis/dampening for shell commands.
@@ -547,6 +571,7 @@ public class WifiScoreReport {
@Nullable
private WifiConnectedNetworkScorerHolder mWifiConnectedNetworkScorerHolder;
+ private boolean mIsExternalScorerDryRun;
private final AdaptiveConnectivityEnabledSettingObserver
mAdaptiveConnectivityEnabledSettingObserver;
@@ -600,6 +625,7 @@ public class WifiScoreReport {
*/
public void reset() {
mSessionNumber++;
+ clearScorerPredictionStatusForEvaluation();
mLegacyIntScore = isPrimary() ? ConnectedScore.WIFI_INITIAL_SCORE
: ConnectedScore.WIFI_SECONDARY_INITIAL_SCORE;
mIsUsable = true;
@@ -634,11 +660,6 @@ public class WifiScoreReport {
* Called periodically (POLL_RSSI_INTERVAL_MSECS) about every 3 seconds.
*/
public void calculateAndReportScore() {
- // Bypass AOSP scorer if Wifi connected network scorer is set
- if (mWifiConnectedNetworkScorerHolder != null) {
- return;
- }
-
if (mWifiInfo.getRssi() == mWifiInfo.INVALID_RSSI) {
Log.d(TAG, "Not reporting score because RSSI is invalid");
return;
@@ -696,6 +717,13 @@ public class WifiScoreReport {
score = 0;
}
+ mAospScorerPredictionStatusForEvaluation = convertToPredictionStatusForEvaluation(
+ score >= transitionScore);
+ // Bypass AOSP scorer if Wifi connected network scorer is set
+ if (mWifiConnectedNetworkScorerHolder != null && !mIsExternalScorerDryRun) {
+ return;
+ }
+
if (score < mWifiGlobals.getWifiLowConnectedScoreThresholdToTriggerScanForMbb()
&& enoughTimePassedSinceLastLowConnectedScoreScan()
&& mActiveModeWarden.canRequestSecondaryTransientClientModeManager()) {
@@ -988,13 +1016,18 @@ public class WifiScoreReport {
return false;
}
mWifiConnectedNetworkScorerHolder = scorerHolder;
- mWifiGlobals.setUsingExternalScorer(true);
+ mDeviceConfigFacade.setDryRunScorerPkgNameChangedListener(dryRunPkgName -> {
+ mIsExternalScorerDryRun =
+ isExternalScorerDryRun(dryRunPkgName, callerUid);
+ mWifiGlobals.setUsingExternalScorer(!mIsExternalScorerDryRun);
+ });
+ mIsExternalScorerDryRun =
+ isExternalScorerDryRun(mDeviceConfigFacade.getDryRunScorerPkgName(), callerUid);
+ mWifiGlobals.setUsingExternalScorer(!mIsExternalScorerDryRun);
// Register to receive updates from external scorer.
mExternalScoreUpdateObserverProxy.registerCallback(mScoreUpdateObserverCallback);
- // Disable AOSP scorer
- mVelocityBasedConnectedScore = null;
mWifiMetrics.setIsExternalWifiScorerOn(true, callerUid);
// If there is already a connection, start a new session
final int netId = getCurrentNetId();
@@ -1004,6 +1037,18 @@ public class WifiScoreReport {
return true;
}
+ private boolean isExternalScorerDryRun(String dryRunPkgName, int uid) {
+ Log.d(TAG, "isExternalScorerDryRun(" + dryRunPkgName + ", " + uid + ")");
+ String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
+ for (String packageName : packageNames) {
+ if (!TextUtils.isEmpty(packageName)
+ && packageName.equalsIgnoreCase(dryRunPkgName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Clear an existing scorer for Wi-Fi connected network score handling.
*/
@@ -1019,7 +1064,7 @@ public class WifiScoreReport {
* Notify the connected network scorer of the user accepting a network switch.
*/
public void onNetworkSwitchAccepted(int targetNetworkId, String targetBssid) {
- if (mWifiConnectedNetworkScorerHolder == null) {
+ if (mWifiConnectedNetworkScorerHolder == null || mIsExternalScorerDryRun) {
return;
}
mWifiConnectedNetworkScorerHolder.onNetworkSwitchAccepted(
@@ -1030,7 +1075,7 @@ public class WifiScoreReport {
* Notify the connected network scorer of the user rejecting a network switch.
*/
public void onNetworkSwitchRejected(int targetNetworkId, String targetBssid) {
- if (mWifiConnectedNetworkScorerHolder == null) {
+ if (mWifiConnectedNetworkScorerHolder == null || mIsExternalScorerDryRun) {
return;
}
mWifiConnectedNetworkScorerHolder.onNetworkSwitchRejected(
@@ -1070,6 +1115,7 @@ public class WifiScoreReport {
* @param netId identifies the current android.net.Network
*/
public void startConnectedNetworkScorer(int netId, boolean isUserSelected) {
+ Log.d(TAG, "startConnectedNetworkScorer(" + netId + ", " + isUserSelected + ")");
mIsUserSelected = isUserSelected;
final int sessionId = getCurrentSessionId();
if (mWifiConnectedNetworkScorerHolder == null
@@ -1148,12 +1194,12 @@ public class WifiScoreReport {
shouldForceKeepConnected
? NetworkScore.KEEP_CONNECTED_FOR_HANDOVER
: NetworkScore.KEEP_CONNECTED_NONE;
- boolean exiting = SdkLevel.isAtLeastS() && mWifiConnectedNetworkScorerHolder != null
+ boolean exiting = (SdkLevel.isAtLeastS() && mWifiConnectedNetworkScorerHolder != null)
? !mIsUsable : mLegacyIntScore < ConnectedScore.WIFI_TRANSITION_SCORE;
return new NetworkScore.Builder()
.setLegacyInt(mShouldReduceNetworkScore ? LINGERING_SCORE : mLegacyIntScore)
.setTransportPrimary(mCurrentRole == ActiveModeManager.ROLE_CLIENT_PRIMARY)
- .setExiting(exiting)
+ .setExiting(exiting | mShouldReduceNetworkScore)
.setKeepConnectedReason(keepConnectedReason);
}
@@ -1178,8 +1224,8 @@ public class WifiScoreReport {
private void revertToDefaultConnectedScorer() {
Log.d(TAG, "Using VelocityBasedConnectedScore");
- mVelocityBasedConnectedScore = new VelocityBasedConnectedScore(mScoringParams, mClock);
mWifiConnectedNetworkScorerHolder = null;
+ mDeviceConfigFacade.setDryRunScorerPkgNameChangedListener(null);
mWifiGlobals.setUsingExternalScorer(false);
mExternalScoreUpdateObserverProxy.unregisterCallback(mScoreUpdateObserverCallback);
mWifiMetrics.setIsExternalWifiScorerOn(false, Process.WIFI_UID);
@@ -1201,6 +1247,43 @@ public class WifiScoreReport {
}
}
+ private int convertToPredictionStatusForEvaluation(boolean isUsable) {
+ return isUsable
+ ? WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE
+ : WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_UNUSABLE;
+ }
+
+ /**
+ * Get whether an external scorer is registered.
+ */
+ public boolean isExternalScorerRegistered() {
+ return mWifiConnectedNetworkScorerHolder != null;
+ }
+
+ /**
+ * Get wifi predicted state for metrics
+ */
+ public int getExternalScorerPredictionStatusForEvaluation() {
+ return mExternalScorerPredictionStatusForEvaluation;
+ }
+
+ /**
+ * Get wifi predicted state for metrics
+ */
+ public int getAospScorerPredictionStatusForEvaluation() {
+ return mAospScorerPredictionStatusForEvaluation;
+ }
+
+ /**
+ * Clear the predicted states for metrics
+ */
+ public void clearScorerPredictionStatusForEvaluation() {
+ mExternalScorerPredictionStatusForEvaluation =
+ WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_NONE;
+ mAospScorerPredictionStatusForEvaluation =
+ WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_NONE;
+ }
+
/** Called when the owner {@link ConcreteClientModeManager}'s role changes. */
public void onRoleChanged(@Nullable ClientRole role) {
mCurrentRole = role;
@@ -1208,4 +1291,13 @@ public class WifiScoreReport {
if (mVelocityBasedConnectedScore != null) mVelocityBasedConnectedScore.onRoleChanged(role);
sendNetworkScore();
}
+
+ /**
+ * Get whether we are in the lingering state or not.
+ */
+ public boolean getLingering() {
+ return (SdkLevel.isAtLeastS() && mWifiConnectedNetworkScorerHolder != null
+ && !mIsExternalScorerDryRun)
+ ? !mIsUsable : mLegacyIntScore < ConnectedScore.WIFI_TRANSITION_SCORE;
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 3a45356a34..4347040fca 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -28,8 +28,10 @@ import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERI
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
import static android.net.wifi.WifiManager.NOT_OVERRIDE_EXISTING_NETWORKS_ON_RESTORE;
import static android.net.wifi.WifiManager.PnoScanResultsCallback.REGISTER_PNO_CALLBACK_PNO_NOT_SUPPORTED;
+import static android.net.wifi.WifiManager.ROAMING_MODE_AGGRESSIVE;
import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL;
import static android.net.wifi.WifiManager.SAP_START_FAILURE_NO_CHANNEL;
+import static android.net.wifi.WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
import static android.net.wifi.WifiManager.VERBOSE_LOGGING_LEVEL_WIFI_AWARE_ENABLED_ONLY;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
@@ -206,6 +208,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.modules.utils.HandlerExecutor;
import com.android.modules.utils.ParceledListSlice;
+import com.android.modules.utils.StringParceledListSlice;
import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.Inet4AddressUtils;
import com.android.server.wifi.coex.CoexManager;
@@ -335,7 +338,7 @@ public class WifiServiceImpl extends BaseWifiService {
private static final String CERT_INSTALLER_PKG = "com.android.certinstaller";
private final WifiSettingsConfigStore mSettingsConfigStore;
- private final WifiResourceCache mWifiResourceCache;
+ private final WifiResourceCache mResourceCache;
/**
* Callback for use with LocalOnlyHotspot to unregister requesting applications upon death.
@@ -516,7 +519,7 @@ public class WifiServiceImpl extends BaseWifiService {
public WifiServiceImpl(WifiContext context, WifiInjector wifiInjector) {
mContext = context;
- mWifiResourceCache = mContext.getResourceCache();
+ mResourceCache = mContext.getResourceCache();
mWifiInjector = wifiInjector;
mClock = wifiInjector.getClock();
@@ -693,21 +696,6 @@ public class WifiServiceImpl extends BaseWifiService {
null,
new Handler(mWifiHandlerThread.getLooper()));
- mContext.registerReceiver(
- new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "onReceive: MODE_CHANGED_ACTION: intent=" + intent);
- }
- updateLocationMode();
- }
- },
- new IntentFilter(LocationManager.MODE_CHANGED_ACTION),
- null,
- new Handler(mWifiHandlerThread.getLooper()));
- updateLocationMode();
-
if (SdkLevel.isAtLeastT()) {
mContext.registerReceiver(
new BroadcastReceiver() {
@@ -886,6 +874,20 @@ public class WifiServiceImpl extends BaseWifiService {
mWifiInjector.getWifiDeviceStateChangeManager().handleBootCompleted();
setPulledAtomCallbacks();
mTwtManager.registerWifiNativeTwtEvents();
+ mContext.registerReceiver(
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "onReceive: MODE_CHANGED_ACTION: intent=" + intent);
+ }
+ updateLocationMode();
+ }
+ },
+ new IntentFilter(LocationManager.MODE_CHANGED_ACTION),
+ null,
+ new Handler(mWifiHandlerThread.getLooper()));
+ updateLocationMode();
}, TAG + "#handleBootCompleted");
}
@@ -1195,6 +1197,54 @@ public class WifiServiceImpl extends BaseWifiService {
}
/**
+ * Validates if the calling user is valid.
+ *
+ * @throws a {@link SecurityException} if the calling user is not valid.
+ */
+ private void enforceValidCallingUser() {
+ if (!isValidCallingUser()) {
+ throw new SecurityException(
+ "Calling user " + Binder.getCallingUserHandle() + " is not the SYSTEM user, "
+ + "the current user, or a profile of the current user, "
+ + "thus not allowed to make changes to WIFI.");
+ }
+ }
+
+ /**
+ * Checks if the calling user is valid on Automotive devices..
+ *
+ * @return true if any of the following conditions are true:
+ * <li>The device is not an Automotive device.
+ * <li>the calling user is the system user.
+ * <li>the calling user is the current user.
+ * <li>the calling user belongs to the same profile group as the current user.
+ */
+ private boolean isValidCallingUser() {
+ // TODO(b/360488316): Ideally UserManager#isVisibleBackgroundUsersEnabled() should be used
+ // but it is a hidden API. We rely on FEATURE_AUTOMOTIVE only, because we cannot access
+ // the RRO config for R.bool.config_multiuserVisibleBackgroundUsers.
+ if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+ return true;
+ }
+ UserHandle callingUser = Binder.getCallingUserHandle();
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ UserHandle currentUser =
+ UserHandle.of(mWifiInjector.getWifiPermissionsWrapper().getCurrentUser());
+ if (UserHandle.SYSTEM.equals(callingUser)
+ || callingUser.equals(currentUser)
+ || mUserManager.isSameProfileGroup(callingUser, currentUser)) {
+ return true;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+
+ return false;
+ }
+
+ /**
* Helper method to check if the app is allowed to access public API's deprecated in
* {@link Build.VERSION_CODES#Q}.
* Note: Invoke mAppOps.checkPackage(uid, packageName) before to ensure correct package name.
@@ -1263,7 +1313,7 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public synchronized boolean setWifiEnabled(String packageName, boolean enable) {
- if (enforceChangePermission(packageName) != MODE_ALLOWED) {
+ if (!isValidCallingUser() || enforceChangePermission(packageName) != MODE_ALLOWED) {
return false;
}
int callingUid = Binder.getCallingUid();
@@ -1445,6 +1495,9 @@ public class WifiServiceImpl extends BaseWifiService {
if (!SdkLevel.isAtLeastS()) {
throw new UnsupportedOperationException();
}
+ if (callback == null) {
+ throw new IllegalArgumentException("Callback is null");
+ }
enforceAccessPermission();
if (mVerboseLoggingEnabled) {
mLog.info("registerSubsystemRestartCallback uid=%").c(Binder.getCallingUid()).flush();
@@ -1463,6 +1516,9 @@ public class WifiServiceImpl extends BaseWifiService {
if (!SdkLevel.isAtLeastS()) {
throw new UnsupportedOperationException();
}
+ if (callback == null) {
+ throw new IllegalArgumentException("Callback is null");
+ }
enforceAccessPermission();
if (mVerboseLoggingEnabled) {
mLog.info("unregisterSubsystemRestartCallback uid=%").c(Binder.getCallingUid()).flush();
@@ -1601,7 +1657,7 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public boolean isDefaultCoexAlgorithmEnabled() {
- return mContext.getResources().getBoolean(R.bool.config_wifiDefaultCoexAlgorithmEnabled);
+ return mResourceCache.getBoolean(R.bool.config_wifiDefaultCoexAlgorithmEnabled);
}
/**
@@ -1622,7 +1678,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (unsafeChannels == null) {
throw new IllegalArgumentException("unsafeChannels cannot be null");
}
- if (mContext.getResources().getBoolean(R.bool.config_wifiDefaultCoexAlgorithmEnabled)) {
+ if (mResourceCache.getBoolean(R.bool.config_wifiDefaultCoexAlgorithmEnabled)) {
Log.e(TAG, "setCoexUnsafeChannels called but default coex algorithm is enabled");
return;
}
@@ -1749,6 +1805,8 @@ public class WifiServiceImpl extends BaseWifiService {
@Override
public boolean startTetheredHotspot(@Nullable SoftApConfiguration softApConfig,
@NonNull String packageName) {
+ enforceValidCallingUser();
+
// NETWORK_STACK is a signature only permission.
enforceNetworkStackPermission();
int callingUid = Binder.getCallingUid();
@@ -1784,6 +1842,7 @@ public class WifiServiceImpl extends BaseWifiService {
throw new IllegalArgumentException("callback must not be null");
}
+ enforceValidCallingUser();
// NETWORK_STACK is a signature only permission.
enforceNetworkStackPermission();
int callingUid = Binder.getCallingUid();
@@ -1890,6 +1949,8 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public boolean stopSoftAp() {
+ enforceValidCallingUser();
+
// NETWORK_STACK is a signature only permission.
enforceNetworkStackPermission();
@@ -1989,7 +2050,6 @@ public class WifiServiceImpl extends BaseWifiService {
+ mCountryCode.getCurrentDriverCountryCode());
}
// Store Soft AP channels for reference after a reboot before the driver is up.
- Resources res = mContext.getResources();
mSettingsConfigStore.put(WifiSettingsConfigStore.WIFI_SOFT_AP_COUNTRY_CODE,
countryCode);
List<Integer> freqs = new ArrayList<>();
@@ -2000,7 +2060,7 @@ public class WifiServiceImpl extends BaseWifiService {
continue;
}
List<Integer> freqsForBand = ApConfigUtil.getAvailableChannelFreqsForBand(
- band, mWifiNative, res, true);
+ band, mWifiNative, mResourceCache, true);
if (freqsForBand != null) {
freqs.addAll(freqsForBand);
int[] channel = new int[freqsForBand.size()];
@@ -2293,7 +2353,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (carrierConfig == null) return;
int carrierMaxClient = carrierConfig.getInt(
CarrierConfigManager.Wifi.KEY_HOTSPOT_MAX_CLIENT_COUNT);
- int finalSupportedClientNumber = mContext.getResources().getInteger(
+ int finalSupportedClientNumber = mResourceCache.getInteger(
R.integer.config_wifiHardwareSoftapMaxClientCount);
if (carrierMaxClient > 0) {
finalSupportedClientNumber = Math.min(finalSupportedClientNumber,
@@ -2851,13 +2911,14 @@ public class WifiServiceImpl extends BaseWifiService {
false, TAG + " registerLocalOnlyHotspotSoftApCallback");
if (mVerboseLoggingEnabled) {
- mLog.info("registerSoftApCallback uid=%").c(Binder.getCallingUid()).flush();
+ mLog.info("registerLocalOnlyHotspotSoftApCallback uid=%")
+ .c(Binder.getCallingUid()).flush();
}
// post operation to handler thread
mWifiThreadRunner.post(() -> {
if (!mLohsSoftApTracker.registerSoftApCallback(callback)) {
- Log.e(TAG, "registerSoftApCallback: Failed to add callback");
+ Log.e(TAG, "registerLocalOnlyHotspotSoftApCallback: Failed to add callback");
return;
}
}, TAG + "#registerLocalOnlyHotspotSoftApCallback");
@@ -2877,7 +2938,8 @@ public class WifiServiceImpl extends BaseWifiService {
false, TAG + " registerLocalOnlyHotspotSoftApCallback");
if (mVerboseLoggingEnabled) {
- mLog.info("unregisterSoftApCallback uid=%").c(Binder.getCallingUid()).flush();
+ mLog.info("unregisterLocalOnlyHotspotSoftApCallback uid=%")
+ .c(Binder.getCallingUid()).flush();
}
// post operation to handler thread
@@ -3535,7 +3597,7 @@ public class WifiServiceImpl extends BaseWifiService {
// API was called to override the overlay value.
return mSettingsConfigStore.get(SHOW_DIALOG_WHEN_THIRD_PARTY_APPS_ENABLE_WIFI);
} else {
- return mContext.getResources().getBoolean(
+ return mResourceCache.getBoolean(
R.bool.config_showConfirmationDialogForThirdPartyAppsEnablingWifi);
}
}
@@ -3631,20 +3693,21 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public Map<String, Map<Integer, List<ScanResult>>>
- getAllMatchingPasspointProfilesForScanResults(List<ScanResult> scanResults) {
+ getAllMatchingPasspointProfilesForScanResults(
+ ParceledListSlice<ScanResult> scanResults) {
if (!isSettingsOrSuw(Binder.getCallingPid(), Binder.getCallingUid())) {
throw new SecurityException(TAG + ": Permission denied");
}
if (mVerboseLoggingEnabled) {
mLog.info("getMatchingPasspointConfigurations uid=%").c(Binder.getCallingUid()).flush();
}
- if (!ScanResultUtil.validateScanResultList(scanResults)) {
+ if (scanResults == null || !ScanResultUtil.validateScanResultList(scanResults.getList())) {
Log.e(TAG, "Attempt to retrieve passpoint with invalid scanResult List");
return Collections.emptyMap();
}
return mWifiThreadRunner.call(
- () -> mPasspointManager.getAllMatchingPasspointProfilesForScanResults(scanResults),
- Collections.emptyMap(),
+ () -> mPasspointManager.getAllMatchingPasspointProfilesForScanResults(
+ scanResults.getList()), Collections.emptyMap(),
TAG + "#getAllMatchingPasspointProfilesForScanResults");
}
@@ -3652,7 +3715,8 @@ public class WifiServiceImpl extends BaseWifiService {
* See {@link WifiManager#setSsidsAllowlist(Set)}
*/
@Override
- public void setSsidsAllowlist(@NonNull String packageName, @NonNull List<WifiSsid> ssids) {
+ public void setSsidsAllowlist(@NonNull String packageName,
+ @NonNull ParceledListSlice<WifiSsid> ssids) {
int uid = Binder.getCallingUid();
mWifiPermissionsUtil.checkPackage(uid, packageName);
boolean hasPermission = mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
@@ -3667,15 +3731,16 @@ public class WifiServiceImpl extends BaseWifiService {
if (mVerboseLoggingEnabled) {
mLog.info("setSsidsAllowlist uid=%").c(uid).flush();
}
- mWifiThreadRunner.post(() ->
- mWifiBlocklistMonitor.setSsidsAllowlist(ssids), TAG + "#setSsidsAllowlist");
+ List<WifiSsid> ssidList = ssids == null ? null : ssids.getList();
+ mWifiThreadRunner.post(() -> mWifiBlocklistMonitor.setSsidsAllowlist(ssidList),
+ TAG + "#setSsidsAllowlist");
}
/**
* See {@link WifiManager#getSsidsAllowlist()}
*/
@Override
- public @NonNull List<WifiSsid> getSsidsAllowlist(String packageName) {
+ public @NonNull ParceledListSlice<WifiSsid> getSsidsAllowlist(String packageName) {
int uid = Binder.getCallingUid();
mWifiPermissionsUtil.checkPackage(uid, packageName);
boolean hasPermission = mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)
@@ -3690,9 +3755,9 @@ public class WifiServiceImpl extends BaseWifiService {
if (mVerboseLoggingEnabled) {
mLog.info("getSsidsAllowlist uid=%").c(uid).flush();
}
- return mWifiThreadRunner.call(
+ return new ParceledListSlice<>(mWifiThreadRunner.call(
() -> mWifiBlocklistMonitor.getSsidsAllowlist(), Collections.EMPTY_LIST,
- TAG + "#getSsidsAllowlist");
+ TAG + "#getSsidsAllowlist"));
}
/**
@@ -3703,21 +3768,20 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public Map<OsuProvider, List<ScanResult>> getMatchingOsuProviders(
- List<ScanResult> scanResults) {
+ ParceledListSlice<ScanResult> scanResults) {
if (!isSettingsOrSuw(Binder.getCallingPid(), Binder.getCallingUid())) {
throw new SecurityException(TAG + ": Permission denied");
}
if (mVerboseLoggingEnabled) {
mLog.info("getMatchingOsuProviders uid=%").c(Binder.getCallingUid()).flush();
}
-
- if (!ScanResultUtil.validateScanResultList(scanResults)) {
+ if (scanResults == null || !ScanResultUtil.validateScanResultList(scanResults.getList())) {
Log.w(TAG, "Attempt to retrieve OsuProviders with invalid scanResult List");
return Collections.emptyMap();
}
return mWifiThreadRunner.call(
- () -> mPasspointManager.getMatchingOsuProviders(scanResults), Collections.emptyMap(),
- TAG + "#getMatchingOsuProviders");
+ () -> mPasspointManager.getMatchingOsuProviders(scanResults.getList()),
+ Collections.emptyMap(), TAG + "#getMatchingOsuProviders");
}
/**
@@ -3728,7 +3792,7 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public Map<OsuProvider, PasspointConfiguration> getMatchingPasspointConfigsForOsuProviders(
- List<OsuProvider> osuProviders) {
+ ParceledListSlice<OsuProvider> osuProviders) {
if (!isSettingsOrSuw(Binder.getCallingPid(), Binder.getCallingUid())) {
throw new SecurityException(TAG + ": Permission denied");
}
@@ -3736,13 +3800,14 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("getMatchingPasspointConfigsForOsuProviders uid=%").c(
Binder.getCallingUid()).flush();
}
- if (osuProviders == null) {
+ if (osuProviders == null || osuProviders.getList() == null) {
Log.e(TAG, "Attempt to retrieve Passpoint configuration with null osuProviders");
return new HashMap<>();
}
return mWifiThreadRunner.call(
- () -> mPasspointManager.getMatchingPasspointConfigsForOsuProviders(osuProviders),
- Collections.emptyMap(), TAG + "#getMatchingPasspointConfigsForOsuProviders");
+ () -> mPasspointManager.getMatchingPasspointConfigsForOsuProviders(
+ osuProviders.getList()), Collections.emptyMap(),
+ TAG + "#getMatchingPasspointConfigsForOsuProviders");
}
/**
@@ -3755,7 +3820,8 @@ public class WifiServiceImpl extends BaseWifiService {
* @return List of {@link WifiConfiguration} converted from {@link PasspointProvider}
*/
@Override
- public List<WifiConfiguration> getWifiConfigsForPasspointProfiles(List<String> fqdnList) {
+ public ParceledListSlice<WifiConfiguration> getWifiConfigsForPasspointProfiles(
+ StringParceledListSlice fqdnList) {
if (!isSettingsOrSuw(Binder.getCallingPid(), Binder.getCallingUid())) {
throw new SecurityException(TAG + ": Permission denied");
}
@@ -3763,13 +3829,13 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("getWifiConfigsForPasspointProfiles uid=%").c(
Binder.getCallingUid()).flush();
}
- if (fqdnList == null) {
+ if (fqdnList == null || fqdnList.getList() == null || fqdnList.getList().isEmpty()) {
Log.e(TAG, "Attempt to retrieve WifiConfiguration with null fqdn List");
- return new ArrayList<>();
+ return new ParceledListSlice<>(Collections.emptyList());
}
- return mWifiThreadRunner.call(
- () -> mPasspointManager.getWifiConfigsForPasspointProfiles(fqdnList),
- Collections.emptyList(), TAG + "#getWifiConfigsForPasspointProfiles");
+ return new ParceledListSlice<>(mWifiThreadRunner.call(
+ () -> mPasspointManager.getWifiConfigsForPasspointProfiles(fqdnList.getList()),
+ Collections.emptyList(), TAG + "#getWifiConfigsForPasspointProfiles"));
}
/**
@@ -3783,8 +3849,9 @@ public class WifiServiceImpl extends BaseWifiService {
* @return a list of {@link WifiConfiguration} from matched {@link WifiNetworkSuggestion}.
*/
@Override
- public List<WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
- List<ScanResult> scanResults) {
+ public ParceledListSlice<WifiConfiguration>
+ getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
+ ParceledListSlice<ScanResult> scanResults) {
if (!isSettingsOrSuw(Binder.getCallingPid(), Binder.getCallingUid())) {
throw new SecurityException(TAG + ": Permission denied");
}
@@ -3792,15 +3859,16 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("getWifiConfigsForMatchedNetworkSuggestions uid=%").c(
Binder.getCallingUid()).flush();
}
- if (!ScanResultUtil.validateScanResultList(scanResults)) {
+ if (scanResults == null || !ScanResultUtil.validateScanResultList(scanResults.getList())) {
Log.w(TAG, "Attempt to retrieve WifiConfiguration with invalid scanResult List");
- return new ArrayList<>();
+ return new ParceledListSlice<>(Collections.emptyList());
}
- return mWifiThreadRunner.call(
+ return new ParceledListSlice<>(WifiConfigurationUtil.convertMultiTypeConfigsToLegacyConfigs(
+ mWifiThreadRunner.call(
() -> mWifiNetworkSuggestionsManager
- .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(scanResults),
- Collections.emptyList(),
- TAG + "#getWifiConfigForMatchedNetworkSuggestionsSharedWithUser");
+ .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
+ scanResults.getList()), Collections.emptyList(),
+ TAG + "#getWifiConfigForMatchedNetworkSuggestionsSharedWithUser"), true));
}
/**
@@ -3891,6 +3959,11 @@ public class WifiServiceImpl extends BaseWifiService {
boolean isCamera = mWifiPermissionsUtil.checkCameraPermission(callingUid);
boolean isSystem = mWifiPermissionsUtil.isSystem(packageName, callingUid);
boolean isPrivileged = isPrivileged(callingPid, callingUid);
+ if (!isPrivileged && !isSystem && !isAdmin && config.getBssidAllowlistInternal() != null) {
+ mLog.info("addOrUpdateNetwork with allow bssid list is not allowed for uid=%")
+ .c(callingUid).flush();
+ return -1;
+ }
if (!isTargetSdkLessThanQOrPrivileged(packageName, callingPid, callingUid)) {
mLog.info("addOrUpdateNetwork not allowed for uid=%").c(callingUid).flush();
@@ -4370,7 +4443,7 @@ public class WifiServiceImpl extends BaseWifiService {
@Override
public void getBssidBlocklist(@NonNull ParceledListSlice<WifiSsid> ssids,
@NonNull IMacAddressListListener listener) {
- if (ssids == null) {
+ if (ssids == null || ssids.getList() == null) {
throw new IllegalArgumentException("Null ssids");
}
if (listener == null) {
@@ -4663,24 +4736,29 @@ public class WifiServiceImpl extends BaseWifiService {
@Override
@NonNull
public Map<WifiNetworkSuggestion, List<ScanResult>> getMatchingScanResults(
- @NonNull List<WifiNetworkSuggestion> networkSuggestions,
- @Nullable List<ScanResult> scanResults,
+ @NonNull ParceledListSlice<WifiNetworkSuggestion> networkSuggestions,
+ @Nullable ParceledListSlice<ScanResult> scanResults,
String callingPackage, String callingFeatureId) {
enforceAccessPermission();
int uid = Binder.getCallingUid();
long ident = Binder.clearCallingIdentity();
+ if (networkSuggestions == null || networkSuggestions.getList() == null) {
+ throw new IllegalArgumentException("networkSuggestions must not be null.");
+ }
try {
mWifiPermissionsUtil.enforceCanAccessScanResults(callingPackage, callingFeatureId,
uid, null);
return mWifiThreadRunner.call(
() -> {
- if (!ScanResultUtil.validateScanResultList(scanResults)) {
+ if (scanResults == null
+ || !ScanResultUtil.validateScanResultList(scanResults.getList())) {
return mWifiNetworkSuggestionsManager.getMatchingScanResults(
- networkSuggestions, mScanRequestProxy.getScanResults());
+ networkSuggestions.getList(),
+ mScanRequestProxy.getScanResults());
} else {
return mWifiNetworkSuggestionsManager.getMatchingScanResults(
- networkSuggestions, scanResults);
+ networkSuggestions.getList(), scanResults.getList());
}
},
Collections.emptyMap(), TAG + "#getMatchingScanResults");
@@ -4788,7 +4866,8 @@ public class WifiServiceImpl extends BaseWifiService {
* @return A list of {@link PasspointConfiguration}.
*/
@Override
- public List<PasspointConfiguration> getPasspointConfigurations(String packageName) {
+ public ParceledListSlice<PasspointConfiguration> getPasspointConfigurations(
+ String packageName) {
final int uid = Binder.getCallingUid();
mWifiPermissionsUtil.checkPackage(uid, packageName);
boolean privileged = false;
@@ -4800,9 +4879,9 @@ public class WifiServiceImpl extends BaseWifiService {
mLog.info("getPasspointConfigurations uid=%").c(Binder.getCallingUid()).flush();
}
final boolean privilegedFinal = privileged;
- return mWifiThreadRunner.call(
+ return new ParceledListSlice<>(mWifiThreadRunner.call(
() -> mPasspointManager.getProviderConfigs(uid, privilegedFinal),
- Collections.emptyList(), TAG + "#getPasspointConfigurations");
+ Collections.emptyList(), TAG + "#getPasspointConfigurations"));
}
/**
@@ -5022,7 +5101,7 @@ public class WifiServiceImpl extends BaseWifiService {
}
private boolean is24GhzBandSupportedInternal() {
- if (mContext.getResources().getBoolean(R.bool.config_wifi24ghzSupport)) {
+ if (mResourceCache.getBoolean(R.bool.config_wifi24ghzSupport)) {
return true;
}
return mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_24_GHZ);
@@ -5039,7 +5118,7 @@ public class WifiServiceImpl extends BaseWifiService {
}
private boolean is5GhzBandSupportedInternal() {
- if (mContext.getResources().getBoolean(R.bool.config_wifi5ghzSupport)) {
+ if (mResourceCache.getBoolean(R.bool.config_wifi5ghzSupport)) {
return true;
}
return mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_5_GHZ);
@@ -5055,7 +5134,7 @@ public class WifiServiceImpl extends BaseWifiService {
}
private boolean is6GhzBandSupportedInternal() {
- if (mContext.getResources().getBoolean(R.bool.config_wifi6ghzSupport)) {
+ if (mResourceCache.getBoolean(R.bool.config_wifi6ghzSupport)) {
return true;
}
return mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_6_GHZ);
@@ -5075,7 +5154,7 @@ public class WifiServiceImpl extends BaseWifiService {
}
private boolean is60GhzBandSupportedInternal() {
- if (mContext.getResources().getBoolean(R.bool.config_wifi60ghzSupport)) {
+ if (mResourceCache.getBoolean(R.bool.config_wifi60ghzSupport)) {
return true;
}
return mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_60_GHZ);
@@ -5608,7 +5687,7 @@ public class WifiServiceImpl extends BaseWifiService {
mWifiInjector.getWifiVoipDetector().dump(fd, pw, args);
}
pw.println();
- mWifiResourceCache.dump(pw);
+ mResourceCache.dump(pw);
}
}, TAG + "#dump");
}
@@ -5743,7 +5822,7 @@ public class WifiServiceImpl extends BaseWifiService {
}
private void updateVerboseLoggingEnabled() {
- final int verboseAlwaysOnLevel = mContext.getResources().getInteger(
+ final int verboseAlwaysOnLevel = mResourceCache.getInteger(
R.integer.config_wifiVerboseLoggingAlwaysOnLevel);
mVerboseLoggingEnabled = WifiManager.VERBOSE_LOGGING_LEVEL_ENABLED == mVerboseLoggingLevel
|| WifiManager.VERBOSE_LOGGING_LEVEL_ENABLED_SHOW_KEY == mVerboseLoggingLevel
@@ -6231,7 +6310,7 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public int addNetworkSuggestions(
- List<WifiNetworkSuggestion> networkSuggestions, String callingPackageName,
+ ParceledListSlice<WifiNetworkSuggestion> networkSuggestions, String callingPackageName,
String callingFeatureId) {
if (enforceChangePermission(callingPackageName) != MODE_ALLOWED) {
return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED;
@@ -6264,12 +6343,15 @@ public class WifiServiceImpl extends BaseWifiService {
if (mVerboseLoggingEnabled) {
mLog.info("addNetworkSuggestions uid=%").c(callingUid).flush();
}
+ if (networkSuggestions == null) {
+ return STATUS_NETWORK_SUGGESTIONS_SUCCESS;
+ }
int success = mWifiThreadRunner.call(() -> mWifiNetworkSuggestionsManager.add(
- networkSuggestions, callingUid, callingPackageName, callingFeatureId),
+ networkSuggestions.getList(), callingUid, callingPackageName, callingFeatureId),
WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
TAG + "#addNetworkSuggestions");
- if (success != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
+ if (success != STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
Log.e(TAG, "Failed to add network suggestions");
}
return success;
@@ -6285,7 +6367,7 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public int removeNetworkSuggestions(
- List<WifiNetworkSuggestion> networkSuggestions, String callingPackageName,
+ ParceledListSlice<WifiNetworkSuggestion> networkSuggestions, String callingPackageName,
@WifiManager.ActionAfterRemovingSuggestion int action) {
if (enforceChangePermission(callingPackageName) != MODE_ALLOWED) {
return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_APP_DISALLOWED;
@@ -6299,11 +6381,14 @@ public class WifiServiceImpl extends BaseWifiService {
}
int callingUid = Binder.getCallingUid();
+ if (networkSuggestions == null) {
+ return STATUS_NETWORK_SUGGESTIONS_SUCCESS;
+ }
int success = mWifiThreadRunner.call(() -> mWifiNetworkSuggestionsManager.remove(
- networkSuggestions, callingUid, callingPackageName,
+ networkSuggestions.getList(), callingUid, callingPackageName,
action), WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
TAG + "#removeNetworkSuggestions");
- if (success != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
+ if (success != STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
Log.e(TAG, "Failed to remove network suggestions");
}
return success;
@@ -6315,16 +6400,17 @@ public class WifiServiceImpl extends BaseWifiService {
* @return a list of network suggestions suggested by this app
*/
@Override
- public List<WifiNetworkSuggestion> getNetworkSuggestions(String callingPackageName) {
+ public ParceledListSlice<WifiNetworkSuggestion> getNetworkSuggestions(
+ String callingPackageName) {
int callingUid = Binder.getCallingUid();
mAppOps.checkPackage(callingUid, callingPackageName);
enforceAccessPermission();
if (mVerboseLoggingEnabled) {
mLog.info("getNetworkSuggestionList uid=%").c(Binder.getCallingUid()).flush();
}
- return mWifiThreadRunner.call(() ->
+ return new ParceledListSlice<>(mWifiThreadRunner.call(() ->
mWifiNetworkSuggestionsManager.get(callingPackageName, callingUid),
- Collections.emptyList(), TAG + "#getNetworkSuggestions");
+ Collections.emptyList(), TAG + "#getNetworkSuggestions"));
}
/**
@@ -7559,7 +7645,8 @@ public class WifiServiceImpl extends BaseWifiService {
true, TAG + " getUsableChannels");
}
if (mVerboseLoggingEnabled) {
- mLog.info("getUsableChannels uid=%").c(Binder.getCallingUid()).flush();
+ mLog.info("getUsableChannels uid=% band=% mode=% filter=%").c(Binder.getCallingUid()).c(
+ band).c(mode).c(filter).flush();
}
if (!isValidBandForGetUsableChannels(band)) {
throw new IllegalArgumentException("Unsupported band: " + band);
@@ -7765,11 +7852,11 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
- public void notifyWifiSsidPolicyChanged(int policyType, List<WifiSsid> ssids) {
+ public void notifyWifiSsidPolicyChanged(int policyType, ParceledListSlice<WifiSsid> ssids) {
if (!SdkLevel.isAtLeastT()) {
throw new UnsupportedOperationException();
}
- if (ssids == null) {
+ if (ssids == null || ssids.getList() == null) {
throw new IllegalArgumentException("SSID list may not be null");
}
if (!checkManageDeviceAdminsPermission(Binder.getCallingPid(), Binder.getCallingUid())) {
@@ -7786,13 +7873,13 @@ public class WifiServiceImpl extends BaseWifiService {
WifiSsid ssid = wifiInfo.getWifiSsid();
if (policyType == WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST
- && !ssids.contains(ssid)) {
+ && !ssids.getList().contains(ssid)) {
cmm.disconnect();
mLog.info("disconnect admin restricted network").flush();
continue;
}
if (policyType == WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST
- && ssids.contains(ssid)) {
+ && ssids.getList().contains(ssid)) {
cmm.disconnect();
mLog.info("disconnect admin restricted network").flush();
continue;
@@ -7843,14 +7930,16 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public void addCustomDhcpOptions(@NonNull WifiSsid ssid, @NonNull byte[] oui,
- @NonNull List<DhcpOption> options) {
+ @NonNull ParceledListSlice<DhcpOption> options) {
enforceAnyPermissionOf(android.Manifest.permission.NETWORK_SETTINGS,
android.Manifest.permission.OVERRIDE_WIFI_CONFIG);
if (mVerboseLoggingEnabled) {
Log.v(TAG, "addCustomDhcpOptions: ssid="
+ ssid + ", oui=" + Arrays.toString(oui) + ", options=" + options);
}
- mWifiThreadRunner.post(() -> mWifiConfigManager.addCustomDhcpOptions(ssid, oui, options),
+ List<DhcpOption> dhcpOptionList = options == null ? null : options.getList();
+ mWifiThreadRunner.post(() -> mWifiConfigManager.addCustomDhcpOptions(ssid, oui,
+ dhcpOptionList),
TAG + "#addCustomDhcpOptions");
}
@@ -7873,7 +7962,7 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
public String[] getOemPrivilegedWifiAdminPackages() {
- return mContext.getResources()
+ return mResourceCache
.getStringArray(R.array.config_oemPrivilegedWifiAdminPackages);
}
@@ -7955,7 +8044,7 @@ public class WifiServiceImpl extends BaseWifiService {
}
@Override
public int getMaxNumberOfChannelsPerRequest() {
- return mContext.getResources()
+ return mResourceCache
.getInteger(R.integer.config_wifiNetworkSpecifierMaxPreferredChannels);
}
@@ -8003,7 +8092,7 @@ public class WifiServiceImpl extends BaseWifiService {
*/
@Override
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
- public void addQosPolicies(@NonNull List<QosPolicyParams> policyParamsList,
+ public void addQosPolicies(@NonNull ParceledListSlice<QosPolicyParams> policyParamsList,
@NonNull IBinder binder, @NonNull String packageName,
@NonNull IListListener listener) {
if (!SdkLevel.isAtLeastU()) {
@@ -8018,33 +8107,39 @@ public class WifiServiceImpl extends BaseWifiService {
}
Objects.requireNonNull(policyParamsList, "policyParamsList cannot be null");
+ Objects.requireNonNull(policyParamsList.getList(),
+ "policyParamsList contents cannot be null");
Objects.requireNonNull(binder, "binder cannot be null");
Objects.requireNonNull(listener, "listener cannot be null");
+ if (policyParamsList.getList().size() == 0
+ || policyParamsList.getList().size()
+ > WifiManager.getMaxNumberOfPoliciesPerQosRequest()
+ || !policyIdsAreUnique(policyParamsList.getList())
+ || !policiesHaveSameDirection(policyParamsList.getList())) {
+ throw new IllegalArgumentException("policyParamsList is invalid");
+ }
+
if (!mApplicationQosPolicyRequestHandler.isFeatureEnabled()) {
Log.i(TAG, "addQosPolicies is disabled on this device");
- rejectAllQosPolicies(policyParamsList, listener);
+ rejectAllQosPolicies(policyParamsList.getList(), listener);
return;
}
- if (policyParamsList.size() == 0
- || policyParamsList.size() > WifiManager.getMaxNumberOfPoliciesPerQosRequest()
- || !policyIdsAreUnique(policyParamsList)
- || !policiesHaveSameDirection(policyParamsList)) {
- throw new IllegalArgumentException("policyParamsList is invalid");
- }
+
if (!(SdkLevel.isAtLeastV() && isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX))
- && policyParamsList.get(0).getDirection() == QosPolicyParams.DIRECTION_UPLINK) {
+ && policyParamsList.getList().get(0).getDirection()
+ == QosPolicyParams.DIRECTION_UPLINK) {
Log.e(TAG, "Uplink QoS policies are only supported on devices with SDK >= V"
+ " and 11ax support");
- rejectAllQosPolicies(policyParamsList, listener);
+ rejectAllQosPolicies(policyParamsList.getList(), listener);
return;
}
mWifiThreadRunner.post(() -> {
mApplicationQosPolicyRequestHandler.queueAddRequest(
- policyParamsList, listener, binder, uid);
+ policyParamsList.getList(), listener, binder, uid);
}, TAG + "#addQosPolicies");
}
@@ -8542,7 +8637,7 @@ public class WifiServiceImpl extends BaseWifiService {
if (!SdkLevel.isAtLeastV()) {
throw new UnsupportedOperationException("SDK level too old");
}
- if (!isAggressiveRoamingModeSupported()) {
+ if (!isAggressiveRoamingModeSupported() && roamingMode == ROAMING_MODE_AGGRESSIVE) {
throw new UnsupportedOperationException("Aggressive roaming mode not supported");
}
Objects.requireNonNull(ssid, "ssid cannot be null");
@@ -8577,9 +8672,6 @@ public class WifiServiceImpl extends BaseWifiService {
if (!SdkLevel.isAtLeastV()) {
throw new UnsupportedOperationException("SDK level too old");
}
- if (!isAggressiveRoamingModeSupported()) {
- throw new UnsupportedOperationException("Aggressive roaming mode not supported");
- }
Objects.requireNonNull(ssid, "ssid cannot be null");
Objects.requireNonNull(packageName, "packageName cannot be null");
@@ -8609,9 +8701,6 @@ public class WifiServiceImpl extends BaseWifiService {
if (!SdkLevel.isAtLeastV()) {
throw new UnsupportedOperationException("SDK level too old");
}
- if (!isAggressiveRoamingModeSupported()) {
- throw new UnsupportedOperationException("Aggressive roaming mode not supported");
- }
Objects.requireNonNull(packageName, "packageName cannot be null");
Objects.requireNonNull(listener, "listener cannot be null");
diff --git a/service/java/com/android/server/wifi/WifiSettingsConfigStore.java b/service/java/com/android/server/wifi/WifiSettingsConfigStore.java
index 17af39fdd8..a5ba58dd13 100644
--- a/service/java/com/android/server/wifi/WifiSettingsConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiSettingsConfigStore.java
@@ -136,12 +136,19 @@ public class WifiSettingsConfigStore {
new Key<>("wifi_default_country_code", WifiCountryCode.getOemDefaultCountryCode());
/**
- * Store the supported features retrieved from WiFi HAL and Supplicant HAL
+ * Store the supported features retrieved from WiFi HAL and Supplicant HAL. Note that this
+ * value is deprecated and is replaced by {@link #WIFI_NATIVE_EXTENDED_SUPPORTED_FEATURES}
*/
public static final Key<Long> WIFI_NATIVE_SUPPORTED_FEATURES =
new Key<>("wifi_native_supported_features", 0L);
/**
+ * Store the extended supported features retrieved from WiFi HAL and Supplicant HAL
+ */
+ public static final Key<long[]> WIFI_NATIVE_EXTENDED_SUPPORTED_FEATURES =
+ new Key<>("wifi_native_extended_supported_features", new long[0]);
+
+ /**
* Store the supported features retrieved from WiFi HAL and Supplicant HAL
*/
public static final Key<Integer> WIFI_NATIVE_SUPPORTED_STA_BANDS =
diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java
index 8b68e3a2a2..1439406afb 100644
--- a/service/java/com/android/server/wifi/WifiShellCommand.java
+++ b/service/java/com/android/server/wifi/WifiShellCommand.java
@@ -29,6 +29,9 @@ import static android.net.wifi.WifiManager.VERBOSE_LOGGING_LEVEL_DISABLED;
import static android.net.wifi.WifiManager.VERBOSE_LOGGING_LEVEL_WIFI_AWARE_ENABLED_ONLY;
import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
+import static android.net.wifi.WifiManager.ROAMING_MODE_NONE;
+import static android.net.wifi.WifiManager.ROAMING_MODE_NORMAL;
+import static android.net.wifi.WifiManager.ROAMING_MODE_AGGRESSIVE;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDGE;
@@ -517,28 +520,70 @@ public class WifiShellCommand extends BasicShellCommandHandler {
+ mWifiGlobals.getIpReachabilityDisconnectEnabled());
return 0;
case "set-poll-rssi-interval-msecs":
- int newPollIntervalMsecs;
- try {
- newPollIntervalMsecs = Integer.parseInt(getNextArgRequired());
- } catch (NumberFormatException e) {
- pw.println(
+ List<Integer> newPollIntervals = new ArrayList<>();
+ while (getRemainingArgsCount() > 0) {
+ int newPollIntervalMsecs;
+ try {
+ newPollIntervalMsecs = Integer.parseInt(getNextArgRequired());
+ } catch (NumberFormatException e) {
+ pw.println(
"Invalid argument to 'set-poll-rssi-interval-msecs' "
- + "- must be a positive integer");
- return -1;
- }
+ + "- must be a positive integer");
+ return -1;
+ }
- if (newPollIntervalMsecs < 1) {
- pw.println(
+ if (newPollIntervalMsecs < 1) {
+ pw.println(
"Invalid argument to 'set-poll-rssi-interval-msecs' "
- + "- must be a positive integer");
- return -1;
+ + "- must be a positive integer");
+ return -1;
+ }
+
+ newPollIntervals.add(newPollIntervalMsecs);
}
- mWifiGlobals.setPollRssiIntervalMillis(newPollIntervalMsecs);
+ switch (newPollIntervals.size()) {
+ case 0:
+ throw new IllegalArgumentException(
+ "Need at least one valid rssi polling interval");
+ case 1:
+ mActiveModeWarden.getPrimaryClientModeManager()
+ .setLinkLayerStatsPollingInterval(newPollIntervals.get(0));
+ break;
+ case 2:
+ int newShortIntervalMsecs = newPollIntervals.get(0);
+ int newLongIntervalMsecs = newPollIntervals.get(1);
+ if (newShortIntervalMsecs >= newLongIntervalMsecs) {
+ pw.println(
+ "Invalid argument to 'set-poll-rssi-interval-msecs' "
+ + "- the long polling interval must be greater "
+ + "than the short polling interval");
+ return -1;
+ }
+ mWifiGlobals.setPollRssiShortIntervalMillis(newShortIntervalMsecs);
+ mWifiGlobals.setPollRssiLongIntervalMillis(newLongIntervalMsecs);
+ mWifiGlobals.setPollRssiIntervalMillis(newShortIntervalMsecs);
+ mActiveModeWarden.getPrimaryClientModeManager()
+ .setLinkLayerStatsPollingInterval(0);
+ break;
+ default:
+ pw.println("Too many arguments, need at most two valid rssi polling "
+ + "intervals");
+ return -1;
+ }
return 0;
case "get-poll-rssi-interval-msecs":
- pw.println("WifiGlobals.getPollRssiIntervalMillis() = "
+ pw.println("Current interval between RSSI polls (milliseconds) = "
+ mWifiGlobals.getPollRssiIntervalMillis());
+ if (mWifiGlobals.isAdjustPollRssiIntervalEnabled()
+ && mDeviceConfig.isAdjustPollRssiIntervalEnabled()
+ && !mWifiGlobals.isPollRssiIntervalOverridden()) {
+ pw.println("Auto adjustment of poll rssi is enabled");
+ pw.println("Regular (short) interval between RSSI polls (milliseconds) = "
+ + mWifiGlobals.getPollRssiShortIntervalMillis());
+ pw.println("Long interval between RSSI polls (milliseconds) = "
+ + mWifiGlobals.getPollRssiLongIntervalMillis());
+ }
return 0;
case "force-hi-perf-mode": {
boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled");
@@ -819,6 +864,12 @@ public class WifiShellCommand extends BasicShellCommandHandler {
mWifiService.clearExternalPnoScanRequest();
return 0;
}
+ case "set-pno-scan": {
+ boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled");
+ mWifiService.setPnoScanEnabled(enabled, true /*enablePnoScanAfterWifiToggle*/,
+ mContext.getOpPackageName());
+ return 0;
+ }
case "start-lohs": {
CountDownLatch countDownLatch = new CountDownLatch(2);
SoftApConfiguration config = buildSoftApConfiguration(pw);
@@ -1123,7 +1174,7 @@ public class WifiShellCommand extends BasicShellCommandHandler {
return -1;
}
int errorCode = mWifiService.addNetworkSuggestions(
- Arrays.asList(suggestion), SHELL_PACKAGE_NAME, null);
+ new ParceledListSlice(List.of(suggestion)), SHELL_PACKAGE_NAME, null);
if (errorCode != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
pw.println("Add network suggestion failed with error code: " + errorCode);
return -1;
@@ -1164,7 +1215,7 @@ public class WifiShellCommand extends BasicShellCommandHandler {
actionCode = ACTION_REMOVE_SUGGESTION_LINGER;
}
List<WifiNetworkSuggestion> suggestions =
- mWifiService.getNetworkSuggestions(SHELL_PACKAGE_NAME);
+ mWifiService.getNetworkSuggestions(SHELL_PACKAGE_NAME).getList();
WifiNetworkSuggestion suggestion = suggestions.stream()
.filter(s -> s.getSsid().equals(ssid))
.findAny()
@@ -1174,7 +1225,8 @@ public class WifiShellCommand extends BasicShellCommandHandler {
return -1;
}
mWifiService.removeNetworkSuggestions(
- Arrays.asList(suggestion), SHELL_PACKAGE_NAME, actionCode);
+ new ParceledListSlice<>(List.of(suggestion)),
+ SHELL_PACKAGE_NAME, actionCode);
// untrusted/oem-paid networks need a corresponding NetworkRequest.
if (suggestion.isUntrusted()
|| (SdkLevel.isAtLeastS()
@@ -1192,12 +1244,12 @@ public class WifiShellCommand extends BasicShellCommandHandler {
}
case "remove-all-suggestions":
mWifiService.removeNetworkSuggestions(
- Collections.emptyList(), SHELL_PACKAGE_NAME,
+ new ParceledListSlice<>(Collections.emptyList()), SHELL_PACKAGE_NAME,
WifiManager.ACTION_REMOVE_SUGGESTION_DISCONNECT);
return 0;
case "list-suggestions": {
List<WifiNetworkSuggestion> suggestions =
- mWifiService.getNetworkSuggestions(SHELL_PACKAGE_NAME);
+ mWifiService.getNetworkSuggestions(SHELL_PACKAGE_NAME).getList();
printWifiNetworkSuggestions(pw, suggestions);
return 0;
}
@@ -1210,7 +1262,7 @@ public class WifiShellCommand extends BasicShellCommandHandler {
case "list-suggestions-from-app": {
String packageName = getNextArgRequired();
List<WifiNetworkSuggestion> suggestions =
- mWifiService.getNetworkSuggestions(packageName);
+ mWifiService.getNetworkSuggestions(packageName).getList();
printWifiNetworkSuggestions(pw, suggestions);
return 0;
}
@@ -2194,6 +2246,38 @@ public class WifiShellCommand extends BasicShellCommandHandler {
resourceCache.restoreIntegerValue(overlayName);
}
}
+ case "string" -> {
+ String value;
+ if (isEnabled) {
+ value = getNextArgRequired();
+ resourceCache.overrideStringValue(overlayName, value);
+ } else {
+ resourceCache.restoreStringValue(overlayName);
+ }
+ }
+ case "string-array" -> {
+ String[] value;
+ if (isEnabled) {
+ value = peekRemainingArgs();
+ resourceCache.overrideStringArrayValue(overlayName, value);
+ } else {
+ resourceCache.restoreStringArrayValue(overlayName);
+ }
+ }
+ case "integer-array" -> {
+ String[] input;
+ if (isEnabled) {
+ input = peekRemainingArgs();
+ int[] value = new int[input.length];
+ for (int i = 0; i < input.length; i++) {
+ value[i] = Integer.parseInt(input[i]);
+ }
+
+ resourceCache.overrideIntArrayValue(overlayName, value);
+ } else {
+ resourceCache.restoreIntArrayValue(overlayName);
+ }
+ }
default -> {
pw.print("require a valid type of the overlay");
return -1;
@@ -2204,6 +2288,32 @@ public class WifiShellCommand extends BasicShellCommandHandler {
case "get-overlay-config-values":
mContext.getResourceCache().dump(pw);
return 0;
+ case "set-ssid-roaming-mode":
+ String ssid = getNextArgRequired();
+ String roamingMode = getNextArgRequired();
+ String option = getNextOption();
+
+ WifiSsid wifiSsid;
+ if (option != null && option.equals("-x")) {
+ wifiSsid = WifiSsid.fromString(ssid);
+ } else {
+ wifiSsid = WifiSsid.fromString("\"" + ssid + "\"");
+ }
+
+ int mode;
+ if (roamingMode.equals("none")) {
+ mode = ROAMING_MODE_NONE;
+ } else if (roamingMode.equals("normal")) {
+ mode = ROAMING_MODE_NORMAL;
+ } else if (roamingMode.equals("aggressive")) {
+ mode = ROAMING_MODE_AGGRESSIVE;
+ } else {
+ pw.println("Unsupported roaming mode");
+ return -1;
+ }
+
+ mWifiService.setPerSsidRoamingMode(wifiSsid, mode, SHELL_PACKAGE_NAME);
+ return 0;
default:
return handleDefaultCommands(cmd);
}
@@ -2999,10 +3109,11 @@ public class WifiShellCommand extends BasicShellCommandHandler {
pw.println(" '31' - band 2.4, 5, 6 and 60 GHz with DFS channels");
pw.println(" get-cached-scan-data");
pw.println(" Gets scan data cached by the firmware");
- pw.println(" force-overlay-config-value bool|integer <overlayName> enabled|disabled"
- + "<configValue>");
+ pw.println(" force-overlay-config-value bool|integer|string|integer-array|string-array "
+ + "<overlayName> enabled|disabled <configValue>");
pw.println(" Force overlay to a specified value.");
- pw.println(" bool|integer - specified the type of the overlay");
+ pw.println(" bool|integer|string|integer-array|string-array - specified the type of the "
+ + "overlay");
pw.println(" <overlayName> - name of the overlay whose value is overridden.");
pw.println(" enabled|disabled: enable the override or disable it and revert to using "
+ "the built-in value.");
@@ -3019,8 +3130,15 @@ public class WifiShellCommand extends BasicShellCommandHandler {
}
private void onHelpPrivileged(PrintWriter pw) {
- pw.println(" set-poll-rssi-interval-msecs <int>");
- pw.println(" Sets the interval between RSSI polls to <int> milliseconds.");
+ pw.println(" set-poll-rssi-interval-msecs <int> [<int>]");
+ pw.println(" Sets the interval between RSSI polls to the specified value(s), in "
+ + "milliseconds.");
+ pw.println(" When only one value is specified, set the interval to that value. "
+ + "When two values are specified, set the regular (short) interval to the first "
+ + "value, and set the long interval to the second value. Note that the "
+ + "enabling/disabling of auto adjustment between the two intervals is handled by "
+ + "the respective flags. If the auto adjustment is disabled, it is equivalent to "
+ + "only specifying the first value, and then setting the interval to that value");
pw.println(" get-poll-rssi-interval-msecs");
pw.println(" Gets current interval between RSSI polls, in milliseconds.");
pw.println(" force-hi-perf-mode enabled|disabled");
@@ -3236,6 +3354,8 @@ public class WifiShellCommand extends BasicShellCommandHandler {
pw.println(" Requests to include a non-quoted UTF-8 SSID in PNO scans");
pw.println(" clear-pno-request");
pw.println(" Clear the PNO scan request.");
+ pw.println(" set-pno-scan enabled|disabled");
+ pw.println(" Set the PNO scan enabled or disabled.");
pw.println(" start-dpp-enrollee-responder [-i <info>] [-c <curve>]");
pw.println(" Start DPP Enrollee responder mode.");
pw.println(" -i - Device Info to be used in DPP Bootstrapping URI");
@@ -3285,6 +3405,10 @@ public class WifiShellCommand extends BasicShellCommandHandler {
+ "option provided or no arguments provided after the -r option, then set the "
+ "request properties to none in the request.");
pw.println(" Example: configure-afc-server https://testURL -r key1 value1 key2 value2");
+ pw.println(" set-ssid-roaming-mode <ssid> none|normal|aggressive [-x]");
+ pw.println(" Sets the roaming mode for the given SSID.");
+ pw.println(" -x - Specifies the SSID as hex digits instead of plain text.");
+ pw.println(" Example: set-ssid-roaming-mode test_ssid aggressive");
}
@Override
diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java
index d8714ff6e3..9d2f1d5ffa 100644
--- a/service/java/com/android/server/wifi/WifiVendorHal.java
+++ b/service/java/com/android/server/wifi/WifiVendorHal.java
@@ -18,6 +18,7 @@ package com.android.server.wifi;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDGE;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_STA;
+import static com.android.server.wifi.util.GeneralUtil.getCapabilityIndex;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -56,6 +57,7 @@ import com.google.errorprone.annotations.CompileTimeConstant;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
@@ -788,15 +790,15 @@ public class WifiVendorHal {
*
* @return bitmask defined by WifiManager.WIFI_FEATURE_*
*/
- private long getSupportedFeatureSetFromPackageManager() {
- long featureSet = 0;
+ private BitSet getSupportedFeatureSetFromPackageManager() {
+ BitSet featureSet = new BitSet();
final PackageManager pm = sContext.getPackageManager();
for (Pair pair: sSystemFeatureCapabilityTranslation) {
if (pm.hasSystemFeature((String) pair.second)) {
- featureSet |= (long) pair.first;
+ featureSet.set(getCapabilityIndex((long) pair.first));
}
}
- enter("System feature set: %").c(featureSet).flush();
+ enter("System feature set: %").c(featureSet.toString()).flush();
return featureSet;
}
@@ -873,50 +875,51 @@ public class WifiVendorHal {
* The result may differ depending on the mode (STA or AP)
*
* @param ifaceName Name of the interface.
- * @return bitmask defined by WifiManager.WIFI_FEATURE_*
+ * @return BitSet defined by WifiManager.WIFI_FEATURE_*
*/
- public long getSupportedFeatureSet(@NonNull String ifaceName) {
- long featureSet = 0L;
+ public BitSet getSupportedFeatureSet(@NonNull String ifaceName) {
+ BitSet featureSet = new BitSet();
if (!mHalDeviceManager.isStarted() || !mHalDeviceManager.isSupported()) {
return getSupportedFeatureSetFromPackageManager();
}
synchronized (sLock) {
if (mWifiChip != null) {
- WifiChip.Response<Long> capsResp = mWifiChip.getCapabilitiesAfterIfacesExist();
+ WifiChip.Response<BitSet> capsResp = mWifiChip.getCapabilitiesAfterIfacesExist();
if (capsResp.getStatusCode() == WifiHal.WIFI_STATUS_SUCCESS) {
featureSet = capsResp.getValue();
} else if (capsResp.getStatusCode() == WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION) {
- return 0;
+ return new BitSet();
}
}
WifiStaIface iface = getStaIface(ifaceName);
if (iface != null) {
- featureSet |= iface.getCapabilities();
+ featureSet.or(iface.getCapabilities());
if (mHalDeviceManager.is24g5gDbsSupported(iface)
|| mHalDeviceManager.is5g6gDbsSupported(iface)) {
- featureSet |= WifiManager.WIFI_FEATURE_DUAL_BAND_SIMULTANEOUS;
+ featureSet.set(
+ getCapabilityIndex(WifiManager.WIFI_FEATURE_DUAL_BAND_SIMULTANEOUS));
}
}
}
if (mWifiGlobals.isWpa3SaeH2eSupported()) {
- featureSet |= WifiManager.WIFI_FEATURE_SAE_H2E;
+ featureSet.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_SAE_H2E));
}
Set<Integer> supportedIfaceTypes = mHalDeviceManager.getSupportedIfaceTypes();
if (supportedIfaceTypes.contains(WifiChip.IFACE_TYPE_STA)) {
- featureSet |= WifiManager.WIFI_FEATURE_INFRA;
+ featureSet.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_INFRA));
}
if (supportedIfaceTypes.contains(WifiChip.IFACE_TYPE_AP)) {
- featureSet |= WifiManager.WIFI_FEATURE_MOBILE_HOTSPOT;
+ featureSet.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_MOBILE_HOTSPOT));
}
if (supportedIfaceTypes.contains(WifiChip.IFACE_TYPE_P2P)) {
- featureSet |= WifiManager.WIFI_FEATURE_P2P;
+ featureSet.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_P2P));
}
if (supportedIfaceTypes.contains(WifiChip.IFACE_TYPE_NAN)) {
- featureSet |= WifiManager.WIFI_FEATURE_AWARE;
+ featureSet.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_AWARE));
}
return featureSet;
diff --git a/service/java/com/android/server/wifi/aware/PairingConfigManager.java b/service/java/com/android/server/wifi/aware/PairingConfigManager.java
index c0ce760b6a..59061d2439 100644
--- a/service/java/com/android/server/wifi/aware/PairingConfigManager.java
+++ b/service/java/com/android/server/wifi/aware/PairingConfigManager.java
@@ -42,8 +42,12 @@ public class PairingConfigManager {
private static final String TAG = "AwarePairingManager";
- private static final int NIK_SIZE_IN_BYTE = 16;
- private static final int TAG_SIZE_IN_BYTE = 8;
+ // NIK size
+ public static final int NIK_SIZE_IN_BYTE = 16;
+ // TAG size
+ public static final int TAG_SIZE_IN_BYTE = 8;
+ // NIR byte array
+ public static final byte[] NIR = {'N', 'I', 'R'};
/**
* Store the NPKSA from the NAN Pairing confirmation
@@ -76,7 +80,6 @@ public class PairingConfigManager {
private byte[] createRandomNik() {
long first, second;
-
Random mRandom = new SecureRandom();
first = mRandom.nextLong();
second = mRandom.nextLong();
@@ -119,14 +122,13 @@ public class PairingConfigManager {
private boolean checkMatchAlias(String alias, byte[] nonce, byte[] tag, byte[] mac) {
byte[] nik = mAliasToNikMap.get(alias);
- byte[] nir = {'N', 'I', 'R'};
if (nik == null) return false;
SecretKeySpec spec = new SecretKeySpec(nik, "HmacSHA256");
try {
Mac hash = Mac.getInstance("HmacSHA256");
hash.init(spec);
- hash.update(nir);
+ hash.update(NIR);
hash.update(mac);
hash.update(nonce);
byte[] message = Arrays.copyOf(hash.doFinal(), TAG_SIZE_IN_BYTE);
@@ -155,11 +157,8 @@ public class PairingConfigManager {
if (info == null) {
return;
}
- Set<String> pairedDevices = mPerAppPairedAliasMap.get(packageName);
- if (pairedDevices == null) {
- pairedDevices = new HashSet<>();
- mPerAppPairedAliasMap.put(packageName, pairedDevices);
- }
+ Set<String> pairedDevices = mPerAppPairedAliasMap.computeIfAbsent(packageName,
+ k -> new HashSet<>());
pairedDevices.add(alias);
mAliasToNikMap.put(alias, info.mPeerNik);
mAliasToSecurityInfoMap.put(alias, info);
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
index a4fd8ad693..3df13e88a9 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
@@ -154,6 +154,8 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
private static final String TAG = "WifiAwareStateManager";
private boolean mVdbg = false; // STOPSHIP if true - for detailed state machine
private boolean mVerboseLoggingEnabled = false;
+ private static final short NUM_LOG_RECS = 256;
+ private static final short NUM_LOG_RECS_VERBOSE = 1024;
@VisibleForTesting
public static final String HAL_COMMAND_TIMEOUT_TAG = TAG + " HAL Command Timeout";
@@ -320,6 +322,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
private static final String MESSAGE_RANGING_INDICATION = "ranging_indication";
private static final String MESSAGE_RANGE_MM = "range_mm";
private static final String MESSAGE_BUNDLE_KEY_NDP_IDS = "ndp_ids";
+ private static final String MESSAGE_BUNDLE_KEY_NDP_ID = "ndp_id";
private static final String MESSAGE_BUNDLE_KEY_APP_INFO = "app_info";
private static final String MESSAGE_BUNDLE_KEY_ACCEPT_STATE = "accept_state";
private static final String MESSAGE_BUNDLE_KEY_NONCE = "nonce";
@@ -457,8 +460,8 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
boolean vDbg) {
mVerboseLoggingEnabled = verboseEnabled;
mDataPathMgr.enableVerboseLogging(verboseEnabled, vDbg);
- mSm.setDbg(halVerboseLogging);
mVdbg = vDbg;
+ mSm.setLogRecSize(verboseEnabled ? NUM_LOG_RECS_VERBOSE : NUM_LOG_RECS);
}
/**
@@ -718,16 +721,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
}
if (action.equals(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)) {
- if (mSettableParameters.get(PARAM_ON_IDLE_DISABLE_AWARE) != 0) {
- if (mPowerManager.isDeviceIdleMode()
- && !isAnyCallerIgnoringBatteryOptimizations()) {
- disableUsage(false);
- } else {
- enableUsage();
- }
- } else {
- reconfigure();
- }
+ reconfigure();
}
}
},
@@ -1450,13 +1444,6 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
* only happens when a connection is created.
*/
public void enableUsage() {
- if (mSettableParameters.get(PARAM_ON_IDLE_DISABLE_AWARE) != 0
- && mPowerManager.isDeviceIdleMode()) {
- if (mVerboseLoggingEnabled) {
- Log.d(TAG, "enableUsage(): while device is in IDLE mode - ignoring");
- }
- return;
- }
if (!SdkLevel.isAtLeastT() && !mWifiPermissionsUtil.isLocationModeEnabled()) {
if (mVerboseLoggingEnabled) {
Log.d(TAG, "enableUsage(): while location is disabled - ignoring");
@@ -1545,6 +1532,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
boolean isOutOfBand, byte[] appInfo) {
Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
msg.arg1 = COMMAND_TYPE_INITIATE_DATA_PATH_SETUP;
+ msg.arg2 = networkSpecifier.clientId;
msg.obj = networkSpecifier;
msg.getData().putInt(MESSAGE_BUNDLE_KEY_PEER_ID, peerId);
msg.getData().putInt(MESSAGE_BUNDLE_KEY_CHANNEL_REQ_TYPE, channelRequestType);
@@ -1564,8 +1552,11 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
WifiAwareNetworkSpecifier networkSpecifier) {
Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
msg.arg1 = COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST;
- msg.arg2 = ndpId;
+ if (networkSpecifier != null) {
+ msg.arg2 = networkSpecifier.clientId;
+ }
msg.obj = networkSpecifier;
+ msg.getData().putInt(MESSAGE_BUNDLE_KEY_NDP_ID, ndpId);
msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_ACCEPT_STATE, accept);
msg.getData().putString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME, interfaceName);
msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_APP_INFO, appInfo);
@@ -2248,6 +2239,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
/* --> */ addState(mWaitForResponseState, mDefaultState);
setInitialState(mWaitState);
+ setLogRecSize(NUM_LOG_RECS);
}
@Override
@@ -2372,36 +2364,11 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
case MESSAGE_TYPE_BOOTSTRAPPING_TIMEOUT -> "MESSAGE_TYPE_BOOTSTRAPPING_TIMEOUT";
default -> {
Log.e(TAG, "unknown message what: " + what);
- yield "what:" + what;
+ yield "<unknown>";
}
};
}
- private String messageToString(Message msg) {
- StringBuilder sb = new StringBuilder();
-
- String s = getWhatToString(msg.what);
- if (s == null) {
- s = "<unknown>";
- }
- sb.append(s).append("/");
-
- if (msg.what == MESSAGE_TYPE_NOTIFICATION || msg.what == MESSAGE_TYPE_COMMAND
- || msg.what == MESSAGE_TYPE_RESPONSE) {
- s = getWhatToString(msg.arg1);
- if (s == null) {
- s = "<unknown>";
- }
- sb.append(s);
- }
-
- if (msg.what == MESSAGE_TYPE_RESPONSE || msg.what == MESSAGE_TYPE_RESPONSE_TIMEOUT) {
- sb.append(" (Transaction ID=").append(msg.arg2).append(")");
- }
-
- return sb.toString();
- }
-
public void onAwareDownCleanupSendQueueState() {
mSendQueueBlocked = false;
mHostQueuedSendMessages.clear();
@@ -2493,6 +2460,8 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
@Override
public void enterImpl() {
+ mCurrentCommand = null;
+ mCurrentTransactionId = TRANSACTION_ID_IGNORE;
}
@Override
@@ -2681,6 +2650,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
if (reason != NanStatusCode.SUCCESS) {
sendAwareStateChangedBroadcast(false);
}
+ releaseAwareInterface();
break;
}
case NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS: {
@@ -3182,7 +3152,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
case COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST: {
Bundle data = msg.getData();
- int ndpId = msg.arg2;
+ int ndpId = data.getInt(MESSAGE_BUNDLE_KEY_NDP_ID);
WifiAwareNetworkSpecifier specifier =
(WifiAwareNetworkSpecifier) msg.obj;
boolean accept = data.getBoolean(MESSAGE_BUNDLE_KEY_ACCEPT_STATE);
@@ -3384,7 +3354,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG),
reason);
if (success) {
- int ndpId = mCurrentCommand.arg2;
+ int ndpId = mCurrentCommand.getData().getInt(MESSAGE_BUNDLE_KEY_NDP_ID);
WakeupMessage timeout = new WakeupMessage(mContext, getHandler(),
HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG, MESSAGE_TYPE_DATA_PATH_TIMEOUT,
ndpId);
@@ -3491,8 +3461,6 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
}
default:
Log.wtf(TAG, "processResponse: this isn't a RESPONSE -- msg=" + msg);
- mCurrentCommand = null;
- mCurrentTransactionId = TRANSACTION_ID_IGNORE;
return;
}
if (msg.arg1 != RESPONSE_TYPE_ON_CONFIG_SUCCESS
@@ -3500,9 +3468,6 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
// Config response handle separately to identify it's connect or reconfigure
recordHalApiCall(mCurrentCommand.arg1, reason, mStartTime);
}
-
- mCurrentCommand = null;
- mCurrentTransactionId = TRANSACTION_ID_IGNORE;
}
private void processTimeout(Message msg) {
@@ -3634,9 +3599,6 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
Log.wtf(TAG, "processTimeout: this isn't a COMMAND -- msg=" + msg);
/* fall-through */
}
-
- mCurrentCommand = null;
- mCurrentTransactionId = TRANSACTION_ID_IGNORE;
}
private void updateSendMessageTimeout() {
@@ -3722,11 +3684,44 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
@Override
protected String getLogRecString(Message msg) {
- StringBuilder sb = new StringBuilder(messageToString(msg));
+ StringBuilder sb = new StringBuilder();
+ if (msg.what == MESSAGE_TYPE_NOTIFICATION || msg.what == MESSAGE_TYPE_COMMAND
+ || msg.what == MESSAGE_TYPE_RESPONSE
+ || msg.what == MESSAGE_TYPE_RESPONSE_TIMEOUT) {
+ sb.append(getWhatToString(msg.arg1));
+ }
+ Message message = msg;
+ if ((msg.what == MESSAGE_TYPE_RESPONSE || msg.what == MESSAGE_TYPE_RESPONSE_TIMEOUT)
+ && mCurrentCommand != null) {
+ message = mCurrentCommand;
+ }
+ if (msg.what == MESSAGE_TYPE_COMMAND
+ || msg.what == MESSAGE_TYPE_RESPONSE
+ || msg.what == MESSAGE_TYPE_RESPONSE_TIMEOUT) {
+ if (message.arg1 == COMMAND_TYPE_CONNECT) {
+ sb.append(" caller=")
+ .append(message.getData().getString(MESSAGE_BUNDLE_KEY_CALLING_PACKAGE))
+ .append("(")
+ .append(message.getData().getInt(MESSAGE_BUNDLE_KEY_UID))
+ .append(")");
+ } else {
+ WifiAwareClientState client = mClients.get(message.arg2);
+ if (client != null) {
+ sb.append(" caller=")
+ .append(client.getCallingPackage())
+ .append("(")
+ .append(client.getUid())
+ .append(")");
+ }
+ }
+ }
if (msg.what == MESSAGE_TYPE_COMMAND
&& mCurrentTransactionId != TRANSACTION_ID_IGNORE) {
sb.append(" (Transaction ID=").append(mCurrentTransactionId).append(")");
+ } else if (msg.what == MESSAGE_TYPE_RESPONSE
+ || msg.what == MESSAGE_TYPE_RESPONSE_TIMEOUT) {
+ sb.append(" (Transaction ID=").append(msg.arg2).append(")");
}
return sb.toString();
@@ -5096,7 +5091,8 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
+ ", success=" + success + ", reasonOnFailure=" + reasonOnFailure);
}
- return mDataPathMgr.onRespondToDataPathRequest(command.arg2, success, reasonOnFailure);
+ return mDataPathMgr.onRespondToDataPathRequest(
+ command.getData().getInt(MESSAGE_BUNDLE_KEY_NDP_ID), success, reasonOnFailure);
}
private void onEndPathEndResponseLocal(Message command, boolean success, int reasonOnFailure) {
diff --git a/service/java/com/android/server/wifi/hal/IWifiChip.java b/service/java/com/android/server/wifi/hal/IWifiChip.java
index 7e3e7dbfcb..7c8235c1db 100644
--- a/service/java/com/android/server/wifi/hal/IWifiChip.java
+++ b/service/java/com/android/server/wifi/hal/IWifiChip.java
@@ -29,6 +29,7 @@ import com.android.server.wifi.SarInfo;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.WlanWakeReasonAndCounts;
+import java.util.BitSet;
import java.util.List;
/** Abstraction of WifiChip */
@@ -153,19 +154,19 @@ public interface IWifiChip {
* but it is recommended to use {@link #getCapabilitiesAfterIfacesExist()} once
* any ifaces are up.
*
- * @return {@link WifiChip.Response} where the value is a bitset of
+ * @return {@link WifiChip.Response} where the value is a BitSet of
* WifiManager.WIFI_FEATURE_* values.
*/
- WifiChip.Response<Long> getCapabilitiesBeforeIfacesExist();
+ WifiChip.Response<BitSet> getCapabilitiesBeforeIfacesExist();
/**
* Get the capabilities supported by this chip.
* Call if interfaces have been created on this chip.
*
- * @return {@link WifiChip.Response} where the value is a bitset of
+ * @return {@link WifiChip.Response} where the value is a BitSet of
* WifiManager.WIFI_FEATURE_* values.
*/
- WifiChip.Response<Long> getCapabilitiesAfterIfacesExist();
+ WifiChip.Response<BitSet> getCapabilitiesAfterIfacesExist();
/**
* Retrieve the Wi-Fi wakeup reason stats for debugging.
diff --git a/service/java/com/android/server/wifi/hal/IWifiStaIface.java b/service/java/com/android/server/wifi/hal/IWifiStaIface.java
index 3e4078531a..2358d2bcd6 100644
--- a/service/java/com/android/server/wifi/hal/IWifiStaIface.java
+++ b/service/java/com/android/server/wifi/hal/IWifiStaIface.java
@@ -29,6 +29,7 @@ import com.android.server.wifi.WifiLinkLayerStats;
import com.android.server.wifi.WifiLoggerHal;
import com.android.server.wifi.WifiNative;
+import java.util.BitSet;
import java.util.List;
/** Abstraction of WifiStaIface */
@@ -97,9 +98,9 @@ public interface IWifiStaIface {
/**
* Get the capabilities supported by this STA iface.
*
- * @return Bitset of WifiManager.WIFI_FEATURE_* values.
+ * @return BitSet of WifiManager.WIFI_FEATURE_* values.
*/
- long getCapabilities();
+ BitSet getCapabilities();
/**
* Retrieve the fates of inbound packets.
diff --git a/service/java/com/android/server/wifi/hal/WifiChip.java b/service/java/com/android/server/wifi/hal/WifiChip.java
index 19d52b8518..557573f207 100644
--- a/service/java/com/android/server/wifi/hal/WifiChip.java
+++ b/service/java/com/android/server/wifi/hal/WifiChip.java
@@ -37,6 +37,7 @@ import com.android.server.wifi.util.NativeUtil;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.BitSet;
import java.util.List;
import java.util.function.Supplier;
@@ -657,16 +658,16 @@ public class WifiChip {
/**
* See comments for {@link IWifiChip#getCapabilitiesBeforeIfacesExist()}
*/
- public Response<Long> getCapabilitiesBeforeIfacesExist() {
- return validateAndCall("getCapabilitiesBeforeIfacesExist", new Response<>(0L),
+ public Response<BitSet> getCapabilitiesBeforeIfacesExist() {
+ return validateAndCall("getCapabilitiesBeforeIfacesExist", new Response<>(new BitSet()),
() -> mWifiChip.getCapabilitiesBeforeIfacesExist());
}
/**
* See comments for {@link IWifiChip#getCapabilitiesAfterIfacesExist()}
*/
- public Response<Long> getCapabilitiesAfterIfacesExist() {
- return validateAndCall("getCapabilitiesAfterIfacesExist", new Response<>(0L),
+ public Response<BitSet> getCapabilitiesAfterIfacesExist() {
+ return validateAndCall("getCapabilitiesAfterIfacesExist", new Response<>(new BitSet()),
() -> mWifiChip.getCapabilitiesAfterIfacesExist());
}
diff --git a/service/java/com/android/server/wifi/hal/WifiChipAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiChipAidlImpl.java
index f9e4ce2232..6ce53df724 100644
--- a/service/java/com/android/server/wifi/hal/WifiChipAidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiChipAidlImpl.java
@@ -23,6 +23,8 @@ import static android.hardware.wifi.WifiChannelWidthInMhz.WIDTH_80;
import static android.hardware.wifi.WifiChannelWidthInMhz.WIDTH_80P80;
import static android.net.wifi.CoexUnsafeChannel.POWER_CAP_NONE;
+import static com.android.server.wifi.util.GeneralUtil.getCapabilityIndex;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -78,6 +80,7 @@ import com.android.server.wifi.util.HalAidlUtil;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.List;
/**
@@ -389,7 +392,7 @@ public class WifiChipAidlImpl implements IWifiChip {
* See comments for {@link IWifiChip#getCapabilitiesBeforeIfacesExist()}
*/
@Override
- public WifiChip.Response<Long> getCapabilitiesBeforeIfacesExist() {
+ public WifiChip.Response<BitSet> getCapabilitiesBeforeIfacesExist() {
final String methodStr = "getCapabilitiesBeforeIfacesExist";
return getCapabilitiesInternal(methodStr);
}
@@ -398,15 +401,15 @@ public class WifiChipAidlImpl implements IWifiChip {
* See comments for {@link IWifiChip#getCapabilitiesAfterIfacesExist()}
*/
@Override
- public WifiChip.Response<Long> getCapabilitiesAfterIfacesExist() {
+ public WifiChip.Response<BitSet> getCapabilitiesAfterIfacesExist() {
final String methodStr = "getCapabilitiesAfterIfacesExist";
return getCapabilitiesInternal(methodStr);
}
- private WifiChip.Response<Long> getCapabilitiesInternal(String methodStr) {
+ private WifiChip.Response<BitSet> getCapabilitiesInternal(String methodStr) {
// getCapabilities uses the same logic in AIDL, regardless of whether the call
// happens before or after any interfaces have been created.
- WifiChip.Response<Long> featuresResp = new WifiChip.Response<>(0L);
+ WifiChip.Response<BitSet> featuresResp = new WifiChip.Response<>(new BitSet());
synchronized (mLock) {
try {
if (!checkIfaceAndLogFailure(methodStr)) return featuresResp;
@@ -1590,28 +1593,28 @@ public class WifiChipAidlImpl implements IWifiChip {
}
@VisibleForTesting
- protected static long halToFrameworkChipFeatureSet(long halFeatureSet) {
- long features = 0;
+ protected static BitSet halToFrameworkChipFeatureSet(long halFeatureSet) {
+ BitSet features = new BitSet();
if (bitmapContains(halFeatureSet, FeatureSetMask.SET_TX_POWER_LIMIT)) {
- features |= WifiManager.WIFI_FEATURE_TX_POWER_LIMIT;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_TX_POWER_LIMIT));
}
if (bitmapContains(halFeatureSet, FeatureSetMask.D2D_RTT)) {
- features |= WifiManager.WIFI_FEATURE_D2D_RTT;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_D2D_RTT));
}
if (bitmapContains(halFeatureSet, FeatureSetMask.D2AP_RTT)) {
- features |= WifiManager.WIFI_FEATURE_D2AP_RTT;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_D2AP_RTT));
}
if (bitmapContains(halFeatureSet, FeatureSetMask.SET_LATENCY_MODE)) {
- features |= WifiManager.WIFI_FEATURE_LOW_LATENCY;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_LOW_LATENCY));
}
if (bitmapContains(halFeatureSet, FeatureSetMask.P2P_RAND_MAC)) {
- features |= WifiManager.WIFI_FEATURE_P2P_RAND_MAC;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_P2P_RAND_MAC));
}
if (bitmapContains(halFeatureSet, FeatureSetMask.WIGIG)) {
- features |= WifiManager.WIFI_FEATURE_INFRA_60G;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_INFRA_60G));
}
if (bitmapContains(halFeatureSet, FeatureSetMask.T2LM_NEGOTIATION)) {
- features |= WifiManager.WIFI_FEATURE_T2LM_NEGOTIATION;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_T2LM_NEGOTIATION));
}
return features;
}
diff --git a/service/java/com/android/server/wifi/hal/WifiChipHidlImpl.java b/service/java/com/android/server/wifi/hal/WifiChipHidlImpl.java
index 31101ac116..505b6545d4 100644
--- a/service/java/com/android/server/wifi/hal/WifiChipHidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiChipHidlImpl.java
@@ -23,6 +23,8 @@ import static android.hardware.wifi.V1_6.WifiChannelWidthInMhz.WIDTH_80;
import static android.hardware.wifi.V1_6.WifiChannelWidthInMhz.WIDTH_80P80;
import static android.net.wifi.CoexUnsafeChannel.POWER_CAP_NONE;
+import static com.android.server.wifi.util.GeneralUtil.getCapabilityIndex;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -64,6 +66,7 @@ import com.android.wifi.resources.R;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.List;
import java.util.function.Supplier;
@@ -236,9 +239,9 @@ public class WifiChipHidlImpl implements IWifiChip {
* See comments for {@link IWifiChip#getCapabilitiesBeforeIfacesExist()}
*/
@Override
- public WifiChip.Response<Long> getCapabilitiesBeforeIfacesExist() {
+ public WifiChip.Response<BitSet> getCapabilitiesBeforeIfacesExist() {
String methodStr = "getCapabilitiesBeforeIfacesExist";
- return validateAndCall(methodStr, new WifiChip.Response<>(0L),
+ return validateAndCall(methodStr, new WifiChip.Response<>(new BitSet()),
() -> getCapabilitiesBeforeIfacesExistInternal(methodStr));
}
@@ -246,9 +249,9 @@ public class WifiChipHidlImpl implements IWifiChip {
* See comments for {@link IWifiChip#getCapabilitiesAfterIfacesExist()}
*/
@Override
- public WifiChip.Response<Long> getCapabilitiesAfterIfacesExist() {
+ public WifiChip.Response<BitSet> getCapabilitiesAfterIfacesExist() {
String methodStr = "getCapabilitiesAfterIfacesExist";
- return validateAndCall(methodStr, new WifiChip.Response<>(0L),
+ return validateAndCall(methodStr, new WifiChip.Response<>(new BitSet()),
() -> getCapabilitiesAfterIfacesExistInternal(methodStr));
}
@@ -800,8 +803,8 @@ public class WifiChipHidlImpl implements IWifiChip {
return modeResp.value;
}
- private WifiChip.Response<Long> getCapabilitiesBeforeIfacesExistInternal(String methodStr) {
- WifiChip.Response<Long> capsResp = new WifiChip.Response<>(0L);
+ private WifiChip.Response<BitSet> getCapabilitiesBeforeIfacesExistInternal(String methodStr) {
+ WifiChip.Response<BitSet> capsResp = new WifiChip.Response<>(new BitSet());
try {
// HAL newer than v1.5 supports getting capabilities before creating an interface.
android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
@@ -823,8 +826,8 @@ public class WifiChipHidlImpl implements IWifiChip {
return capsResp;
}
- private WifiChip.Response<Long> getCapabilitiesAfterIfacesExistInternal(String methodStr) {
- WifiChip.Response<Long> capsResp = new WifiChip.Response<>(0L);
+ private WifiChip.Response<BitSet> getCapabilitiesAfterIfacesExistInternal(String methodStr) {
+ WifiChip.Response<BitSet> capsResp = new WifiChip.Response<>(new BitSet());
try {
android.hardware.wifi.V1_5.IWifiChip chip15 = getWifiChipV1_5Mockable();
android.hardware.wifi.V1_3.IWifiChip chip13 = getWifiChipV1_3Mockable();
@@ -851,7 +854,7 @@ public class WifiChipHidlImpl implements IWifiChip {
} else {
mWifiChip.getCapabilities((status, caps) -> {
if (isOk(status, methodStr)) {
- capsResp.setValue((long) wifiFeatureMaskFromChipCapabilities(caps));
+ capsResp.setValue(wifiFeatureMaskFromChipCapabilities(caps));
capsResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
} else {
capsResp.setStatusCode(
@@ -1790,11 +1793,11 @@ public class WifiChipHidlImpl implements IWifiChip {
* @return bitmask defined by WifiManager.WIFI_FEATURE_*
*/
@VisibleForTesting
- int wifiFeatureMaskFromChipCapabilities(int capabilities) {
- int features = 0;
+ BitSet wifiFeatureMaskFromChipCapabilities(int capabilities) {
+ BitSet features = new BitSet();
for (int i = 0; i < sChipFeatureCapabilityTranslation.length; i++) {
if ((capabilities & sChipFeatureCapabilityTranslation[i][1]) != 0) {
- features |= sChipFeatureCapabilityTranslation[i][0];
+ features.set(getCapabilityIndex(sChipFeatureCapabilityTranslation[i][0]));
}
}
return features;
@@ -1807,14 +1810,14 @@ public class WifiChipHidlImpl implements IWifiChip {
* @return bitmask defined by WifiManager.WIFI_FEATURE_*
*/
@VisibleForTesting
- long wifiFeatureMaskFromChipCapabilities_1_5(int capabilities) {
+ BitSet wifiFeatureMaskFromChipCapabilities_1_5(int capabilities) {
// First collect features from previous versions
- long features = wifiFeatureMaskFromChipCapabilities_1_3(capabilities);
+ BitSet features = wifiFeatureMaskFromChipCapabilities_1_3(capabilities);
// Next collect features for V1_5 version
for (int i = 0; i < sChipFeatureCapabilityTranslation15.length; i++) {
if ((capabilities & sChipFeatureCapabilityTranslation15[i][1]) != 0) {
- features |= sChipFeatureCapabilityTranslation15[i][0];
+ features.set(getCapabilityIndex(sChipFeatureCapabilityTranslation15[i][0]));
}
}
return features;
@@ -1827,14 +1830,14 @@ public class WifiChipHidlImpl implements IWifiChip {
* @return bitmask defined by WifiManager.WIFI_FEATURE_*
*/
@VisibleForTesting
- long wifiFeatureMaskFromChipCapabilities_1_3(int capabilities) {
+ BitSet wifiFeatureMaskFromChipCapabilities_1_3(int capabilities) {
// First collect features from previous versions
- long features = wifiFeatureMaskFromChipCapabilities(capabilities);
+ BitSet features = wifiFeatureMaskFromChipCapabilities(capabilities);
// Next collect features for V1_3 version
for (int i = 0; i < sChipFeatureCapabilityTranslation13.length; i++) {
if ((capabilities & sChipFeatureCapabilityTranslation13[i][1]) != 0) {
- features |= sChipFeatureCapabilityTranslation13[i][0];
+ features.set(getCapabilityIndex(sChipFeatureCapabilityTranslation13[i][0]));
}
}
return features;
diff --git a/service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java
index 2b5a7da08a..ecefe9bf33 100644
--- a/service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiNanIfaceAidlImpl.java
@@ -18,6 +18,8 @@ package com.android.server.wifi.hal;
import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_128;
import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_256;
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128;
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_256;
import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128;
import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
@@ -455,9 +457,9 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
byte[] pairingIdentityKey, boolean enablePairingCache, int requestType, byte[] pmk,
String password, int akm, int cipherSuite) {
String methodStr = "respondToPairingRequest";
- NanRespondToPairingIndicationRequest request = createNanPairingResponse(pairingId, accept,
- pairingIdentityKey, enablePairingCache, requestType, pmk, password, akm,
- cipherSuite);
+ NanRespondToPairingIndicationRequest request = createRespondToPairingIndicationRequest(
+ pairingId, accept, pairingIdentityKey, enablePairingCache, requestType, pmk,
+ password, akm, cipherSuite);
synchronized (mLock) {
try {
if (!checkIfaceAndLogFailure(methodStr)) return false;
@@ -844,7 +846,7 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.OPEN;
WifiAwareDataPathSecurityConfig securityConfig = publishConfig.getSecurityConfig();
if (securityConfig != null) {
- req.baseConfigs.securityConfig.cipherType = getHalCipherSuiteType(
+ req.baseConfigs.securityConfig.cipherType = getHalCipherSuites(
securityConfig.getCipherSuite());
if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.PMK;
@@ -867,6 +869,10 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
req.publishType = publishConfig.mPublishType;
req.txType = NanTxType.BROADCAST;
req.pairingConfig = createAidlPairingConfig(publishConfig.getPairingConfig());
+ if (publishConfig.getPairingConfig() != null) {
+ req.baseConfigs.securityConfig.cipherType |= getHalCipherSuites(
+ publishConfig.getPairingConfig().getSupportedCipherSuites());
+ }
req.identityKey = copyArray(nik, 16);
if (SdkLevel.isAtLeastV() && !publishConfig.getVendorData().isEmpty()) {
@@ -935,6 +941,10 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
req.subscribeType = subscribeConfig.mSubscribeType;
req.pairingConfig = createAidlPairingConfig(subscribeConfig.getPairingConfig());
+ if (subscribeConfig.getPairingConfig() != null) {
+ req.baseConfigs.securityConfig.cipherType |= getHalCipherSuites(
+ subscribeConfig.getPairingConfig().getSupportedCipherSuites());
+ }
req.identityKey = copyArray(nik, 16);
req.intfAddr = new android.hardware.wifi.MacAddress[0];
@@ -995,7 +1005,7 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
req.securityConfig.scid = new byte[16];
req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
if (securityConfig != null) {
- req.securityConfig.cipherType = getHalCipherSuiteType(securityConfig.getCipherSuite());
+ req.securityConfig.cipherType = getHalCipherSuites(securityConfig.getCipherSuite());
if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
req.securityConfig.securityType = NanDataPathSecurityType.PMK;
req.securityConfig.pmk = copyArray(securityConfig.getPmk());
@@ -1032,7 +1042,7 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
: NanPairingRequestType.NAN_PAIRING_VERIFICATION;
request.securityConfig = new NanPairingSecurityConfig();
request.securityConfig.pmk = new byte[32];
- request.securityConfig.cipherType = cipherSuite;
+ request.securityConfig.cipherType = getHalCipherSuites(cipherSuite);
request.securityConfig.passphrase = new byte[0];
if (pmk != null && pmk.length != 0) {
request.securityConfig.securityType = NanPairingSecurityType.PMK;
@@ -1050,7 +1060,7 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
return request;
}
- private static NanRespondToPairingIndicationRequest createNanPairingResponse(
+ private static NanRespondToPairingIndicationRequest createRespondToPairingIndicationRequest(
int pairingInstanceId, boolean accept, byte[] pairingIdentityKey,
boolean enablePairingCache, int requestType, byte[] pmk, String password, int akm,
int cipherSuite) {
@@ -1065,7 +1075,7 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
request.securityConfig = new NanPairingSecurityConfig();
request.securityConfig.pmk = new byte[32];
request.securityConfig.passphrase = new byte[0];
- request.securityConfig.cipherType = cipherSuite;
+ request.securityConfig.cipherType = getHalCipherSuites(cipherSuite);
if (pmk != null && pmk.length != 0) {
request.securityConfig.securityType = NanPairingSecurityType.PMK;
request.securityConfig.pmk = copyArray(pmk);
@@ -1097,7 +1107,7 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
req.securityConfig.scid = new byte[16];
req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
if (securityConfig != null) {
- req.securityConfig.cipherType = getHalCipherSuiteType(securityConfig.getCipherSuite());
+ req.securityConfig.cipherType = getHalCipherSuites(securityConfig.getCipherSuite());
if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) {
req.securityConfig.securityType = NanDataPathSecurityType.PMK;
req.securityConfig.pmk = copyArray(securityConfig.getPmk());
@@ -1119,18 +1129,27 @@ public class WifiNanIfaceAidlImpl implements IWifiNanIface {
return req;
}
- private static int getHalCipherSuiteType(int frameworkCipherSuites) {
- switch (frameworkCipherSuites) {
- case WIFI_AWARE_CIPHER_SUITE_NCS_SK_128:
- return NanCipherSuiteType.SHARED_KEY_128_MASK;
- case WIFI_AWARE_CIPHER_SUITE_NCS_SK_256:
- return NanCipherSuiteType.SHARED_KEY_256_MASK;
- case WIFI_AWARE_CIPHER_SUITE_NCS_PK_128:
- return NanCipherSuiteType.PUBLIC_KEY_2WDH_256_MASK;
- case WIFI_AWARE_CIPHER_SUITE_NCS_PK_256:
- return NanCipherSuiteType.PUBLIC_KEY_2WDH_256_MASK;
+ private static int getHalCipherSuites(int frameworkCipherSuites) {
+ int cipherSuites = NanCipherSuiteType.NONE;
+ if ((frameworkCipherSuites & WIFI_AWARE_CIPHER_SUITE_NCS_SK_128) != 0) {
+ cipherSuites |= NanCipherSuiteType.SHARED_KEY_128_MASK;
+ }
+ if ((frameworkCipherSuites & WIFI_AWARE_CIPHER_SUITE_NCS_SK_256) != 0) {
+ cipherSuites |= NanCipherSuiteType.SHARED_KEY_256_MASK;
+ }
+ if ((frameworkCipherSuites & WIFI_AWARE_CIPHER_SUITE_NCS_PK_128) != 0) {
+ cipherSuites |= NanCipherSuiteType.PUBLIC_KEY_2WDH_128_MASK;
+ }
+ if ((frameworkCipherSuites & WIFI_AWARE_CIPHER_SUITE_NCS_PK_256) != 0) {
+ cipherSuites |= NanCipherSuiteType.PUBLIC_KEY_2WDH_256_MASK;
+ }
+ if ((frameworkCipherSuites & WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128) != 0) {
+ cipherSuites |= NanCipherSuiteType.PUBLIC_KEY_PASN_128_MASK;
+ }
+ if ((frameworkCipherSuites & WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_256) != 0) {
+ cipherSuites |= NanCipherSuiteType.PUBLIC_KEY_PASN_256_MASK;
}
- return NanCipherSuiteType.NONE;
+ return cipherSuites;
}
private static byte[] copyArray(byte[] source) {
diff --git a/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java
index bb1a2e1bf2..f3c410badf 100644
--- a/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiNanIfaceCallbackAidlImpl.java
@@ -440,18 +440,21 @@ public class WifiNanIfaceCallbackAidlImpl extends IWifiNanIfaceEventCallback.Stu
NanRangingIndication.fromAidl(event.rangingIndicationType),
event.rangingMeasurementInMm,
event.scid,
- toPublicDataPathCipherSuites(event.peerCipherType),
+ toPublicDataPathCipherSuites(event.peerCipherType)
+ | toPublicPairingCipherSuites(event.peerCipherType),
event.peerNira.nonce,
event.peerNira.tag,
- createPublicPairingConfig(event.peerPairingConfig),
+ createPublicPairingConfig(event.peerPairingConfig, event.peerCipherType),
vendorData);
}
- private AwarePairingConfig createPublicPairingConfig(NanPairingConfig nativePairingConfig) {
+ private AwarePairingConfig createPublicPairingConfig(NanPairingConfig nativePairingConfig,
+ int cipherSuites) {
return new AwarePairingConfig(nativePairingConfig.enablePairingSetup,
nativePairingConfig.enablePairingCache,
nativePairingConfig.enablePairingVerification,
- toBootStrappingMethods(nativePairingConfig.supportedBootstrappingMethods));
+ toBootStrappingMethods(nativePairingConfig.supportedBootstrappingMethods),
+ toPublicPairingCipherSuites(cipherSuites));
}
private int toBootStrappingMethods(int nativeMethods) {
@@ -642,7 +645,7 @@ public class WifiNanIfaceCallbackAidlImpl extends IWifiNanIfaceEventCallback.Stu
NpkSecurityAssociation npksa) {
return new PairingSecurityAssociationInfo(npksa.peerNanIdentityKey,
npksa.localNanIdentityKey, npksa.npk,
- createPublicPairingAkm(npksa.akm), toPublicDataPathCipherSuites(npksa.cipherType));
+ createPublicPairingAkm(npksa.akm), toPublicPairingCipherSuites(npksa.cipherType));
}
private static int createPublicPairingAkm(int aidlAkm) {
diff --git a/service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java
index 9c10ee0937..ba32e3f93b 100644
--- a/service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiRttControllerAidlImpl.java
@@ -56,6 +56,8 @@ import java.util.Set;
public class WifiRttControllerAidlImpl implements IWifiRttController {
private static final String TAG = "WifiRttControllerAidl";
private boolean mVerboseLoggingEnabled = false;
+ private static final int CONVERSION_MICROS_TO_10_MILLIS = 10000;
+ private static final int CONVERSION_MICROS_TO_100_MICROS = 100;
private android.hardware.wifi.IWifiRttController mWifiRttController;
private WifiRttController.Capabilities mRttCapabilities;
@@ -292,8 +294,10 @@ public class WifiRttControllerAidlImpl implements IWifiRttController {
.setMeasurementChannelFrequencyMHz(rttResult.channelFreqMHz)
.setMeasurementBandwidth(halToFrameworkChannelBandwidth(rttResult.packetBw))
.set80211azNtbMeasurement(rttResult.type == RttType.TWO_SIDED_11AZ_NTB)
- .setMinTimeBetweenNtbMeasurementsMicros(rttResult.ntbMinMeasurementTime)
- .setMaxTimeBetweenNtbMeasurementsMicros(rttResult.ntbMaxMeasurementTime)
+ .setMinTimeBetweenNtbMeasurementsMicros(rttResult.ntbMinMeasurementTime
+ * CONVERSION_MICROS_TO_100_MICROS)
+ .setMaxTimeBetweenNtbMeasurementsMicros(rttResult.ntbMaxMeasurementTime
+ * CONVERSION_MICROS_TO_10_MILLIS)
.set80211azInitiatorTxLtfRepetitionsCount(rttResult.i2rTxLtfRepetitionCount)
.set80211azResponderTxLtfRepetitionsCount(rttResult.r2iTxLtfRepetitionCount)
.set80211azNumberOfTxSpatialStreams(rttResult.numTxSpatialStreams)
@@ -486,11 +490,11 @@ public class WifiRttControllerAidlImpl implements IWifiRttController {
}
validateBwAndPreambleCombination(config.bw, config.preamble);
// ResponderConfig#ntbMaxMeasurementTime is in units of 10 milliseconds
- config.ntbMaxMeasurementTime =
- responder.getNtbMaxTimeBetweenMeasurementsMicros() / 10000;
+ config.ntbMaxMeasurementTime = responder.getNtbMaxTimeBetweenMeasurementsMicros()
+ / CONVERSION_MICROS_TO_10_MILLIS;
// ResponderConfig#ntbMinMeasurementTime is in units of 100 microseconds
- config.ntbMinMeasurementTime =
- responder.getNtbMinTimeBetweenMeasurementsMicros() / 100;
+ config.ntbMinMeasurementTime = responder.getNtbMinTimeBetweenMeasurementsMicros()
+ / CONVERSION_MICROS_TO_100_MICROS;
if (config.peer == RttPeerType.NAN_TYPE) {
config.mustRequestLci = false;
diff --git a/service/java/com/android/server/wifi/hal/WifiStaIface.java b/service/java/com/android/server/wifi/hal/WifiStaIface.java
index ca4cd785d1..b0caeca366 100644
--- a/service/java/com/android/server/wifi/hal/WifiStaIface.java
+++ b/service/java/com/android/server/wifi/hal/WifiStaIface.java
@@ -37,6 +37,7 @@ import com.android.server.wifi.WifiLinkLayerStats;
import com.android.server.wifi.WifiNative;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.List;
import java.util.function.Supplier;
@@ -253,8 +254,8 @@ public class WifiStaIface implements WifiHal.WifiInterface {
/**
* See comments for {@link IWifiStaIface#getCapabilities()}
*/
- public long getCapabilities() {
- return validateAndCall("getCapabilities", 0L,
+ public BitSet getCapabilities() {
+ return validateAndCall("getCapabilities", new BitSet(),
() -> mWifiStaIface.getCapabilities());
}
diff --git a/service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java b/service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java
index 8cb199a0f4..ee64cfef71 100644
--- a/service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiStaIfaceAidlImpl.java
@@ -17,6 +17,7 @@
package com.android.server.wifi.hal;
import static com.android.server.wifi.hal.WifiHalAidlImpl.isServiceVersionAtLeast;
+import static com.android.server.wifi.util.GeneralUtil.getCapabilityIndex;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -80,6 +81,7 @@ import com.android.server.wifi.util.NativeUtil;
import com.android.wifi.resources.R;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.List;
/**
@@ -281,11 +283,11 @@ public class WifiStaIfaceAidlImpl implements IWifiStaIface {
* See comments for {@link IWifiStaIface#getCapabilities()}
*/
@Override
- public long getCapabilities() {
+ public BitSet getCapabilities() {
final String methodStr = "getCapabilities";
synchronized (mLock) {
try {
- if (!checkIfaceAndLogFailure(methodStr)) return 0L;
+ if (!checkIfaceAndLogFailure(methodStr)) return new BitSet();
long halFeatureSet = mWifiStaIface.getFeatureSet();
return halToFrameworkStaFeatureSet(halFeatureSet);
} catch (RemoteException e) {
@@ -293,7 +295,7 @@ public class WifiStaIfaceAidlImpl implements IWifiStaIface {
} catch (ServiceSpecificException e) {
handleServiceSpecificException(e, methodStr);
}
- return 0L;
+ return new BitSet();
}
}
@@ -1265,59 +1267,60 @@ public class WifiStaIfaceAidlImpl implements IWifiStaIface {
}
@VisibleForTesting
- protected static long halToFrameworkStaFeatureSet(long halFeatureSet) {
- long features = 0;
+ protected static BitSet halToFrameworkStaFeatureSet(long halFeatureSet) {
+ BitSet features = new BitSet();
if (hasCapability(halFeatureSet,
android.hardware.wifi.IWifiStaIface.FeatureSetMask.HOTSPOT)) {
- features |= WifiManager.WIFI_FEATURE_PASSPOINT;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_PASSPOINT));
}
if (hasCapability(halFeatureSet,
android.hardware.wifi.IWifiStaIface.FeatureSetMask.BACKGROUND_SCAN)) {
- features |= WifiManager.WIFI_FEATURE_SCANNER;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_SCANNER));
}
if (hasCapability(halFeatureSet,
android.hardware.wifi.IWifiStaIface.FeatureSetMask.PNO)) {
- features |= WifiManager.WIFI_FEATURE_PNO;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_PNO));
}
if (hasCapability(halFeatureSet,
android.hardware.wifi.IWifiStaIface.FeatureSetMask.TDLS)) {
- features |= WifiManager.WIFI_FEATURE_TDLS;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_TDLS));
}
if (hasCapability(halFeatureSet,
android.hardware.wifi.IWifiStaIface.FeatureSetMask.TDLS_OFFCHANNEL)) {
- features |= WifiManager.WIFI_FEATURE_TDLS_OFFCHANNEL;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_TDLS_OFFCHANNEL));
}
if (hasCapability(halFeatureSet,
android.hardware.wifi.IWifiStaIface.FeatureSetMask.LINK_LAYER_STATS)) {
- features |= WifiManager.WIFI_FEATURE_LINK_LAYER_STATS;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS));
}
if (hasCapability(halFeatureSet,
android.hardware.wifi.IWifiStaIface.FeatureSetMask.RSSI_MONITOR)) {
- features |= WifiManager.WIFI_FEATURE_RSSI_MONITOR;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_RSSI_MONITOR));
}
if (hasCapability(halFeatureSet,
android.hardware.wifi.IWifiStaIface.FeatureSetMask.KEEP_ALIVE)) {
- features |= WifiManager.WIFI_FEATURE_MKEEP_ALIVE;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_MKEEP_ALIVE));
}
if (hasCapability(halFeatureSet,
android.hardware.wifi.IWifiStaIface.FeatureSetMask.ND_OFFLOAD)) {
- features |= WifiManager.WIFI_FEATURE_CONFIG_NDO;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_CONFIG_NDO));
}
if (hasCapability(halFeatureSet,
android.hardware.wifi.IWifiStaIface.FeatureSetMask.CONTROL_ROAMING)) {
- features |= WifiManager.WIFI_FEATURE_CONTROL_ROAMING;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_CONTROL_ROAMING));
}
if (hasCapability(halFeatureSet,
android.hardware.wifi.IWifiStaIface.FeatureSetMask.PROBE_IE_ALLOWLIST)) {
- features |= WifiManager.WIFI_FEATURE_IE_WHITELIST;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_IE_WHITELIST));
}
if (hasCapability(halFeatureSet,
android.hardware.wifi.IWifiStaIface.FeatureSetMask.SCAN_RAND)) {
- features |= WifiManager.WIFI_FEATURE_SCAN_RAND;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_SCAN_RAND));
}
if (hasCapability(halFeatureSet,
android.hardware.wifi.IWifiStaIface.FeatureSetMask.ROAMING_MODE_CONTROL)) {
- features |= WifiManager.WIFI_FEATURE_AGGRESSIVE_ROAMING_MODE_SUPPORT;
+ features.set(
+ getCapabilityIndex(WifiManager.WIFI_FEATURE_AGGRESSIVE_ROAMING_MODE_SUPPORT));
}
return features;
}
diff --git a/service/java/com/android/server/wifi/hal/WifiStaIfaceHidlImpl.java b/service/java/com/android/server/wifi/hal/WifiStaIfaceHidlImpl.java
index 399fd2c377..bdcecdeb03 100644
--- a/service/java/com/android/server/wifi/hal/WifiStaIfaceHidlImpl.java
+++ b/service/java/com/android/server/wifi/hal/WifiStaIfaceHidlImpl.java
@@ -18,6 +18,8 @@ package com.android.server.wifi.hal;
import static android.net.wifi.WifiUsabilityStatsEntry.LINK_STATE_UNKNOWN;
+import static com.android.server.wifi.util.GeneralUtil.getCapabilityIndex;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -61,6 +63,7 @@ import com.android.server.wifi.util.NativeUtil;
import com.android.wifi.resources.R;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.List;
import java.util.function.Supplier;
@@ -159,9 +162,9 @@ public class WifiStaIfaceHidlImpl implements IWifiStaIface {
/**
* See comments for {@link IWifiStaIface#getCapabilities()}
*/
- public long getCapabilities() {
+ public BitSet getCapabilities() {
final String methodStr = "getCapabilities";
- return validateAndCall(methodStr, 0L,
+ return validateAndCall(methodStr, new BitSet(),
() -> getCapabilitiesInternal(methodStr));
}
@@ -467,8 +470,8 @@ public class WifiStaIfaceHidlImpl implements IWifiStaIface {
return scanResp.value;
}
- private long getCapabilitiesInternal(String methodStr) {
- GeneralUtil.Mutable<Long> capsResp = new GeneralUtil.Mutable<>(0L);
+ private BitSet getCapabilitiesInternal(String methodStr) {
+ GeneralUtil.Mutable<BitSet> capsResp = new GeneralUtil.Mutable<>(new BitSet());
try {
mWifiStaIface.getCapabilities((status, caps) -> {
if (isOk(status, methodStr)) {
@@ -889,56 +892,56 @@ public class WifiStaIfaceHidlImpl implements IWifiStaIface {
}
@VisibleForTesting
- long halToFrameworkStaIfaceCapability(int caps) {
- long features = 0;
+ BitSet halToFrameworkStaIfaceCapability(int caps) {
+ BitSet features = new BitSet();
if (hasCapability(caps,
android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.HOTSPOT)) {
- features |= WifiManager.WIFI_FEATURE_PASSPOINT;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_PASSPOINT));
}
if (hasCapability(caps,
android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN)) {
- features |= WifiManager.WIFI_FEATURE_SCANNER;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_SCANNER));
}
if (hasCapability(caps,
android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.PNO)) {
- features |= WifiManager.WIFI_FEATURE_PNO;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_PNO));
}
if (hasCapability(caps,
android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.TDLS)) {
- features |= WifiManager.WIFI_FEATURE_TDLS;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_TDLS));
}
if (hasCapability(caps,
android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.TDLS_OFFCHANNEL)) {
- features |= WifiManager.WIFI_FEATURE_TDLS_OFFCHANNEL;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_TDLS_OFFCHANNEL));
}
if (hasCapability(caps,
android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS)) {
- features |= WifiManager.WIFI_FEATURE_LINK_LAYER_STATS;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_LINK_LAYER_STATS));
}
if (hasCapability(caps,
android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.RSSI_MONITOR)) {
- features |= WifiManager.WIFI_FEATURE_RSSI_MONITOR;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_RSSI_MONITOR));
}
if (hasCapability(caps,
android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.KEEP_ALIVE)) {
- features |= WifiManager.WIFI_FEATURE_MKEEP_ALIVE;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_MKEEP_ALIVE));
}
if (hasCapability(caps,
android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.ND_OFFLOAD)) {
- features |= WifiManager.WIFI_FEATURE_CONFIG_NDO;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_CONFIG_NDO));
}
if (hasCapability(caps,
android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.CONTROL_ROAMING)) {
- features |= WifiManager.WIFI_FEATURE_CONTROL_ROAMING;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_CONTROL_ROAMING));
}
if (hasCapability(caps,
android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask
.PROBE_IE_WHITELIST)) {
- features |= WifiManager.WIFI_FEATURE_IE_WHITELIST;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_IE_WHITELIST));
}
if (hasCapability(caps,
android.hardware.wifi.V1_0.IWifiStaIface.StaIfaceCapabilityMask.SCAN_RAND)) {
- features |= WifiManager.WIFI_FEATURE_SCAN_RAND;
+ features.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_SCAN_RAND));
}
return features;
}
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java
index 44db1f3c0d..afb6b8ff6e 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelper.java
@@ -342,8 +342,6 @@ public class PasspointNetworkNominateHelper {
return existingNetwork;
}
mWifiConfigManager.enableNetwork(result.getNetworkId(), false, config.creatorUid, null);
- mWifiConfigManager.setNetworkCandidateScanResult(result.getNetworkId(),
- candidate.mScanDetail.getScanResult(), 0, null);
mWifiConfigManager.updateScanDetailForNetwork(
result.getNetworkId(), candidate.mScanDetail);
return mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
index edbf956ace..3be642d651 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
@@ -34,6 +34,7 @@ import android.os.Handler;
import android.os.WorkSource;
import android.text.TextUtils;
import android.util.Log;
+import android.util.SparseArray;
import com.android.server.wifi.HalDeviceManager;
import com.android.server.wifi.PropertyService;
@@ -996,6 +997,18 @@ public class WifiP2pNative {
}
/**
+ * Returns whether P2P + P2P concurrency is supported or not.
+ */
+ public boolean isP2pP2pConcurrencySupported() {
+ synchronized (mLock) {
+ return mWifiVendorHal.canDeviceSupportCreateTypeCombo(
+ new SparseArray<Integer>() {{
+ put(HDM_CREATE_IFACE_P2P, 2);
+ }});
+ }
+ }
+
+ /**
* Configure the IP addresses in supplicant for P2P GO to provide the IP address to
* client in EAPOL handshake. Refer Wi-Fi P2P Technical Specification v1.7 - Section 4.2.8
* IP Address Allocation in EAPOL-Key Frames (4-Way Handshake) for more details.
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index e004bc4660..6fb46f4667 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -169,6 +169,7 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -342,7 +343,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// Messages for interaction with IpClient.
private static final int IPC_PRE_DHCP_ACTION = BASE + 30;
private static final int IPC_POST_DHCP_ACTION = BASE + 31;
- private static final int IPC_DHCP_RESULTS = BASE + 32;
+ @VisibleForTesting
+ static final int IPC_DHCP_RESULTS = BASE + 32;
private static final int IPC_PROVISIONING_SUCCESS = BASE + 33;
private static final int IPC_PROVISIONING_FAILURE = BASE + 34;
@VisibleForTesting
@@ -429,6 +431,16 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
private final Map<String, HashSet<ScanResult.InformationElement>> mVendorElements =
new HashMap<>();
+ // client(application) P2P group info list, key = package name
+ private final Map<String, WifiP2pGroupInfo> mOwnershipMap = new HashMap<>();
+
+ // Max number of P2P groups supported
+ private static final int MAX_NUM_GROUP = 1;
+ // Package name used to represent all shared connections
+ private static final String SHARED_PKG_NAME = "__SHARED_PACKAGE_NAME";
+ // Ongoing connection request package name with the default value set for shared connection
+ private String mConnectionPkgName = SHARED_PKG_NAME;
+
// peer authorizing timestamp which is indexed by the peer MAC address.
private final Map<String, Long> mPeerAuthorizingTimestamp = new HashMap<>();
@@ -463,6 +475,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
private final RemoteCallbackList<IWifiP2pListener> mWifiP2pListeners =
new RemoteCallbackList<>();
+ // clients(application) P2P listener map, key = package name
+ private final Map<String, IWifiP2pListener> mP2pListenerMap = new HashMap<>();
/**
* Error code definition.
@@ -581,6 +595,18 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
/**
+ * Stores P2P group information
+ */
+ private static class WifiP2pGroupInfo {
+ public WifiP2pGroup p2pGroup;
+ public WifiP2pInfo p2pInfo;
+ WifiP2pGroupInfo(WifiP2pGroup group, WifiP2pInfo info) {
+ p2pGroup = group;
+ p2pInfo = info;
+ }
+ }
+
+ /**
* Handles client connections
*/
private class ClientHandler extends Handler {
@@ -1052,6 +1078,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
AttributionSource source = mClientAttributionSource.remove(binder);
if (null != source) {
mVendorElements.remove(source.getPackageName());
+ mOwnershipMap.remove(source.getPackageName());
+ mP2pListenerMap.remove(source.getPackageName());
}
}
@@ -1070,6 +1098,24 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
}
+ /**
+ * Get WifiP2pGroupInfo owned by the provided package name
+ */
+ private WifiP2pGroupInfo getP2pGroupInfo(String packageName) {
+ if (mOwnershipMap.containsKey(packageName)) {
+ return mOwnershipMap.get(packageName);
+ } else if (mOwnershipMap.containsKey(SHARED_PKG_NAME)) {
+ return mOwnershipMap.get(SHARED_PKG_NAME);
+ }
+ return null;
+ }
+
+ private boolean checkIfPackageIsGroupOwner(String packageName) {
+ return !mFeatureFlags.p2pOwnership()
+ || mOwnershipMap.containsKey(packageName)
+ || mOwnershipMap.containsKey(SHARED_PKG_NAME);
+ }
+
/** This is used to provide information to drivers to optimize performance depending
* on the current mode of operation.
* 0 - disabled
@@ -1120,6 +1166,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
TAG + " registerWifiP2pListener");
Log.i(TAG, "registerWifiP2pListener uid=" + Binder.getCallingUid());
mWifiP2pListeners.register(listener);
+ mP2pListenerMap.put(packageName, listener);
}
/**
@@ -1133,6 +1180,15 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
Log.i(TAG, "unregisterWifiP2pListener uid=" + Binder.getCallingUid());
mWifiP2pListeners.unregister(listener);
+ Iterator<Map.Entry<String, IWifiP2pListener>> iterator =
+ mP2pListenerMap.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry<String, IWifiP2pListener> entry = iterator.next();
+ if (entry.getValue() == listener) {
+ iterator.remove();
+ break;
+ }
+ }
}
private void onP2pStateChanged(@WifiP2pManager.WifiP2pState int state) {
@@ -1243,53 +1299,57 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mWifiP2pListeners.finishBroadcast();
}
- private void onGroupCreated(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) {
- int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ private void onGroupCreated(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup,
+ RemoteCallbackList<IWifiP2pListener> callbackList) {
+ int numCallbacks = callbackList.beginBroadcast();
for (int i = 0; i < numCallbacks; i++) {
try {
- mWifiP2pListeners.getBroadcastItem(i).onGroupCreated(p2pInfo, p2pGroup);
+ callbackList.getBroadcastItem(i).onGroupCreated(p2pInfo, p2pGroup);
} catch (RemoteException e) {
Log.e(TAG, "Failure calling onGroupCreated" + e);
}
}
- mWifiP2pListeners.finishBroadcast();
+ callbackList.finishBroadcast();
}
- private void onPeerClientJoined(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) {
- int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ private void onPeerClientJoined(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup,
+ RemoteCallbackList<IWifiP2pListener> callbackList) {
+ int numCallbacks = callbackList.beginBroadcast();
for (int i = 0; i < numCallbacks; i++) {
try {
- mWifiP2pListeners.getBroadcastItem(i).onPeerClientJoined(p2pInfo, p2pGroup);
+ callbackList.getBroadcastItem(i).onPeerClientJoined(p2pInfo, p2pGroup);
} catch (RemoteException e) {
Log.e(TAG, "Failure calling onPeerClientJoined" + e);
}
}
- mWifiP2pListeners.finishBroadcast();
+ callbackList.finishBroadcast();
}
- private void onPeerClientDisconnected(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) {
- int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ private void onPeerClientDisconnected(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup,
+ RemoteCallbackList<IWifiP2pListener> callbackList) {
+ int numCallbacks = callbackList.beginBroadcast();
for (int i = 0; i < numCallbacks; i++) {
try {
- mWifiP2pListeners.getBroadcastItem(i).onPeerClientDisconnected(p2pInfo,
+ callbackList.getBroadcastItem(i).onPeerClientDisconnected(p2pInfo,
p2pGroup);
} catch (RemoteException e) {
Log.e(TAG, "Failure calling onPeerClientDisconnected" + e);
}
}
- mWifiP2pListeners.finishBroadcast();
+ callbackList.finishBroadcast();
}
- private void onFrequencyChanged(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup) {
- int numCallbacks = mWifiP2pListeners.beginBroadcast();
+ private void onFrequencyChanged(WifiP2pInfo p2pInfo, WifiP2pGroup p2pGroup,
+ RemoteCallbackList<IWifiP2pListener> callbackList) {
+ int numCallbacks = callbackList.beginBroadcast();
for (int i = 0; i < numCallbacks; i++) {
try {
- mWifiP2pListeners.getBroadcastItem(i).onFrequencyChanged(p2pInfo, p2pGroup);
+ callbackList.getBroadcastItem(i).onFrequencyChanged(p2pInfo, p2pGroup);
} catch (RemoteException e) {
Log.e(TAG, "Failure calling onFrequencyChanged" + e);
}
}
- mWifiP2pListeners.finishBroadcast();
+ callbackList.finishBroadcast();
}
private void onGroupRemoved() {
@@ -1311,6 +1371,12 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
!= PackageManager.PERMISSION_DENIED;
}
+ private boolean isDualP2pSupported() {
+ return mFeatureFlags.p2pDual()
+ && mFeatureFlags.p2pOwnership()
+ && mWifiNative.isP2pP2pConcurrencySupported();
+ }
+
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
@@ -1333,6 +1399,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
pw.println("mClientInfoList " + mClientInfoList.size());
pw.println("mActiveClients " + mActiveClients);
pw.println("mPeerAuthorizingTimestamp" + mPeerAuthorizingTimestamp);
+ pw.println("isDualP2pSupported" + isDualP2pSupported());
pw.println();
final IIpClient ipClient = mIpClient;
@@ -1376,6 +1443,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
new P2pEnabledState(mThreshold, mThreadLocalLog);
// Inactive is when p2p is enabled with no connectivity
private final InactiveState mInactiveState = new InactiveState(mThreshold, mThreadLocalLog);
+ // Idle is when p2p is enabled and there's no ongoing connection attempt
+ private final IdleState mIdleState = new IdleState(mThreshold, mThreadLocalLog);
private final GroupCreatingState mGroupCreatingState =
new GroupCreatingState(mThreshold, mThreadLocalLog);
private final UserAuthorizingInviteRequestState mUserAuthorizingInviteRequestState =
@@ -1469,6 +1538,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
addState(mWaitingState, mP2pDisabledContainerState);
addState(mP2pEnabledState, mDefaultState);
addState(mInactiveState, mP2pEnabledState);
+ addState(mIdleState, mP2pEnabledState);
addState(mGroupCreatingState, mP2pEnabledState);
addState(mUserAuthorizingInviteRequestState, mGroupCreatingState);
addState(mUserAuthorizingNegotiationRequestState, mGroupCreatingState);
@@ -1595,6 +1665,25 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
}
+ private RemoteCallbackList<IWifiP2pListener> generateCallbackList(WifiP2pGroup group) {
+ if (!mFeatureFlags.p2pOwnership() || mOwnershipMap.containsKey(SHARED_PKG_NAME)) {
+ return mWifiP2pListeners;
+ }
+
+ for (Map.Entry<String, WifiP2pGroupInfo> entry : mOwnershipMap.entrySet()) {
+ if (entry.getValue().p2pGroup.getInterface().equals(group.getInterface())) {
+ IWifiP2pListener p2pListener = mP2pListenerMap.get(entry.getKey());
+ RemoteCallbackList<IWifiP2pListener> listener = new RemoteCallbackList<>();
+ if (p2pListener != null) {
+ listener.register(p2pListener);
+ logd("WifiP2pListener callback generated for " + entry.getKey());
+ }
+ return listener;
+ }
+ }
+ return mWifiP2pListeners;
+ }
+
@Override
protected String getLogRecString(Message msg) {
StringBuilder sb = new StringBuilder();
@@ -2220,8 +2309,22 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
message.obj));
break;
case WifiP2pManager.REQUEST_CONNECTION_INFO:
- replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO,
- new WifiP2pInfo(mWifiP2pInfo));
+ if (mFeatureFlags.p2pOwnership()) {
+ String packageName = getCallingPkgName(
+ message.sendingUid, message.replyTo);
+ WifiP2pGroupInfo groupInfo = getP2pGroupInfo(packageName);
+ if (groupInfo != null) {
+ replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO,
+ new WifiP2pInfo(groupInfo.p2pInfo));
+ } else {
+ logd("No group owned by caller - returning empty info");
+ replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO,
+ new WifiP2pInfo());
+ }
+ } else {
+ replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO,
+ new WifiP2pInfo(mWifiP2pInfo));
+ }
break;
case WifiP2pManager.REQUEST_GROUP_INFO: {
String packageName = getCallingPkgName(message.sendingUid, message.replyTo);
@@ -2247,8 +2350,19 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// remain at this state.
break;
}
- replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO,
- maybeEraseOwnDeviceAddress(mGroup, message.sendingUid));
+ if (mFeatureFlags.p2pOwnership()) {
+ WifiP2pGroupInfo groupInfo = getP2pGroupInfo(packageName);
+ if (groupInfo != null) {
+ replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO,
+ maybeEraseOwnDeviceAddress(groupInfo.p2pGroup, uid));
+ } else {
+ logd("No group owned by caller - returning null group");
+ replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO, null);
+ }
+ } else {
+ replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO,
+ maybeEraseOwnDeviceAddress(mGroup, message.sendingUid));
+ }
break;
}
case WifiP2pManager.REQUEST_PERSISTENT_GROUP_INFO: {
@@ -2839,6 +2953,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
resetWifiP2pInfo();
mGroup = null;
+ mOwnershipMap.clear();
}
@Override
@@ -2963,7 +3078,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
} else if (proceedWithOperation
== InterfaceConflictManager.ICM_EXECUTE_COMMAND) {
if (setupInterface()) {
- smTransition(this, mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
}
} // else InterfaceConflictManager.ICM_SKIP_COMMAND_WAIT_FOR_USER: nop
break;
@@ -3041,7 +3160,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
== InterfaceConflictManager.ICM_EXECUTE_COMMAND) {
if (!setupInterface()) return NOT_HANDLED;
deferMessage(message);
- smTransition(this, mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
} // else InterfaceConflictManager.ICM_SKIP_COMMAND_WAIT_FOR_USER: nop
break;
}
@@ -3762,7 +3885,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
break;
}
mSavedPeerConfig = new WifiP2pConfig();
- mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
+ mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
mSavedPeerConfig.deviceAddress = device.deviceAddress;
mSavedPeerConfig.wps.pin = provDisc.pin;
if (SdkLevel.isAtLeastV() && provDisc.getVendorData() != null) {
@@ -4019,6 +4142,486 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
}
+ class IdleState extends RunnerState {
+
+ /**
+ * The Runner state Constructor
+ *
+ * @param threshold the running time threshold in milliseconds
+ */
+ IdleState(int threshold, @NonNull LocalLog localLog) {
+ super(threshold, localLog);
+ }
+
+ @Override
+ public void enterImpl() {
+ logSmStateName(this.getName(),
+ getCurrentState() != null ? getCurrentState().getName() : "");
+ mPeerAuthorizingTimestamp.clear();
+ mSavedPeerConfig.invalidate();
+ mDetailedState = NetworkInfo.DetailedState.IDLE;
+ mConnectionPkgName = SHARED_PKG_NAME;
+ scheduleIdleShutdown();
+ }
+
+ @Override
+ public void exitImpl() {
+ cancelIdleShutdown();
+ }
+
+ @Override
+ public boolean processMessageImpl(Message message) {
+ logSmMessage(getName(), message);
+ // Re-schedule the shutdown timer since we got the new operation.
+ // only handle commands from clients.
+ if (message.what > Protocol.BASE_WIFI_P2P_MANAGER
+ && message.what < Protocol.BASE_WIFI_P2P_SERVICE) {
+ scheduleIdleShutdown();
+ }
+ switch (message.what) {
+ case WifiP2pManager.CONNECT: {
+ String packageName = getCallingPkgName(message.sendingUid, message.replyTo);
+ if (packageName == null) {
+ replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
+ break;
+ }
+ int uid = message.sendingUid;
+ String attributionTag = getCallingFeatureId(uid, message.replyTo);
+ Bundle extras = message.getData()
+ .getBundle(WifiP2pManager.EXTRA_PARAM_KEY_BUNDLE);
+ boolean hasPermission = false;
+ if (isPlatformOrTargetSdkLessThanT(packageName, uid)) {
+ hasPermission = mWifiPermissionsUtil.checkCanAccessWifiDirect(
+ packageName,
+ attributionTag,
+ uid, false);
+ } else {
+ hasPermission = checkNearbyDevicesPermission(uid, packageName,
+ extras, "CONNECT", message.obj);
+ }
+ if (!hasPermission) {
+ replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
+ // remain at this state.
+ break;
+ }
+ mLastCallerInfoManager.put(WifiManager.API_P2P_CONNECT,
+ Process.myTid(), uid, 0, packageName, true);
+ if (mVerboseLoggingEnabled) logd(getName() + " sending connect");
+ WifiP2pConfig config = (WifiP2pConfig)
+ extras.getParcelable(WifiP2pManager.EXTRA_PARAM_KEY_CONFIG);
+
+ boolean isConnectFailed = false;
+ if (isConfigValidAsGroup(config)) {
+ mAutonomousGroup = false;
+ mWifiNative.p2pStopFind();
+ if (mVerboseLoggingEnabled) {
+ logd("FAST_CONNECTION GC band freq: " + getGroupOwnerBandToString(
+ config.groupOwnerBand));
+ }
+ if (mWifiNative.p2pGroupAdd(config, true)) {
+ reportConnectionEventTakeBugReportIfOverlapped(
+ P2pConnectionEvent.CONNECTION_FAST,
+ config, WifiMetricsProto.GroupEvent.GROUP_CLIENT, uid,
+ attributionTag);
+ mConnectionPkgName = packageName;
+ smTransition(this, mGroupNegotiationState);
+ } else {
+ loge("Cannot join a group with config.");
+ isConnectFailed = true;
+ replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
+ }
+ } else {
+ if (isConfigInvalid(config)) {
+ loge("Dropping connect request " + config);
+ isConnectFailed = true;
+ replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
+ } else {
+ mAutonomousGroup = false;
+ mWifiNative.p2pStopFind();
+ if (reinvokePersistentGroup(config, false)) {
+ mWifiP2pMetrics.startConnectionEvent(
+ P2pConnectionEvent.CONNECTION_REINVOKE,
+ config, GroupEvent.GROUP_UNKNOWN, uid, attributionTag);
+ smTransition(this, mGroupNegotiationState);
+ } else {
+ mWifiP2pMetrics.startConnectionEvent(
+ P2pConnectionEvent.CONNECTION_FRESH,
+ config, GroupEvent.GROUP_UNKNOWN, uid, attributionTag);
+ smTransition(this, mProvisionDiscoveryState);
+ }
+ }
+ }
+
+ if (!isConnectFailed) {
+ mSavedPeerConfig = config;
+ mPeers.updateStatus(mSavedPeerConfig.deviceAddress,
+ WifiP2pDevice.INVITED);
+ sendPeersChangedBroadcast();
+ replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
+ }
+ break;
+ }
+ case WifiP2pManager.STOP_DISCOVERY:
+ mLastCallerInfoManager.put(WifiManager.API_P2P_STOP_PEER_DISCOVERY,
+ Process.myTid(), message.sendingUid, 0,
+ getCallingPkgName(message.sendingUid, message.replyTo), true);
+ if (mWifiNative.p2pStopFind()) {
+ // When discovery stops in inactive state, flush to clear
+ // state peer data
+ mWifiNative.p2pFlush();
+ mServiceDiscReqId = null;
+ replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
+ } else {
+ replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
+ WifiP2pManager.ERROR);
+ }
+ break;
+ case CMD_P2P_IDLE_SHUTDOWN:
+ Log.d(TAG, "IdleShutDown message received");
+ sendMessage(DISABLE_P2P);
+ break;
+ case WifiP2pMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
+ WifiP2pConfig config = (WifiP2pConfig) message.obj;
+ if (isConfigInvalid(config)) {
+ loge("Dropping GO neg request " + config);
+ break;
+ }
+ mSavedPeerConfig = config;
+ mAutonomousGroup = false;
+ mJoinExistingGroup = false;
+ mWifiP2pMetrics.startConnectionEvent(
+ P2pConnectionEvent.CONNECTION_FRESH,
+ config, GroupEvent.GROUP_UNKNOWN, Process.SYSTEM_UID, null);
+ smTransition(this, mUserAuthorizingNegotiationRequestState);
+ break;
+ case WifiP2pMonitor.P2P_INVITATION_RECEIVED_EVENT:
+ if (message.obj == null) {
+ Log.e(TAG, "Invalid argument(s)");
+ break;
+ }
+ WifiP2pGroup group = (WifiP2pGroup) message.obj;
+ WifiP2pDevice owner = group.getOwner();
+ if (owner == null) {
+ int id = group.getNetworkId();
+ if (id < 0) {
+ loge("Ignored invitation from null owner");
+ break;
+ }
+
+ String addr = mGroups.getOwnerAddr(id);
+ if (addr != null) {
+ group.setOwner(new WifiP2pDevice(addr));
+ owner = group.getOwner();
+ } else {
+ loge("Ignored invitation from null owner");
+ break;
+ }
+ }
+ config = new WifiP2pConfig();
+ config.deviceAddress = group.getOwner().deviceAddress;
+ if (isConfigInvalid(config)) {
+ loge("Dropping invitation request " + config);
+ break;
+ }
+ mSavedPeerConfig = config;
+
+ // Check if we have the owner in peer list and use appropriate
+ // wps method. Default is to use PBC.
+ if (owner != null && ((owner = mPeers.get(owner.deviceAddress)) != null)) {
+ if (owner.wpsPbcSupported()) {
+ mSavedPeerConfig.wps.setup = WpsInfo.PBC;
+ } else if (owner.wpsKeypadSupported()) {
+ mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
+ } else if (owner.wpsDisplaySupported()) {
+ mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
+ }
+ }
+
+ mAutonomousGroup = false;
+ mJoinExistingGroup = true;
+ mWifiP2pMetrics.startConnectionEvent(
+ P2pConnectionEvent.CONNECTION_FRESH,
+ config, GroupEvent.GROUP_UNKNOWN, Process.SYSTEM_UID, null);
+ smTransition(this, mUserAuthorizingInviteRequestState);
+ break;
+ case WifiP2pMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
+ case WifiP2pMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
+ // We let the supplicant handle the provision discovery response
+ // and wait instead for the GO_NEGOTIATION_REQUEST_EVENT.
+ // Handling provision discovery and issuing a p2p_connect before
+ // group negotiation comes through causes issues
+ break;
+ case WifiP2pMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
+ if (message.obj == null) {
+ Log.e(TAG, "Illegal argument(s)");
+ break;
+ }
+ WifiP2pProvDiscEvent provDisc = (WifiP2pProvDiscEvent) message.obj;
+ WifiP2pDevice device = provDisc.device;
+ if (device == null) {
+ loge("Device entry is null");
+ break;
+ }
+ mSavedPeerConfig = new WifiP2pConfig();
+ mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
+ mSavedPeerConfig.deviceAddress = device.deviceAddress;
+ mSavedPeerConfig.wps.pin = provDisc.pin;
+ if (SdkLevel.isAtLeastV() && provDisc.getVendorData() != null) {
+ mSavedPeerConfig.setVendorData(provDisc.getVendorData());
+ }
+
+ notifyP2pProvDiscShowPinRequest(provDisc.pin, device.deviceAddress);
+ mPeers.updateStatus(device.deviceAddress, WifiP2pDevice.INVITED);
+ sendPeersChangedBroadcast();
+ smTransition(this, mUserAuthorizingNegotiationRequestState);
+ break;
+ case WifiP2pManager.CREATE_GROUP: {
+ String packageName = getCallingPkgName(message.sendingUid, message.replyTo);
+ if (packageName == null) {
+ replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
+ WifiP2pManager.ERROR);
+ break;
+ }
+ int uid = message.sendingUid;
+ String attributionTag = getCallingFeatureId(uid, message.replyTo);
+ Bundle extras = message.getData()
+ .getBundle(WifiP2pManager.EXTRA_PARAM_KEY_BUNDLE);
+ boolean hasPermission;
+ if (isPlatformOrTargetSdkLessThanT(packageName, uid)) {
+ hasPermission = mWifiPermissionsUtil.checkCanAccessWifiDirect(
+ packageName,
+ attributionTag,
+ uid, false);
+ } else {
+ hasPermission = checkNearbyDevicesPermission(uid, packageName,
+ extras, "CREATE_GROUP", message.obj);
+ }
+ if (!hasPermission) {
+ replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
+ WifiP2pManager.ERROR);
+ // remain at this state.
+ break;
+ }
+ mAutonomousGroup = true;
+ int netId = message.arg1;
+ config = extras.getParcelable(WifiP2pManager.EXTRA_PARAM_KEY_CONFIG);
+ mLastCallerInfoManager.put(config == null
+ ? WifiManager.API_P2P_CREATE_GROUP
+ : WifiManager.API_P2P_CREATE_GROUP_P2P_CONFIG,
+ Process.myTid(), uid, 0, packageName, true);
+ boolean ret = false;
+ if (config != null) {
+ if (isConfigValidAsGroup(config)) {
+ mConnectionPkgName = packageName;
+ if (mVerboseLoggingEnabled) {
+ logd("FAST_CONNECTION GO band freq: "
+ + getGroupOwnerBandToString(config.groupOwnerBand));
+ }
+ reportConnectionEventTakeBugReportIfOverlapped(
+ P2pConnectionEvent.CONNECTION_FAST,
+ config, GroupEvent.GROUP_OWNER, uid, attributionTag);
+ ret = mWifiNative.p2pGroupAdd(config, false);
+ }
+ } else if (netId == WifiP2pGroup.NETWORK_ID_PERSISTENT) {
+ // check if the go persistent group is present.
+ netId = mGroups.getNetworkId(mThisDevice.deviceAddress);
+ if (netId != -1) {
+ mWifiP2pMetrics.startConnectionEvent(
+ P2pConnectionEvent.CONNECTION_REINVOKE,
+ null, GroupEvent.GROUP_OWNER, uid, attributionTag);
+ ret = mWifiNative.p2pGroupAdd(netId);
+ } else {
+ mWifiP2pMetrics.startConnectionEvent(
+ P2pConnectionEvent.CONNECTION_LOCAL,
+ null, GroupEvent.GROUP_OWNER, uid, attributionTag);
+ ret = mWifiNative.p2pGroupAdd(true);
+ }
+ } else {
+ mWifiP2pMetrics.startConnectionEvent(
+ P2pConnectionEvent.CONNECTION_LOCAL,
+ null, GroupEvent.GROUP_OWNER, uid, attributionTag);
+ ret = mWifiNative.p2pGroupAdd(false);
+ }
+
+ if (ret) {
+ replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
+ smTransition(this, mGroupNegotiationState);
+ } else {
+ mConnectionPkgName = SHARED_PKG_NAME;
+ replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
+ WifiP2pManager.ERROR);
+ // remain at this state.
+ String errorMsg = "P2P group creating failed";
+ if (mVerboseLoggingEnabled) logd(getName() + errorMsg);
+ if (mWifiP2pMetrics.isP2pFastConnectionType()) {
+ takeBugReportP2pFailureIfNeeded("Wi-Fi BugReport (P2P "
+ + mWifiP2pMetrics.getP2pGroupRoleString()
+ + " creation failure)", errorMsg);
+ }
+ mWifiP2pMetrics.endConnectionEvent(
+ P2pConnectionEvent.CLF_CREATE_GROUP_FAILED);
+ }
+ break;
+ }
+ case WifiP2pMonitor.P2P_GROUP_STARTED_EVENT:
+ if (message.obj == null) {
+ Log.e(TAG, "Invalid argument(s)");
+ break;
+ }
+ mGroup = (WifiP2pGroup) message.obj;
+ if (mVerboseLoggingEnabled) logd(getName() + " group started");
+ if (mGroup.isGroupOwner()
+ && EMPTY_DEVICE_ADDRESS.equals(mGroup.getOwner().deviceAddress)) {
+ // wpa_supplicant doesn't set own device address to go_dev_addr.
+ mGroup.getOwner().deviceAddress = mThisDevice.deviceAddress;
+ }
+ // We hit this scenario when a persistent group is reinvoked
+ if (mGroup.getNetworkId() == WifiP2pGroup.NETWORK_ID_PERSISTENT) {
+ mAutonomousGroup = false;
+ deferMessage(message);
+ smTransition(this, mGroupNegotiationState);
+ } else {
+ loge("Unexpected group creation, remove " + mGroup);
+ mWifiNative.p2pGroupRemove(mGroup.getInterface());
+ mGroup = null;
+ }
+ break;
+ case WifiP2pManager.START_LISTEN:
+ String packageName = getCallingPkgName(message.sendingUid, message.replyTo);
+ if (packageName == null) {
+ replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED);
+ break;
+ }
+ int uid = message.sendingUid;
+ int listenType = message.arg1;
+ if (listenType == WifiP2pManager.WIFI_P2P_EXT_LISTEN_WITH_PARAMS
+ && !SdkLevel.isAtLeastV()) {
+ replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED);
+ break;
+ }
+ Bundle extras = message.getData()
+ .getBundle(WifiP2pManager.EXTRA_PARAM_KEY_BUNDLE);
+ WifiP2pExtListenParams extListenParams = SdkLevel.isAtLeastV()
+ && (listenType == WifiP2pManager.WIFI_P2P_EXT_LISTEN_WITH_PARAMS)
+ ? extras.getParcelable(
+ WifiP2pManager.EXTRA_PARAM_KEY_EXT_LISTEN_PARAMS,
+ WifiP2pExtListenParams.class)
+ : null;
+ boolean hasPermission;
+ if (isPlatformOrTargetSdkLessThanT(packageName, uid)) {
+ hasPermission = mWifiPermissionsUtil.checkCanAccessWifiDirect(
+ packageName,
+ getCallingFeatureId(message.sendingUid, message.replyTo),
+ uid, true);
+ } else {
+ hasPermission = checkNearbyDevicesPermission(uid, packageName,
+ extras, "START_LISTEN", message.obj);
+ }
+ if (!hasPermission) {
+ replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED);
+ break;
+ }
+ mLastCallerInfoManager.put(WifiManager.API_P2P_START_LISTENING,
+ Process.myTid(), uid, 0, packageName, true);
+ if (mVerboseLoggingEnabled) logd(getName() + " start listen mode");
+ mWifiNative.p2pStopFind();
+ if (mWifiNative.p2pExtListen(true,
+ mContext.getResources().getInteger(
+ R.integer.config_wifiP2pExtListenPeriodMs),
+ mContext.getResources().getInteger(
+ R.integer.config_wifiP2pExtListenIntervalMs),
+ extListenParams)) {
+ replyToMessage(message, WifiP2pManager.START_LISTEN_SUCCEEDED);
+ sendP2pListenChangedBroadcast(true);
+ } else {
+ replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED);
+ }
+ break;
+ case WifiP2pManager.STOP_LISTEN:
+ mLastCallerInfoManager.put(WifiManager.API_P2P_STOP_LISTENING,
+ Process.myTid(), message.sendingUid, 0,
+ getCallingPkgName(message.sendingUid, message.replyTo), true);
+ if (mVerboseLoggingEnabled) logd(getName() + " stop listen mode");
+ if (mWifiNative.p2pExtListen(false, 0, 0, null)) {
+ replyToMessage(message, WifiP2pManager.STOP_LISTEN_SUCCEEDED);
+ sendP2pListenChangedBroadcast(false);
+ } else {
+ replyToMessage(message, WifiP2pManager.STOP_LISTEN_FAILED);
+ }
+ mWifiNative.p2pStopFind();
+ break;
+ case WifiP2pManager.SET_CHANNEL:
+ if (!checkNetworkSettingsOrNetworkStackOrOverrideWifiConfigPermission(
+ message.sendingUid)) {
+ loge("Permission violation - none of NETWORK_SETTING, NETWORK_STACK,"
+ + " or OVERRIDE_WIFI_CONFIG permission, uid = "
+ + message.sendingUid);
+ replyToMessage(message, WifiP2pManager.SET_CHANNEL_FAILED,
+ WifiP2pManager.ERROR);
+ break;
+ }
+ if (message.obj == null) {
+ Log.e(TAG, "Illegal arguments(s)");
+ break;
+ }
+ mLastCallerInfoManager.put(WifiManager.API_P2P_SET_CHANNELS,
+ Process.myTid(), message.sendingUid, 0,
+ getCallingPkgName(message.sendingUid, message.replyTo), true);
+ Bundle p2pChannels = (Bundle) message.obj;
+ mUserListenChannel = p2pChannels.getInt("lc", 0);
+ mUserOperatingChannel = p2pChannels.getInt("oc", 0);
+ if (updateP2pChannels()) {
+ replyToMessage(message, WifiP2pManager.SET_CHANNEL_SUCCEEDED);
+ } else {
+ replyToMessage(message, WifiP2pManager.SET_CHANNEL_FAILED);
+ }
+ break;
+ case WifiP2pManager.INITIATOR_REPORT_NFC_HANDOVER:
+ String handoverSelect = null;
+
+ if (message.obj != null) {
+ handoverSelect = ((Bundle) message.obj)
+ .getString(WifiP2pManager.EXTRA_HANDOVER_MESSAGE);
+ }
+
+ if (handoverSelect != null
+ && mWifiNative.initiatorReportNfcHandover(handoverSelect)) {
+ replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_SUCCEEDED);
+ smTransition(this, mGroupCreatingState);
+ } else {
+ replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_FAILED);
+ }
+ break;
+ case WifiP2pManager.RESPONDER_REPORT_NFC_HANDOVER:
+ String handoverRequest = null;
+
+ if (message.obj != null) {
+ handoverRequest = ((Bundle) message.obj)
+ .getString(WifiP2pManager.EXTRA_HANDOVER_MESSAGE);
+ }
+
+ if (handoverRequest != null
+ && mWifiNative.responderReportNfcHandover(handoverRequest)) {
+ replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_SUCCEEDED);
+ smTransition(this, mGroupCreatingState);
+ } else {
+ replyToMessage(message, WifiP2pManager.REPORT_NFC_HANDOVER_FAILED);
+ }
+ break;
+ default:
+ return NOT_HANDLED;
+ }
+ return HANDLED;
+ }
+
+ @Override
+ public String getMessageLogRec(int what) {
+ return P2pStateMachine.class.getSimpleName() + "."
+ + this.getClass().getSimpleName()
+ + "." + getWhatToString(what);
+ }
+ }
+
class P2pRejectWaitState extends RunnerState {
/**
@@ -4058,7 +4661,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
WifiP2pManager.CANCEL_CONNECT_SUCCEEDED);
}
}
- transitionTo(mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
} else {
loge(
"Stale P2p rejection resume after delay - cached index: "
@@ -4128,7 +4735,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
P2pConnectionEvent.CLF_TIMEOUT);
handleGroupCreationFailure(
WifiP2pManager.GROUP_CREATION_FAILURE_REASON_TIMED_OUT);
- smTransition(this, mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
}
break;
case WifiP2pMonitor.P2P_DEVICE_LOST_EVENT:
@@ -4180,6 +4791,16 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// discovery or for a pending user action, but at the framework
// level, we always treat cancel as succeeded and enter
// an inactive state
+ String packageName = getCallingPkgName(message.sendingUid, message.replyTo);
+ if (mFeatureFlags.p2pOwnership()
+ && mConnectionPkgName != packageName
+ && mConnectionPkgName != SHARED_PKG_NAME) {
+ replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
+ WifiP2pManager.BUSY);
+ logd("Cancel connect requested by " + packageName
+ + " when connection is initiated by " + mConnectionPkgName);
+ break;
+ }
mLastCallerInfoManager.put(WifiManager.API_P2P_CANCEL_CONNECT,
Process.myTid(), message.sendingUid, 0,
getCallingPkgName(message.sendingUid, message.replyTo), true);
@@ -4290,7 +4911,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mWifiNative.p2pCancelConnect();
handleGroupCreationFailure(
WifiP2pManager.GROUP_CREATION_FAILURE_REASON_USER_REJECTED);
- smTransition(this, mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
}
break;
case PEER_CONNECTION_USER_CONFIRM:
@@ -4304,7 +4929,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
loge("provision discovery failed status: " + message.arg1);
handleGroupCreationFailure(WifiP2pManager
.GROUP_CREATION_FAILURE_REASON_PROVISION_DISCOVERY_FAILED);
- smTransition(this, mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
break;
case WifiP2pManager.SET_CONNECTION_REQUEST_RESULT: {
if (!handleSetConnectionResult(message,
@@ -4384,13 +5013,21 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
if (mVerboseLoggingEnabled) {
logd("User rejected invitation " + mSavedPeerConfig);
}
- smTransition(this, mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
break;
case WifiP2pMonitor.P2P_PROV_DISC_FAILURE_EVENT:
loge("provision discovery failed status: " + message.arg1);
handleGroupCreationFailure(WifiP2pManager
.GROUP_CREATION_FAILURE_REASON_PROVISION_DISCOVERY_FAILED);
- smTransition(this, mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
break;
case WifiP2pManager.SET_CONNECTION_REQUEST_RESULT:
if (!handleSetConnectionResult(message,
@@ -4547,7 +5184,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
P2pConnectionEvent.CLF_PROV_DISC_FAIL);
handleGroupCreationFailure(WifiP2pManager
.GROUP_CREATION_FAILURE_REASON_PROVISION_DISCOVERY_FAILED);
- smTransition(this, mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
break;
default:
return NOT_HANDLED;
@@ -4618,7 +5259,6 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mGroup.setNetworkId(mGroups.getNetworkId(devAddr,
mGroup.getNetworkName()));
}
-
if (mGroup.isGroupOwner()) {
// Setting an idle time out on GO causes issues with certain scenarios
// on clients where it can be off-channel for longer and with the power
@@ -4648,7 +5288,12 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
}
break;
}
-
+ if (mOwnershipMap.size() >= MAX_NUM_GROUP) {
+ Log.wtf(TAG, "group size= " + mOwnershipMap.size()
+ + " exceeds max number of p2p group supported");
+ }
+ mOwnershipMap.put(
+ mConnectionPkgName, new WifiP2pGroupInfo(mGroup, null));
mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
Log.d(TAG, "start Ip client with provisioning mode: "
+ mSavedPeerConfig.getGroupClientIpProvisioningMode());
@@ -4687,6 +5332,15 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
if (!interfaces.contains(mGroup.getInterface())) break;
Log.d(TAG, "tether " + mGroup.getInterface() + " ready");
+ if (mOwnershipMap.size() > MAX_NUM_GROUP) {
+ Log.wtf(TAG, "group size= " + mOwnershipMap.size()
+ + " exceeds max number of p2p group supported");
+ }
+ WifiP2pGroupInfo groupInfo = mOwnershipMap.putIfAbsent(mConnectionPkgName,
+ new WifiP2pGroupInfo(mGroup, null));
+ if (groupInfo != null) {
+ groupInfo.p2pGroup = mGroup;
+ }
smTransition(this, mGroupCreatedState);
break;
case WifiP2pMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
@@ -4708,7 +5362,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
P2pConnectionEvent.CLF_GROUP_REMOVED);
handleGroupCreationFailure(
WifiP2pManager.GROUP_CREATION_FAILURE_REASON_GROUP_REMOVED);
- smTransition(this, mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
break;
case WifiP2pMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
// A group formation failure is always followed by
@@ -4780,7 +5438,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
P2pConnectionEvent.CLF_INVITATION_FAIL);
handleGroupCreationFailure(
WifiP2pManager.GROUP_CREATION_FAILURE_REASON_INVITATION_FAILED);
- smTransition(this, mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
}
break;
case WifiP2pMonitor.P2P_PROV_DISC_FAILURE_EVENT:
@@ -4789,7 +5451,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
P2pConnectionEvent.CLF_GROUP_REMOVED);
handleGroupCreationFailure(WifiP2pManager
.GROUP_CREATION_FAILURE_REASON_PROVISION_DISCOVERY_FAILED);
- smTransition(this, mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
break;
case WifiP2pMonitor.AP_STA_CONNECTED_EVENT:
case WifiP2pMonitor.AP_STA_DISCONNECTED_EVENT:
@@ -4940,7 +5606,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
P2pConnectionEvent.CLF_USER_REJECT);
handleGroupCreationFailure(
WifiP2pManager.GROUP_CREATION_FAILURE_REASON_USER_REJECTED);
- smTransition(this, mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
break;
case DROP_WIFI_USER_ACCEPT:
mFrequencyConflictDialog = null;
@@ -4953,7 +5623,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
if (mVerboseLoggingEnabled) {
logd(getName() + "Wifi disconnected, retry p2p");
}
- smTransition(this, mInactiveState);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
p2pReconnect();
break;
default:
@@ -5015,7 +5689,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// In case of a negotiation group, connection changed is sent
// after a client joins. For autonomous, send now
if (mAutonomousGroup) {
- onGroupCreated(new WifiP2pInfo(mWifiP2pInfo), eraseOwnDeviceAddress(mGroup));
+ onGroupCreated(new WifiP2pInfo(mWifiP2pInfo), eraseOwnDeviceAddress(mGroup),
+ generateCallbackList(mGroup));
sendP2pConnectionChangedBroadcast();
}
@@ -5060,8 +5735,14 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
} else {
loge("Connect on null device address, ignore");
}
+ if (!mAutonomousGroup && mGroup.getClientList().size() == 1) {
+ onGroupCreated(new WifiP2pInfo(mWifiP2pInfo),
+ eraseOwnDeviceAddress(mGroup),
+ generateCallbackList(mGroup));
+ }
onPeerClientJoined(new WifiP2pInfo(mWifiP2pInfo),
- eraseOwnDeviceAddress(mGroup));
+ eraseOwnDeviceAddress(mGroup),
+ generateCallbackList(mGroup));
sendP2pConnectionChangedBroadcast();
break;
}
@@ -5085,7 +5766,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// when this happens at exit()
} else {
onPeerClientDisconnected(new WifiP2pInfo(mWifiP2pInfo),
- eraseOwnDeviceAddress(mGroup));
+ eraseOwnDeviceAddress(mGroup),
+ generateCallbackList(mGroup));
// Notify when a client disconnects from group
sendP2pConnectionChangedBroadcast();
}
@@ -5176,7 +5858,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
loge("Failed to add iface to local network " + e);
}
onGroupCreated(new WifiP2pInfo(mWifiP2pInfo),
- eraseOwnDeviceAddress(mGroup));
+ eraseOwnDeviceAddress(mGroup),
+ generateCallbackList(mGroup));
sendP2pConnectionChangedBroadcast();
break;
case IPC_PROVISIONING_SUCCESS:
@@ -5202,7 +5885,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
if (goInterfaceMacAddress == null) {
setWifiP2pInfoOnGroupFormationWithInetAddress(null);
onGroupCreated(new WifiP2pInfo(mWifiP2pInfo),
- eraseOwnDeviceAddress(mGroup));
+ eraseOwnDeviceAddress(mGroup),
+ generateCallbackList(mGroup));
sendP2pConnectionChangedBroadcast();
break;
}
@@ -5214,7 +5898,8 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
NetworkInterface.getByName(mGroup.getInterface()));
setWifiP2pInfoOnGroupFormationWithInetAddress(goIp);
onGroupCreated(new WifiP2pInfo(mWifiP2pInfo),
- eraseOwnDeviceAddress(mGroup));
+ eraseOwnDeviceAddress(mGroup),
+ generateCallbackList(mGroup));
sendP2pConnectionChangedBroadcast();
} catch (UnknownHostException | SocketException e) {
loge("Unable to retrieve link-local IPv6 address of group owner "
@@ -5226,21 +5911,32 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
loge("IP provisioning failed");
mWifiNative.p2pGroupRemove(mGroup.getInterface());
break;
- case WifiP2pManager.REMOVE_GROUP:
+ case WifiP2pManager.REMOVE_GROUP: {
+ String packageName = getCallingPkgName(message.sendingUid, message.replyTo);
+ if (!checkIfPackageIsGroupOwner(packageName)
+ && message.sendingUid != Process.SYSTEM_UID) {
+ replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
+ WifiP2pManager.BUSY);
+ break;
+ }
mLastCallerInfoManager.put(WifiManager.API_P2P_REMOVE_GROUP,
- Process.myTid(), message.sendingUid, 0,
- getCallingPkgName(message.sendingUid, message.replyTo), true);
+ Process.myTid(), message.sendingUid, 0, packageName, true);
if (mVerboseLoggingEnabled) logd(getName() + " remove group");
if (mWifiNative.p2pGroupRemove(mGroup.getInterface())) {
smTransition(this, mOngoingGroupRemovalState);
replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
} else {
- handleGroupRemoved();
- smTransition(this, mInactiveState);
+ handleGroupRemoved(packageName);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
WifiP2pManager.ERROR);
}
break;
+ }
case WifiP2pMonitor.P2P_GROUP_REMOVED_EVENT:
// We do not listen to NETWORK_DISCONNECTION_EVENT for group removal
// handling since supplicant actually tries to reconnect after a temporary
@@ -5253,8 +5949,26 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// Treating network disconnection as group removal causes race conditions
// since supplicant would still maintain the group at that stage.
if (mVerboseLoggingEnabled) logd(getName() + " group removed");
- handleGroupRemoved();
- smTransition(this, mInactiveState);
+
+ if (message.obj == null) {
+ Log.e(TAG, "Illegal arguments");
+ break;
+ }
+ String pkgName = SHARED_PKG_NAME;
+ WifiP2pGroup group = (WifiP2pGroup) message.obj;
+ for (Map.Entry<String, WifiP2pGroupInfo> entry : mOwnershipMap.entrySet()) {
+ if (entry.getValue().p2pGroup.getInterface().equals(
+ group.getInterface())) {
+ pkgName = entry.getKey();
+ break;
+ }
+ }
+ handleGroupRemoved(pkgName);
+ if (mFeatureFlags.p2pOwnership()) {
+ smTransition(this, mIdleState);
+ } else {
+ smTransition(this, mInactiveState);
+ }
break;
case WifiP2pMonitor.P2P_DEVICE_LOST_EVENT:
if (message.obj == null) {
@@ -5328,6 +6042,12 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
// remain at this state.
break;
}
+ if (!checkIfPackageIsGroupOwner(packageName)) {
+ replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
+ WifiP2pManager.BUSY);
+ logd("Cannot perform invitation connection due to lack of ownership");
+ break;
+ }
mLastCallerInfoManager.put(WifiManager.API_P2P_CONNECT,
Process.myTid(), uid, 0, packageName, true);
WifiP2pConfig config = (WifiP2pConfig)
@@ -5343,6 +6063,9 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED);
sendPeersChangedBroadcast();
replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
+ if (mOwnershipMap.containsKey(packageName)) {
+ mConnectionPkgName = packageName;
+ }
} else {
replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
WifiP2pManager.ERROR);
@@ -5418,7 +6141,17 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
case WifiP2pMonitor.P2P_GROUP_STARTED_EVENT:
loge("Duplicate group creation event notice, ignore");
break;
- case WifiP2pManager.CANCEL_CONNECT:
+ case WifiP2pManager.CANCEL_CONNECT: {
+ String packageName = getCallingPkgName(message.sendingUid, message.replyTo);
+ if (mFeatureFlags.p2pOwnership()
+ && mConnectionPkgName != packageName
+ && mConnectionPkgName != SHARED_PKG_NAME) {
+ replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
+ WifiP2pManager.BUSY);
+ logd("Cancel invitation connect requested by " + packageName
+ + " when connection is initiated by " + mConnectionPkgName);
+ break;
+ }
mLastCallerInfoManager.put(WifiManager.API_P2P_CANCEL_CONNECT,
Process.myTid(), message.sendingUid, 0,
getCallingPkgName(message.sendingUid, message.replyTo), true);
@@ -5438,11 +6171,13 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_SUCCEEDED);
break;
+ }
case WifiP2pMonitor.P2P_FREQUENCY_CHANGED_EVENT:
if (mGroup != null) {
mGroup.setFrequency(message.arg1);
onFrequencyChanged(new WifiP2pInfo(mWifiP2pInfo),
- eraseOwnDeviceAddress(mGroup));
+ eraseOwnDeviceAddress(mGroup),
+ generateCallbackList(mGroup));
sendP2pConnectionChangedBroadcast();
}
break;
@@ -5560,7 +6295,6 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
break;
case PEER_CONNECTION_USER_REJECT:
if (mVerboseLoggingEnabled) logd("User rejected incoming request");
- mSavedPeerConfig.invalidate();
smTransition(this, mGroupCreatedState);
break;
case WifiP2pManager.SET_CONNECTION_REQUEST_RESULT:
@@ -5765,6 +6499,12 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
broadcastOptions.setRequireNoneOfPermissions(excludedPermissionsList.toArray(
new String[0]));
}
+ // remove package name from intent for ownership
+ if (mFeatureFlags.p2pOwnership()
+ && intent.getAction().equals(
+ WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
+ intent = getP2pConnectionChangedIntent(true);
+ }
context.sendBroadcast(intent, null, broadcastOptions.toBundle());
}
}
@@ -5789,18 +6529,25 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
sendBroadcastWithExcludedPermissions(intent, null);
}
- private Intent getP2pConnectionChangedIntent() {
+ private Intent getP2pConnectionChangedIntent(boolean tethering) {
Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, new WifiP2pInfo(mWifiP2pInfo));
intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, makeNetworkInfo());
intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP, eraseOwnDeviceAddress(mGroup));
+ if (tethering || !mFeatureFlags.p2pOwnership()) return intent;
+ if (!mOwnershipMap.containsKey(SHARED_PKG_NAME)) {
+ for (String pkg : mOwnershipMap.keySet()) {
+ intent.setPackage(pkg);
+ logd("sending p2p connection changed broadcast to only " + pkg);
+ }
+ }
return intent;
}
private void sendP2pConnectionChangedBroadcast() {
if (mVerboseLoggingEnabled) logd("sending p2p connection changed broadcast");
- Intent intent = getP2pConnectionChangedIntent();
+ Intent intent = getP2pConnectionChangedIntent(false);
if (SdkLevel.isAtLeastU()) {
// First send direct foreground broadcast to Tethering package and system service
// with same android.permission.MAINLINE_NETWORK_STACK
@@ -5907,7 +6654,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
if (TextUtils.isEmpty(tetheringServicePackage)) return false;
Log.i(TAG, "sending p2p tether request broadcast to " + tetheringServicePackage
+ " with permission " + Arrays.toString(permissions));
- Intent intent = getP2pConnectionChangedIntent();
+ Intent intent = getP2pConnectionChangedIntent(true);
if (setAdditionalFlags) {
intent.addFlags(flags);
}
@@ -5919,7 +6666,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
private void sendBroadcastWithMainlineNetworkStackPermissionPostU() {
String[] receiverPermissions = RECEIVER_PERMISSIONS_MAINLINE_NETWORK_STACK;
- Intent intent = getP2pConnectionChangedIntent();
+ Intent intent = getP2pConnectionChangedIntent(true);
// Adding the flag to allow recipient to run at foreground priority with a shorter
// timeout interval.
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
@@ -6697,6 +7444,11 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mWifiP2pInfo.groupFormed = true;
mWifiP2pInfo.isGroupOwner = mGroup.isGroupOwner();
mWifiP2pInfo.groupOwnerAddress = serverAddress;
+ WifiP2pGroupInfo groupInfo = mOwnershipMap.putIfAbsent(
+ mConnectionPkgName, new WifiP2pGroupInfo(null, mWifiP2pInfo));
+ if (groupInfo != null) {
+ groupInfo.p2pInfo = mWifiP2pInfo;
+ }
}
private void resetWifiP2pInfo() {
@@ -6893,7 +7645,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
mWifiNative.setDeviceName(mThisDevice.deviceName);
// DIRECT-XY-DEVICENAME (XY is randomly generated)
- mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
+ mWifiNative.setP2pSsidPostfix(generateP2pSsidPostfix(mThisDevice.deviceName));
mWifiNative.setP2pDeviceType(mThisDevice.primaryDeviceType);
// Supplicant defaults to using virtual display with display
// which refers to a remote display. Use physical_display
@@ -6991,7 +7743,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
sendDisconnectWifiRequest(false);
}
- private void handleGroupRemoved() {
+ private void handleGroupRemoved(String packageName) {
if (mGroup.isGroupOwner()) {
// {@link com.android.server.connectivity.Tethering} listens to
// {@link WifiP2pManager#WIFI_P2P_CONNECTION_CHANGED_ACTION}
@@ -7029,6 +7781,12 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
sendPeersChangedBroadcast();
}
+ if (mOwnershipMap.containsKey(packageName)) {
+ mOwnershipMap.remove(packageName);
+ } else {
+ mOwnershipMap.remove(SHARED_PKG_NAME);
+ }
+
mGroup = null;
mPeersLostDuringConnection.clear();
mServiceDiscReqId = null;
@@ -7739,7 +8497,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
if (WifiP2pManager.CONNECTION_REQUEST_ACCEPT == message.arg1) {
if (WifiP2pManager.ExternalApproverRequestListener.REQUEST_TYPE_NEGOTIATION
== requestType
- && WpsInfo.KEYPAD == mSavedPeerConfig.wps.setup) {
+ && WpsInfo.DISPLAY == mSavedPeerConfig.wps.setup) {
sendMessage(PEER_CONNECTION_USER_CONFIRM);
} else {
Bundle extras = message.getData().getBundle(
diff --git a/service/java/com/android/server/wifi/scanner/WifiScannerInternal.java b/service/java/com/android/server/wifi/scanner/WifiScannerInternal.java
index 862b4cbdab..713edd792e 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScannerInternal.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScannerInternal.java
@@ -93,6 +93,12 @@ public abstract class WifiScannerInternal {
}
@Override
+ public void onFullResults(List<ScanResult> fullScanResult) {
+ mWifiThreadRunner.post(() -> fullScanResult.forEach(mScanListener::onFullResult),
+ TAG + "#onFullResults");
+ }
+
+ @Override
public void onSingleScanCompleted() {
// Internal scan listener doesn't need to handle this.
}
diff --git a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
index 2c07b4cc5a..120de838d6 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
@@ -528,12 +528,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
return;
}
mWifiThreadRunner.post(() -> {
- ExternalClientInfo client = (ExternalClientInfo) mClients.get(listener);
- if (client == null) {
- Log.e(TAG, "listener not found " + listener);
- return;
- }
- localLog("stop pno scan: " + client + " AttributionTag " + featureId);
+ localLog("stop pno scan: " + packageName + " AttributionTag " + featureId);
Message msg = Message.obtain();
msg.what = WifiScanner.CMD_STOP_PNO_SCAN;
msg.obj = new ScanParams(listener, null, null);
@@ -653,7 +648,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
private static final int BASE = Protocol.BASE_WIFI_SCANNER_SERVICE;
private static final int CMD_SCAN_RESULTS_AVAILABLE = BASE + 0;
- private static final int CMD_FULL_SCAN_RESULTS = BASE + 1;
+ private static final int CMD_FULL_SCAN_SINGLE_RESULT = BASE + 1;
+ private static final int CMD_FULL_SCAN_ALL_RESULTS = BASE + 2;
private static final int CMD_SCAN_PAUSED = BASE + 8;
private static final int CMD_SCAN_RESTARTED = BASE + 9;
private static final int CMD_SCAN_FAILED = BASE + 10;
@@ -1029,6 +1025,16 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
public void onScanRequestFailed(int errorCode) {
reportScanStatusForImpl(mImplIfaceName, STATUS_FAILED, errorCode);
}
+
+ @Override
+ public void onFullScanResults(List<ScanResult> fullScanResults,
+ int bucketsScanned) {
+ if (DBG) localLog("onFullScanResults received on iface " + mImplIfaceName);
+ if (fullScanResults == null || fullScanResults.isEmpty()) {
+ return;
+ }
+ reportFullScanResultsForImpl(mImplIfaceName, fullScanResults, bucketsScanned);
+ }
}
private static final int STATUS_PENDING = 0;
@@ -1086,7 +1092,15 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
ScanResult fullScanResult, int bucketsScanned) {
Integer status = mStatusPerImpl.get(implIfaceName);
if (status != null && status == STATUS_PENDING) {
- sendMessage(CMD_FULL_SCAN_RESULTS, 0, bucketsScanned, fullScanResult);
+ sendMessage(CMD_FULL_SCAN_SINGLE_RESULT, 0, bucketsScanned, fullScanResult);
+ }
+ }
+
+ private void reportFullScanResultsForImpl(@NonNull String implIfaceName,
+ List<ScanResult> fullScanResults, int bucketsScanned) {
+ Integer status = mStatusPerImpl.get(implIfaceName);
+ if (status != null && status == STATUS_PENDING) {
+ sendMessage(CMD_FULL_SCAN_ALL_RESULTS, 0, bucketsScanned, fullScanResults);
}
}
@@ -1223,7 +1237,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
case CMD_SCAN_RESULTS_AVAILABLE:
if (DBG) localLog("ignored scan results available event");
return HANDLED;
- case CMD_FULL_SCAN_RESULTS:
+ case CMD_FULL_SCAN_SINGLE_RESULT:
+ case CMD_FULL_SCAN_ALL_RESULTS:
if (DBG) localLog("ignored full scan result event");
return HANDLED;
case WifiScanner.CMD_GET_SINGLE_SCAN_RESULTS:
@@ -1324,8 +1339,13 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
transitionTo(mIdleState);
return HANDLED;
- case CMD_FULL_SCAN_RESULTS:
- reportFullScanResult((ScanResult) msg.obj, /* bucketsScanned */ msg.arg2);
+ case CMD_FULL_SCAN_SINGLE_RESULT:
+ reportFullScanSingleResult((ScanResult) msg.obj,
+ /* bucketsScanned */ msg.arg2);
+ return HANDLED;
+ case CMD_FULL_SCAN_ALL_RESULTS:
+ reportFullScanAllResults((List<ScanResult>) msg.obj,
+ /* bucketsScanned */ msg.arg2);
return HANDLED;
case CMD_SCAN_FAILED:
mWifiMetrics.incrementScanReturnEntry(
@@ -1595,7 +1615,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
clientHandlers.clear();
}
- void reportFullScanResult(@NonNull ScanResult result, int bucketsScanned) {
+ void reportFullScanSingleResult(@NonNull ScanResult result, int bucketsScanned) {
for (RequestInfo<ScanSettings> entry : mActiveScans) {
if (ScanScheduleUtil.shouldReportFullScanResultForSettings(mChannelHelper,
result, bucketsScanned, entry.settings, -1)) {
@@ -1620,6 +1640,36 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
}
+ void reportFullScanAllResults(@NonNull List<ScanResult> results, int bucketsScanned) {
+ List<ScanResult> matchedScanResults = new ArrayList<>(results.size());
+ for (RequestInfo<ScanSettings> entry : mActiveScans) {
+ for (ScanResult result : results) {
+ if (ScanScheduleUtil.shouldReportFullScanResultForSettings(mChannelHelper,
+ result, bucketsScanned, entry.settings, -1)) {
+ matchedScanResults.add(result);
+ }
+ }
+ entry.clientInfo.reportEvent((listener) -> {
+ try {
+ listener.onFullResults(new ArrayList<>(matchedScanResults));
+ } catch (RemoteException e) {
+ loge("Failed to call onFullResult: " + entry.clientInfo);
+ }
+ });
+ matchedScanResults.clear();
+ }
+
+ for (RequestInfo<Void> entry : mSingleScanListeners) {
+ entry.clientInfo.reportEvent((listener) -> {
+ try {
+ listener.onFullResults(results);
+ } catch (RemoteException e) {
+ loge("Failed to call onFullResult: " + entry.clientInfo);
+ }
+ });
+ }
+ }
+
void reportScanResults(@NonNull ScanData results) {
if (results != null && results.getResults() != null) {
if (results.getResults().length > 0) {
@@ -1772,7 +1822,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
@Override
public void onFullScanResult(ScanResult fullScanResult, int bucketsScanned) {
if (DBG) localLog("onFullScanResult received");
- sendMessage(CMD_FULL_SCAN_RESULTS, 0, bucketsScanned, fullScanResult);
+ sendMessage(CMD_FULL_SCAN_SINGLE_RESULT, 0, bucketsScanned, fullScanResult);
}
@Override
@@ -1794,6 +1844,16 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
public void onScanRequestFailed(int errorCode) {
sendMessage(CMD_SCAN_FAILED, errorCode);
}
+
+ @Override
+ public void onFullScanResults(List<ScanResult> fullScanResults, int bucketsScanned) {
+ if (DBG) localLog("onFullScanResult received");
+ if (fullScanResults == null || fullScanResults.isEmpty()) {
+ return;
+ }
+ sendMessage(CMD_FULL_SCAN_ALL_RESULTS, 0, bucketsScanned, fullScanResults);
+
+ }
}
class DefaultState extends State {
@@ -1858,8 +1918,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
case CMD_SCAN_RESULTS_AVAILABLE:
if (DBG) localLog("ignored scan results available event");
break;
-
- case CMD_FULL_SCAN_RESULTS:
+ case CMD_FULL_SCAN_SINGLE_RESULT:
+ case CMD_FULL_SCAN_ALL_RESULTS:
if (DBG) localLog("ignored full scan result event");
break;
@@ -1935,8 +1995,13 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
results != null ? results.length : 0);
reportScanResults(results);
break;
- case CMD_FULL_SCAN_RESULTS:
- reportFullScanResult((ScanResult) msg.obj, /* bucketsScanned */ msg.arg2);
+ case CMD_FULL_SCAN_SINGLE_RESULT:
+ reportFullScanSingleResult((ScanResult) msg.obj,
+ /* bucketsScanned */ msg.arg2);
+ break;
+ case CMD_FULL_SCAN_ALL_RESULTS:
+ reportFullScanAllResults((List<ScanResult>) msg.obj,
+ /* bucketsScanned */ msg.arg2);
break;
case CMD_SCAN_PAUSED:
reportScanResults((ScanData[]) msg.obj);
@@ -2112,7 +2177,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
}
- private void reportFullScanResult(ScanResult result, int bucketsScanned) {
+ private void reportFullScanSingleResult(ScanResult result, int bucketsScanned) {
for (RequestInfo<ScanSettings> entry : mActiveBackgroundScans) {
ClientInfo ci = entry.clientInfo;
ScanSettings settings = entry.settings;
@@ -2136,6 +2201,40 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
}
+ private void reportFullScanAllResults(List<ScanResult> results, int bucketsScanned) {
+ List<ScanResult> copyResults = new ArrayList<>(results.size());
+ for (ScanResult result : results) {
+ ScanResult newResult = new ScanResult(result);
+ if (result.informationElements != null) {
+ newResult.informationElements = result.informationElements.clone();
+ } else {
+ newResult.informationElements = null;
+ }
+ copyResults.add(newResult);
+ }
+ List<ScanResult> matchedResults = new ArrayList<>(copyResults.size());
+ for (RequestInfo<ScanSettings> entry : mActiveBackgroundScans) {
+ ClientInfo ci = entry.clientInfo;
+ ScanSettings settings = entry.settings;
+
+ for (ScanResult result : results) {
+ if (mBackgroundScheduler.shouldReportFullScanResultForSettings(
+ result, bucketsScanned, settings)) {
+
+ matchedResults.add(result);
+ }
+ entry.clientInfo.reportEvent((listener) -> {
+ try {
+ listener.onFullResults(new ArrayList<>(matchedResults));
+ } catch (RemoteException e) {
+ loge("Failed to call onFullResult: " + ci);
+ }
+ });
+ }
+ matchedResults.clear();
+ }
+ }
+
private void reportScanResults(ScanData[] results) {
if (results == null) {
Log.d(TAG,"The results is null, nothing to report.");
@@ -3277,33 +3376,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
}
- private static class InternalListener extends IWifiScannerListener.Stub {
- InternalListener() {
- }
-
- @Override
- public void onSuccess() {
- }
-
- @Override
- public void onFailure(int reason, String description) {
- }
-
- @Override
- public void onResults(WifiScanner.ScanData[] results) {
- }
-
- @Override
- public void onFullResult(ScanResult fullScanResult) {
- }
-
- @Override
- public void onSingleScanCompleted() {
- }
-
- @Override
- public void onPnoNetworkFound(ScanResult[] results) {
- }
+ private static class InternalListener extends IWifiScannerListener.Default {
}
private class LocalService extends WifiScannerInternal {
diff --git a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java
index 1fec135396..5f87b76596 100644
--- a/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java
@@ -422,12 +422,10 @@ public class WificondScannerImpl extends WifiScannerImpl implements Handler.Call
if (mLastScanSettings.singleScanEventHandler != null) {
if (mLastScanSettings.reportSingleScanFullResults) {
- for (ScanResult scanResult : singleScanResults) {
- // ignore buckets scanned since there is only one bucket for a single scan
- mLastScanSettings.singleScanEventHandler.onFullScanResult(scanResult,
- /* bucketsScanned */ 0);
- }
+ mLastScanSettings.singleScanEventHandler
+ .onFullScanResults(singleScanResults, 0);
}
+
Collections.sort(singleScanResults, SCAN_RESULT_SORT_COMPARATOR);
mLatestSingleScanResult = new WifiScanner.ScanData(0, 0, 0,
getScannedBandsInternal(mLastScanSettings.singleScanFreqs),
diff --git a/service/java/com/android/server/wifi/util/ApConfigUtil.java b/service/java/com/android/server/wifi/util/ApConfigUtil.java
index bbc8d4b5e3..3da0bf1586 100644
--- a/service/java/com/android/server/wifi/util/ApConfigUtil.java
+++ b/service/java/com/android/server/wifi/util/ApConfigUtil.java
@@ -28,14 +28,14 @@ import static android.net.wifi.SoftApCapability.SOFTAP_FEATURE_MAC_ADDRESS_CUSTO
import static android.net.wifi.SoftApCapability.SOFTAP_FEATURE_WPA3_OWE;
import static android.net.wifi.SoftApCapability.SOFTAP_FEATURE_WPA3_OWE_TRANSITION;
import static android.net.wifi.SoftApCapability.SOFTAP_FEATURE_WPA3_SAE;
+import static android.net.wifi.SoftApConfiguration.BAND_2GHZ;
+import static android.net.wifi.SoftApConfiguration.BAND_5GHZ;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDGE;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_STA;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.Resources;
import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.ScanResult;
import android.net.wifi.SoftApCapability;
@@ -45,9 +45,11 @@ import android.net.wifi.SoftApInfo;
import android.net.wifi.WifiAvailableChannel;
import android.net.wifi.WifiClient;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.nl80211.DeviceWiphyCapabilities;
+import android.net.wifi.util.WifiResourceCache;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
@@ -241,7 +243,7 @@ public class ApConfigUtil {
* @return The band includes 2.4Ghz when 2.4G SoftAp supported.
*/
public static @BandType int append24GToBandIf24GSupported(@BandType int targetBand,
- Context context) {
+ WifiContext context) {
if (isBandSupported(SoftApConfiguration.BAND_2GHZ, context)) {
return targetBand | SoftApConfiguration.BAND_2GHZ;
}
@@ -255,7 +257,7 @@ public class ApConfigUtil {
* @return The band includes 5Ghz when 5G SoftAp supported.
*/
public static @BandType int append5GToBandIf5GSupported(@BandType int targetBand,
- Context context) {
+ WifiContext context) {
if (isBandSupported(SoftApConfiguration.BAND_5GHZ, context)) {
return targetBand | SoftApConfiguration.BAND_5GHZ;
}
@@ -298,7 +300,7 @@ public class ApConfigUtil {
* @param context the caller context used to get value from resource file.
* @return true if band is supported, false otherwise
*/
- public static boolean isBandSupported(@BandType int apBand, Context context) {
+ public static boolean isBandSupported(@BandType int apBand, WifiContext context) {
if (!isBandValid(apBand)) {
Log.e(TAG, "Invalid SoftAp band " + apBand);
return false;
@@ -377,7 +379,8 @@ public class ApConfigUtil {
return unsafeFreqs;
}
- private static List<Integer> getConfiguredChannelList(Resources resources, @BandType int band) {
+ private static List<Integer> getConfiguredChannelList(WifiResourceCache resources,
+ @BandType int band) {
switch (band) {
case SoftApConfiguration.BAND_2GHZ:
return convertStringToChannelList(resources.getString(
@@ -397,8 +400,8 @@ public class ApConfigUtil {
}
private static List<Integer> addDfsChannelsIfNeeded(List<Integer> regulatoryList,
- @WifiScanner.WifiBand int scannerBand, WifiNative wifiNative, Resources resources,
- boolean inFrequencyMHz) {
+ @WifiScanner.WifiBand int scannerBand, WifiNative wifiNative,
+ WifiResourceCache resources, boolean inFrequencyMHz) {
// Add DFS channels to the supported channel list if the device supports SoftAp
// operation in the DFS channel.
if (resources.getBoolean(R.bool.config_wifiSoftapAcsIncludeDfs)
@@ -417,8 +420,8 @@ public class ApConfigUtil {
}
private static List<Integer> getWifiCondAvailableChannelsForBand(
- @WifiScanner.WifiBand int scannerBand, WifiNative wifiNative, Resources resources,
- boolean inFrequencyMHz) {
+ @WifiScanner.WifiBand int scannerBand, WifiNative wifiNative,
+ WifiResourceCache resources, boolean inFrequencyMHz) {
List<Integer> regulatoryList = new ArrayList<Integer>();
// Get the allowed list of channel frequencies in MHz from wificond
int[] regulatoryArray = wifiNative.getChannelsForBand(scannerBand);
@@ -431,7 +434,8 @@ public class ApConfigUtil {
}
private static List<Integer> getHalAvailableChannelsForBand(
- @WifiScanner.WifiBand int scannerBand, WifiNative wifiNative, Resources resources,
+ @WifiScanner.WifiBand int scannerBand, WifiNative wifiNative,
+ WifiResourceCache resources,
boolean inFrequencyMHz) {
// Try vendor HAL API to get the usable channel list.
List<WifiAvailableChannel> usableChannelList = wifiNative.getUsableChannels(
@@ -465,7 +469,7 @@ public class ApConfigUtil {
* @return A list of frequencies that are allowed, null on error.
*/
public static List<Integer> getAvailableChannelFreqsForBand(
- @BandType int band, WifiNative wifiNative, Resources resources,
+ @BandType int band, WifiNative wifiNative, WifiResourceCache resources,
boolean inFrequencyMHz) {
if (!isBandValid(band) || isMultiband(band)) {
return null;
@@ -527,7 +531,7 @@ public class ApConfigUtil {
* @return a valid channel frequency on success, -1 on failure.
*/
public static int chooseApChannel(int apBand, @NonNull CoexManager coexManager,
- @NonNull Resources resources, SoftApCapability capability) {
+ @NonNull WifiResourceCache resources, SoftApCapability capability) {
if (!isBandValid(apBand)) {
Log.e(TAG, "Invalid band: " + apBand);
return -1;
@@ -645,7 +649,7 @@ public class ApConfigUtil {
*/
public static SoftApConfiguration removeUnavailableBandsFromConfig(
SoftApConfiguration config, SoftApCapability capability, CoexManager coexManager,
- @NonNull Context context) {
+ @NonNull WifiContext context) {
SoftApConfiguration.Builder builder = new SoftApConfiguration.Builder(config);
try {
@@ -694,6 +698,58 @@ public class ApConfigUtil {
}
/**
+ * Upgrades a single band config to 2 + 5 GHz dual band if the overlay is configured and
+ * there are no non-2GHz/5GHz bands that are configured and available with the current
+ * capabilities.
+ * </p>
+ * This is intended for configurations that were previously set with single band in a different
+ * country code that didn't support 2 + 5 GHz dual band, but the current country code does
+ * support 2 + 5 GHz dual band.
+ */
+ public static SoftApConfiguration upgradeTo2g5gBridgedIfAvailableBandsAreSubset(
+ SoftApConfiguration config, SoftApCapability capability, @NonNull WifiContext context) {
+ // DBS requires SdkLevel S or above.
+ if (!SdkLevel.isAtLeastS()) {
+ return config;
+ }
+
+ // Skip if overlay isn't set.
+ if (!context.getResourceCache().getBoolean(
+ R.bool.config_wifiSoftapUpgradeTetheredTo2g5gBridgedIfBandsAreSubset)) {
+ return config;
+ }
+
+ // Skip if config is already multi-band.
+ if (config.getBands().length != 1) {
+ return config;
+ }
+
+ // Skip if 2 or 5 GHz aren't supported.
+ if (capability.getSupportedChannelList(BAND_2GHZ).length == 0
+ || capability.getSupportedChannelList(BAND_5GHZ).length == 0) {
+ return config;
+ }
+
+ // Skip if any non-2GHz/5GHz band is specified and supported.
+ int configuredBand = config.getBand();
+ for (int band : SoftApConfiguration.BAND_TYPES) {
+ if (band == BAND_2GHZ || band == BAND_5GHZ) {
+ continue;
+ }
+ if ((configuredBand & band) != 0
+ && capability.getSupportedChannelList(band).length > 0) {
+ return config;
+ }
+ }
+
+ Log.i(TAG, "Temporarily upgrading config with band " + config.getBands()[0]
+ + " to 2 + 5GHz bridged.");
+ return new SoftApConfiguration.Builder(config)
+ .setBands(new int[]{BAND_2GHZ, BAND_2GHZ | BAND_5GHZ})
+ .build();
+ }
+
+ /**
* Remove all unsupported bands from the input band and return the resulting
* (remaining) support bands. Unsupported bands are those which don't have channels available.
*
@@ -703,7 +759,7 @@ public class ApConfigUtil {
* @return the available band which removed the unsupported band.
* 0 when all of the band is not supported.
*/
- public static @BandType int removeUnsupportedBands(Context context,
+ public static @BandType int removeUnsupportedBands(WifiContext context,
@NonNull int band) {
int availableBand = band;
for (int b : SoftApConfiguration.BAND_TYPES) {
@@ -747,8 +803,8 @@ public class ApConfigUtil {
* @return true if HAL support to map WPA3 transition mode to WPA3 in 6GHz band,
* false otherwise.
*/
- public static boolean canHALConvertRestrictedSecurityTypeFor6GHz(@NonNull Resources resources,
- @SoftApConfiguration.SecurityType int type) {
+ public static boolean canHALConvertRestrictedSecurityTypeFor6GHz(
+ @NonNull WifiResourceCache resources, @SoftApConfiguration.SecurityType int type) {
return type == SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION
&& resources.getBoolean(R.bool
.config_wifiSofapHalMapWpa3TransitionModeToWpa3OnlyIn6GHzBand);
@@ -765,7 +821,7 @@ public class ApConfigUtil {
* @return the updated SoftApConfiguration.
*/
public static SoftApConfiguration remove6gBandForUnsupportedSecurity(
- @NonNull Resources resources,
+ @NonNull WifiResourceCache resources,
SoftApConfiguration config, boolean isBridgedMode) {
SoftApConfiguration.Builder builder = new SoftApConfiguration.Builder(config);
@@ -842,7 +898,7 @@ public class ApConfigUtil {
* @return true if IEEE80211BE is allowed for the given configuration, false otherwise.
*/
public static boolean is11beAllowedForThisConfiguration(DeviceWiphyCapabilities capabilities,
- @NonNull Context context,
+ @NonNull WifiContext context,
SoftApConfiguration config,
boolean isBridgedMode) {
if (!ApConfigUtil.isIeee80211beSupported(context)) {
@@ -853,7 +909,7 @@ public class ApConfigUtil {
return false;
}
if (isBridgedMode
- && !context.getResources().getBoolean(
+ && !context.getResourceCache().getBoolean(
R.bool.config_wifiSoftApSingleLinkMloInBridgedModeSupported)) {
return false;
}
@@ -876,7 +932,7 @@ public class ApConfigUtil {
*/
public static @SoftApManager.StartResult int updateApChannelConfig(WifiNative wifiNative,
@NonNull CoexManager coexManager,
- Resources resources,
+ WifiResourceCache resources,
String countryCode,
SoftApConfiguration.Builder configBuilder,
SoftApConfiguration config,
@@ -988,7 +1044,7 @@ public class ApConfigUtil {
* @return SoftApCapability which updated the feature support or not from resource.
*/
@NonNull
- public static SoftApCapability updateCapabilityFromResource(@NonNull Context context) {
+ public static SoftApCapability updateCapabilityFromResource(@NonNull WifiContext context) {
long features = 0;
if (isAcsSupported(context)) {
Log.d(TAG, "Update Softap capability, add acs feature support");
@@ -1051,7 +1107,7 @@ public class ApConfigUtil {
}
SoftApCapability capability = new SoftApCapability(features);
- int hardwareSupportedMaxClient = context.getResources().getInteger(
+ int hardwareSupportedMaxClient = context.getResourceCache().getInteger(
R.integer.config_wifiHardwareSoftapMaxClientCount);
if (hardwareSupportedMaxClient > 0) {
Log.d(TAG, "Update Softap capability, max client = " + hardwareSupportedMaxClient);
@@ -1088,8 +1144,8 @@ public class ApConfigUtil {
* @param context the caller context used to get value from resource file.
* @return true if supported, false otherwise.
*/
- public static boolean isIeee80211axSupported(@NonNull Context context) {
- return context.getResources().getBoolean(
+ public static boolean isIeee80211axSupported(@NonNull WifiContext context) {
+ return context.getResourceCache().getBoolean(
R.bool.config_wifiSoftapIeee80211axSupported);
}
@@ -1099,8 +1155,8 @@ public class ApConfigUtil {
* @param context the caller context used to get value from resource file.
* @return true if supported, false otherwise.
*/
- public static boolean isIeee80211beSupported(@NonNull Context context) {
- return context.getResources().getBoolean(
+ public static boolean isIeee80211beSupported(@NonNull WifiContext context) {
+ return context.getResourceCache().getBoolean(
R.bool.config_wifiSoftapIeee80211beSupported);
}
@@ -1122,8 +1178,8 @@ public class ApConfigUtil {
* @param context the caller context used to get value from resource file.
* @return true if supported, false otherwise.
*/
- public static boolean isApMacRandomizationSupported(@NonNull Context context) {
- return context.getResources().getBoolean(
+ public static boolean isApMacRandomizationSupported(@NonNull WifiContext context) {
+ return context.getResourceCache().getBoolean(
R.bool.config_wifi_ap_mac_randomization_supported);
}
@@ -1135,8 +1191,8 @@ public class ApConfigUtil {
* @return true if supported, false otherwise.
*/
public static boolean isBridgedModeSupported(
- @NonNull Context context, @NonNull WifiNative wifiNative) {
- return SdkLevel.isAtLeastS() && context.getResources().getBoolean(
+ @NonNull WifiContext context, @NonNull WifiNative wifiNative) {
+ return SdkLevel.isAtLeastS() && context.getResourceCache().getBoolean(
R.bool.config_wifiBridgedSoftApSupported)
&& wifiNative.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
put(HDM_CREATE_IFACE_AP_BRIDGE, 1);
@@ -1150,8 +1206,8 @@ public class ApConfigUtil {
* @param context the caller context used to get value from resource file.
* @return true if supported, false otherwise.
*/
- public static boolean isBridgedModeSupportedInConfig(@NonNull Context context) {
- return SdkLevel.isAtLeastS() && context.getResources().getBoolean(
+ public static boolean isBridgedModeSupportedInConfig(@NonNull WifiContext context) {
+ return SdkLevel.isAtLeastS() && context.getResourceCache().getBoolean(
R.bool.config_wifiBridgedSoftApSupported);
}
@@ -1164,8 +1220,8 @@ public class ApConfigUtil {
* @return true if supported, false otherwise.
*/
public static boolean isStaWithBridgedModeSupported(
- @NonNull Context context, @NonNull WifiNative wifiNative) {
- return SdkLevel.isAtLeastS() && context.getResources().getBoolean(
+ @NonNull WifiContext context, @NonNull WifiNative wifiNative) {
+ return SdkLevel.isAtLeastS() && context.getResourceCache().getBoolean(
R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported)
&& wifiNative.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{
put(HDM_CREATE_IFACE_AP_BRIDGE, 1);
@@ -1179,8 +1235,8 @@ public class ApConfigUtil {
* @param context the caller context used to get value from resource file.
* @return true if supported, false otherwise.
*/
- public static boolean isClientForceDisconnectSupported(@NonNull Context context) {
- return context.getResources().getBoolean(
+ public static boolean isClientForceDisconnectSupported(@NonNull WifiContext context) {
+ return context.getResourceCache().getBoolean(
R.bool.config_wifiSofapClientForceDisconnectSupported);
}
@@ -1190,8 +1246,8 @@ public class ApConfigUtil {
* @param context the caller context used to get value from resource file.
* @return true if supported, false otherwise.
*/
- public static boolean isWpa3SaeSupported(@NonNull Context context) {
- return context.getResources().getBoolean(
+ public static boolean isWpa3SaeSupported(@NonNull WifiContext context) {
+ return context.getResourceCache().getBoolean(
R.bool.config_wifi_softap_sae_supported);
}
@@ -1201,8 +1257,8 @@ public class ApConfigUtil {
* @param context the caller context used to get value from resource file.
* @return true if supported, false otherwise.
*/
- public static boolean isAcsSupported(@NonNull Context context) {
- return context.getResources().getBoolean(
+ public static boolean isAcsSupported(@NonNull WifiContext context) {
+ return context.getResourceCache().getBoolean(
R.bool.config_wifi_softap_acs_supported);
}
@@ -1212,8 +1268,8 @@ public class ApConfigUtil {
* @param context the caller context used to get value from resource file.
* @return true if supported, false otherwise.
*/
- public static boolean isMacCustomizationSupported(@NonNull Context context) {
- return context.getResources().getBoolean(
+ public static boolean isMacCustomizationSupported(@NonNull WifiContext context) {
+ return context.getResourceCache().getBoolean(
R.bool.config_wifiSoftapMacAddressCustomizationSupported);
}
@@ -1224,23 +1280,25 @@ public class ApConfigUtil {
* @param band the band soft AP to operate on.
* @return true if supported, false otherwise.
*/
- public static boolean isSoftApBandSupported(@NonNull Context context, @BandType int band) {
+ public static boolean isSoftApBandSupported(@NonNull WifiContext context,
+ @BandType int band) {
+
switch (band) {
case SoftApConfiguration.BAND_2GHZ:
- return context.getResources().getBoolean(R.bool.config_wifi24ghzSupport)
- && context.getResources().getBoolean(
+ return context.getResourceCache().getBoolean(R.bool.config_wifi24ghzSupport)
+ && context.getResourceCache().getBoolean(
R.bool.config_wifiSoftap24ghzSupported);
case SoftApConfiguration.BAND_5GHZ:
- return context.getResources().getBoolean(R.bool.config_wifi5ghzSupport)
- && context.getResources().getBoolean(
+ return context.getResourceCache().getBoolean(R.bool.config_wifi5ghzSupport)
+ && context.getResourceCache().getBoolean(
R.bool.config_wifiSoftap5ghzSupported);
case SoftApConfiguration.BAND_6GHZ:
- return context.getResources().getBoolean(R.bool.config_wifi6ghzSupport)
- && context.getResources().getBoolean(
+ return context.getResourceCache().getBoolean(R.bool.config_wifi6ghzSupport)
+ && context.getResourceCache().getBoolean(
R.bool.config_wifiSoftap6ghzSupported);
case SoftApConfiguration.BAND_60GHZ:
- return context.getResources().getBoolean(R.bool.config_wifi60ghzSupport)
- && context.getResources().getBoolean(
+ return context.getResourceCache().getBoolean(R.bool.config_wifi60ghzSupport)
+ && context.getResourceCache().getBoolean(
R.bool.config_wifiSoftap60ghzSupported);
default:
return false;
@@ -1254,8 +1312,8 @@ public class ApConfigUtil {
* @param context the caller context used to get value from resource file.
* @return true if supported, false otherwise.
*/
- public static boolean isSoftApDynamicCountryCodeSupported(@NonNull Context context) {
- return context.getResources().getBoolean(
+ public static boolean isSoftApDynamicCountryCodeSupported(@NonNull WifiContext context) {
+ return context.getResourceCache().getBoolean(
R.bool.config_wifiSoftApDynamicCountryCodeUpdateSupported);
}
@@ -1266,8 +1324,9 @@ public class ApConfigUtil {
* @param context the caller context used to get value from resource file.
* @return true if supported, false otherwise.
*/
- public static boolean isSoftApRestartRequiredWhenCountryCodeChanged(@NonNull Context context) {
- return context.getResources().getBoolean(
+ public static boolean isSoftApRestartRequiredWhenCountryCodeChanged(
+ @NonNull WifiContext context) {
+ return context.getResourceCache().getBoolean(
R.bool.config_wifiForcedSoftApRestartWhenCountryCodeChanged);
}
@@ -1277,8 +1336,8 @@ public class ApConfigUtil {
* @param context the caller context used to get value from resource file.
* @return true if supported, false otherwise.
*/
- public static boolean isOweTransitionSupported(@NonNull Context context) {
- return context.getResources().getBoolean(
+ public static boolean isOweTransitionSupported(@NonNull WifiContext context) {
+ return context.getResourceCache().getBoolean(
R.bool.config_wifiSoftapOweTransitionSupported);
}
@@ -1288,8 +1347,8 @@ public class ApConfigUtil {
* @param context the caller context used to get value from resource file.
* @return true if supported, false otherwise.
*/
- public static boolean isOweSupported(@NonNull Context context) {
- return context.getResources().getBoolean(
+ public static boolean isOweSupported(@NonNull WifiContext context) {
+ return context.getResourceCache().getBoolean(
R.bool.config_wifiSoftapOweSupported);
}
@@ -1420,7 +1479,7 @@ public class ApConfigUtil {
*
* @return true when freq ranges is needed, otherwise false.
*/
- public static boolean isSendFreqRangesNeeded(@BandType int band, Context context,
+ public static boolean isSendFreqRangesNeeded(@BandType int band, WifiContext context,
SoftApConfiguration config) {
// Fist we check if one of the selected bands has restrictions in the overlay file or in the
// provided SoftApConfiguration.
@@ -1429,7 +1488,8 @@ public class ApConfigUtil {
// - If there is no restrictions on channels, we store the full band
for (int b : SoftApConfiguration.BAND_TYPES) {
if ((band & b) != 0) {
- List<Integer> configuredList = getConfiguredChannelList(context.getResources(), b);
+ List<Integer> configuredList = getConfiguredChannelList(
+ context.getResourceCache(), b);
if (configuredList != null && !configuredList.isEmpty()) {
// If any of the selected band has restriction in the overlay file return true.
return true;
@@ -1602,7 +1662,7 @@ public class ApConfigUtil {
* @return updated soft AP capability
*/
public static SoftApCapability updateSoftApCapabilityWithAvailableChannelList(
- @NonNull SoftApCapability softApCapability, @NonNull Context context,
+ @NonNull SoftApCapability softApCapability, @NonNull WifiContext context,
@NonNull WifiNative wifiNative, @NonNull SparseArray<int[]> channelMap) {
SoftApCapability newSoftApCapability = new SoftApCapability(softApCapability);
if (channelMap != null) {
@@ -1621,7 +1681,7 @@ public class ApConfigUtil {
for (int band : SoftApConfiguration.BAND_TYPES) {
if (isSoftApBandSupported(context, band)) {
supportedChannelList = getAvailableChannelFreqsForBand(
- band, wifiNative, context.getResources(), false);
+ band, wifiNative, context.getResourceCache(), false);
if (supportedChannelList != null) {
newSoftApCapability.setSupportedChannelList(
band,
diff --git a/service/java/com/android/server/wifi/util/GeneralUtil.java b/service/java/com/android/server/wifi/util/GeneralUtil.java
index 80d745cc93..7040d814e3 100644
--- a/service/java/com/android/server/wifi/util/GeneralUtil.java
+++ b/service/java/com/android/server/wifi/util/GeneralUtil.java
@@ -16,6 +16,8 @@
package com.android.server.wifi.util;
+import java.util.BitSet;
+
/**
* Class for general helper methods and objects for Wifi Framework code.
* @hide
@@ -40,4 +42,37 @@ public class GeneralUtil {
this.value = value;
}
}
+
+ /**
+ * Convert a capability bitmask to its index in a BitSet.
+ *
+ * TODO: Remove this method once the WifiManager capabilities are
+ * represented as indexes rather than bitmasks.
+ */
+ public static int getCapabilityIndex(long capability) {
+ // Index of the first enabled bit is the number of trailing zeroes
+ // in the binary representation
+ return Long.numberOfTrailingZeros(capability);
+ }
+
+ /**
+ * Convert a long to a BitSet.
+ *
+ * See TODO in {@link #getCapabilityIndex(long)}.
+ */
+ public static BitSet longToBitset(long longValue) {
+ return BitSet.valueOf(new long[]{longValue});
+ }
+
+ /**
+ * Convert a BitSet to a long.
+ *
+ * See TODO in {@link #getCapabilityIndex(long)}.
+ */
+ public static long bitsetToLong(BitSet bitset) {
+ if (bitset == null || bitset.cardinality() == 0) {
+ return 0L;
+ }
+ return bitset.toLongArray()[0];
+ }
}
diff --git a/service/java/com/android/server/wifi/util/InformationElementUtil.java b/service/java/com/android/server/wifi/util/InformationElementUtil.java
index 57643b9c01..ea499578df 100644
--- a/service/java/com/android/server/wifi/util/InformationElementUtil.java
+++ b/service/java/com/android/server/wifi/util/InformationElementUtil.java
@@ -1859,6 +1859,8 @@ public class InformationElementUtil {
private static final int WPS_VENDOR_OUI_TYPE = 0x04f25000;
private static final short WPA_VENDOR_OUI_VERSION = 0x0001;
private static final int OWE_VENDOR_OUI_TYPE = 0x1c9a6f50;
+ private static final int RSNE_OVERRIDE_VENDOR_OUI_TYPE = 0x299a6f50;
+ private static final int RSNE_OVERRIDE2_VENDOR_OUI_TYPE = 0x2A9a6f50;
private static final short RSNE_VERSION = 0x0001;
private static final int WPA_AKM_EAP = 0x01f25000;
@@ -1910,10 +1912,25 @@ public class InformationElementUtil {
public boolean isWPS;
public boolean isManagementFrameProtectionRequired;
public boolean isManagementFrameProtectionCapable;
+ private boolean mHasPmfRequiredBitSetToFalseOccurred;
+ public boolean isRSNEOverrideElementPresent;
public Capabilities() {
}
+ private static boolean isRsneOverrideElement(InformationElement ie) {
+ ByteBuffer buf = ByteBuffer.wrap(ie.bytes).order(ByteOrder.LITTLE_ENDIAN);
+ try {
+ int vendorOuiType = buf.getInt();
+ // Wi-Fi Alliance specific OUI and OUI type identifying RSNE Override element.
+ return (vendorOuiType == RSNE_OVERRIDE_VENDOR_OUI_TYPE
+ || vendorOuiType == RSNE_OVERRIDE2_VENDOR_OUI_TYPE);
+ } catch (BufferUnderflowException e) {
+ Log.e("IE_Capabilities", "Couldn't parse VSA IE, buffer underflow");
+ return false;
+ }
+ }
+
// RSNE format (size unit: byte)
//
// | Element ID | Length | Version | Group Data Cipher Suite |
@@ -1927,8 +1944,7 @@ public class InformationElementUtil {
//
// Note: InformationElement.bytes has 'Element ID' and 'Length'
// stripped off already
- private void parseRsnElement(InformationElement ie, SparseIntArray unknownAkmMap) {
- ByteBuffer buf = ByteBuffer.wrap(ie.bytes).order(ByteOrder.LITTLE_ENDIAN);
+ private void parseRsnElement(ByteBuffer buf, SparseIntArray unknownAkmMap) {
try {
// version
@@ -2027,9 +2043,17 @@ public class InformationElementUtil {
// see section 9.4.2.25 - RSNE - In IEEE Std 802.11-2016
if (buf.remaining() < 2) return;
int rsnCaps = buf.getShort();
- isManagementFrameProtectionRequired =
- 0 != (RSN_CAP_MANAGEMENT_FRAME_PROTECTION_REQUIRED & rsnCaps);
- isManagementFrameProtectionCapable =
+ // This method gets called multiple times if the AP and STA supports RSN overriding.
+ // The PMF required bit should be set to false if one of the RSN fields PMF
+ // required bit is ever false. The PMF capable bit should be set to true if one of
+ // the RSN fields PMF capable bit is ever true.
+ if ((RSN_CAP_MANAGEMENT_FRAME_PROTECTION_REQUIRED & rsnCaps) == 0) {
+ mHasPmfRequiredBitSetToFalseOccurred = true;
+ isManagementFrameProtectionRequired = false;
+ } else if (!mHasPmfRequiredBitSetToFalseOccurred) {
+ isManagementFrameProtectionRequired = true;
+ }
+ isManagementFrameProtectionCapable |=
0 != (RSN_CAP_MANAGEMENT_FRAME_PROTECTION_CAPABLE & rsnCaps);
if (buf.remaining() < 2) return;
@@ -2218,6 +2242,8 @@ public class InformationElementUtil {
* @param ies -- Information Element array
* @param beaconCap -- 16-bit Beacon Capability Information field
* @param isOweSupported -- Boolean flag to indicate if OWE is supported by the device
+ * @param isRsnOverridingSupported -- Boolean flag to indicate if RSN Overriding is
+ * supported by the device
* @param freq -- Frequency on which frame/beacon was transmitted. Some parsing may be
* affected such as DMG parameters in DMG (60GHz) beacon.
* @param unknownAkmMap -- unknown AKM to known AKM mapping (Internally converted to
@@ -2228,6 +2254,7 @@ public class InformationElementUtil {
InformationElement[] ies,
int beaconCap,
boolean isOweSupported,
+ boolean isRsnOverridingSupported,
int freq,
SparseIntArray unknownAkmMap) {
protocol = new ArrayList<>();
@@ -2265,10 +2292,22 @@ public class InformationElementUtil {
}
if (ie.id == InformationElement.EID_RSN) {
- parseRsnElement(ie, unknownAkmMap);
+ parseRsnElement(ByteBuffer.wrap(ie.bytes).order(ByteOrder.LITTLE_ENDIAN),
+ unknownAkmMap);
}
if (ie.id == InformationElement.EID_VSA) {
+ if (isRsnOverridingSupported && isRsneOverrideElement(ie)) {
+ ByteBuffer buf = ByteBuffer.wrap(ie.bytes).order(ByteOrder.LITTLE_ENDIAN);
+ // RSN Override and RSN Override 2 vendor specific element begins
+ // with 3 bytes of Wi-Fi Alliance specific OUI and 1 byte of OUI type.
+ // The Payload field of the RSNE Override element and the RSNE Override 2
+ // element uses the same format as the Information field of the RSNE.
+ // So skip the 4 byte OUI field and proceed to parse the RSN element.
+ buf.getInt();
+ parseRsnElement(buf, unknownAkmMap);
+ isRSNEOverrideElementPresent = true;
+ }
if (isWpaOneElement(ie)) {
parseWpaOneElement(ie, unknownAkmMap);
}
@@ -2474,6 +2513,9 @@ public class InformationElementUtil {
if (isManagementFrameProtectionCapable) {
capabilities.append("[MFPC]");
}
+ if (isRSNEOverrideElementPresent) {
+ capabilities.append("[RSNO]");
+ }
return capabilities.toString();
}
diff --git a/service/java/com/android/server/wifi/util/NativeUtil.java b/service/java/com/android/server/wifi/util/NativeUtil.java
index 0d422d0b9a..f98a2c17c7 100644
--- a/service/java/com/android/server/wifi/util/NativeUtil.java
+++ b/service/java/com/android/server/wifi/util/NativeUtil.java
@@ -23,6 +23,8 @@ import android.net.wifi.util.HexEncoding;
import android.text.TextUtils;
import com.android.server.wifi.ByteBufferReader;
+import com.android.server.wifi.SupplicantStaIfaceHal.StaIfaceReasonCode;
+import com.android.server.wifi.WifiConfigurationUtil;
import com.android.server.wifi.WifiGlobals;
import java.nio.BufferUnderflowException;
@@ -433,6 +435,31 @@ public class NativeUtil {
return ciphers;
}
+ /**
+ * Check if the EAPOL 4-WAY H/S failure is due to wrong password
+ *
+ */
+ public static boolean isEapol4WayHandshakeFailureDueToWrongPassword(WifiConfiguration config,
+ boolean locallyGenerated, int reasonCode) {
+ if (!(WifiConfigurationUtil.isConfigForPskNetwork(config)
+ || WifiConfigurationUtil.isConfigForWapiPskNetwork(
+ config))) {
+ return false;
+ }
+ // Filter out the disconnect triggered by the supplicant due to WPA/RSN IE mismatch in the
+ // received EAPOL message 3/4 with the Beacon/ProbeResp WPA/RSN IE.
+ if (locallyGenerated && reasonCode == StaIfaceReasonCode.IE_IN_4WAY_DIFFERS) {
+ return false;
+ }
+ // Some APs send de-authentication/disassociation with reason code 5
+ // (NO_MORE_STAS - Disassociated because AP is unable to handle all currently associated
+ // STAs) in the middle of EAPOL H/S. Filter out this reason code.
+ if (!locallyGenerated && reasonCode == StaIfaceReasonCode.DISASSOC_AP_BUSY) {
+ return false;
+ }
+ return true;
+ }
+
private static boolean isPskSaeParamsMergeable(
WifiConfiguration config, WifiGlobals wifiGlobals) {
if (config.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK)
diff --git a/service/java/com/android/server/wifi/util/XmlUtil.java b/service/java/com/android/server/wifi/util/XmlUtil.java
index e0bb9e5f28..0f70340d84 100644
--- a/service/java/com/android/server/wifi/util/XmlUtil.java
+++ b/service/java/com/android/server/wifi/util/XmlUtil.java
@@ -16,6 +16,8 @@
package com.android.server.wifi.util;
+import static com.android.wifi.flags.Flags.softapConfigStoreMaxChannelWidth;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.compat.CompatChanges;
@@ -1972,6 +1974,7 @@ public class XmlUtil {
public static final String XML_TAG_VENDOR_ELEMENTS = "VendorElements";
public static final String XML_TAG_PERSISTENT_RANDOMIZED_MAC_ADDRESS =
"PersistentRandomizedMacAddress";
+ public static final String XML_TAG_MAX_CHANNEL_WIDTH = "MaxChannelWidth";
/**
@@ -2195,6 +2198,10 @@ public class XmlUtil {
XmlUtil.writeNextValue(out, XML_TAG_PERSISTENT_RANDOMIZED_MAC_ADDRESS,
softApConfig.getPersistentRandomizedMacAddress().toString());
}
+ if (softapConfigStoreMaxChannelWidth()) {
+ XmlUtil.writeNextValue(out, XML_TAG_MAX_CHANNEL_WIDTH,
+ softApConfig.getMaxChannelBandwidth());
+ }
}
if (SdkLevel.isAtLeastV()) {
writeVendorDataListToXml(out, softApConfig.getVendorData());
@@ -2348,6 +2355,12 @@ public class XmlUtil {
MacAddress.fromString((String) value));
}
break;
+ case XML_TAG_MAX_CHANNEL_WIDTH:
+ if (SdkLevel.isAtLeastT()
+ && softapConfigStoreMaxChannelWidth()) {
+ softApConfigBuilder.setMaxChannelBandwidth((int) value);
+ }
+ break;
default:
Log.w(TAG, "Ignoring unknown value name " + valueName[0]);
break;
diff --git a/service/tests/wifitests/Android.bp b/service/tests/wifitests/Android.bp
index 7349dcbdb0..98974c26c7 100644
--- a/service/tests/wifitests/Android.bp
+++ b/service/tests/wifitests/Android.bp
@@ -674,6 +674,9 @@ android_test {
"com.android.server.wifi.WifiVendorHal",
"com.android.server.wifi.WifiVendorHal$*",
"com.android.server.wifi.WifiVendorHal.**",
+ "com.android.server.wifi.WifiVoipDetector",
+ "com.android.server.wifi.WifiVoipDetector$*",
+ "com.android.server.wifi.WifiVoipDetector.**",
"com.android.server.wifi.WifiWakeMetrics",
"com.android.server.wifi.WifiWakeMetrics$*",
"com.android.server.wifi.WifiWakeMetrics.**",
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java b/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
index 78f28fb507..18d1fbe2f3 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ActiveModeWardenTest.java
@@ -63,10 +63,8 @@ import static org.mockito.Mockito.when;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
-import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.content.res.Resources;
import android.location.LocationManager;
import android.net.MacAddress;
import android.net.Network;
@@ -80,8 +78,10 @@ import android.net.wifi.SoftApInfo;
import android.net.wifi.SoftApState;
import android.net.wifi.WifiClient;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
+import android.net.wifi.util.WifiResourceCache;
import android.os.BatteryStatsManager;
import android.os.Build;
import android.os.IBinder;
@@ -158,8 +158,8 @@ public class ActiveModeWardenTest extends WifiBaseTest {
TestLooper mLooper;
@Mock WifiInjector mWifiInjector;
- @Mock Context mContext;
- @Mock Resources mResources;
+ @Mock WifiContext mContext;
+ @Mock WifiResourceCache mWifiResourceCache;
@Mock WifiNative mWifiNative;
@Mock WifiApConfigStore mWifiApConfigStore;
@Mock ConcreteClientModeManager mClientModeManager;
@@ -226,16 +226,16 @@ public class ActiveModeWardenTest extends WifiBaseTest {
when(mWifiInjector.getWifiConfigManager()).thenReturn(mWifiConfigManager);
when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
when(mClientModeManager.getInterfaceName()).thenReturn(WIFI_IFACE_NAME);
- when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getResourceCache()).thenReturn(mWifiResourceCache);
when(mSoftApManager.getRole()).thenReturn(ROLE_SOFTAP_TETHERED);
- when(mResources.getString(R.string.wifi_localhotspot_configure_ssid_default))
+ when(mWifiResourceCache.getString(R.string.wifi_localhotspot_configure_ssid_default))
.thenReturn("AndroidShare");
- when(mResources.getInteger(R.integer.config_wifi_framework_recovery_timeout_delay))
+ when(mWifiResourceCache.getInteger(R.integer.config_wifi_framework_recovery_timeout_delay))
.thenReturn(TEST_WIFI_RECOVERY_DELAY_MS);
- when(mResources.getBoolean(R.bool.config_wifiScanHiddenNetworksScanOnlyMode))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiScanHiddenNetworksScanOnlyMode))
.thenReturn(false);
- when(mResources.getBoolean(R.bool.config_wifi_turn_off_during_emergency_call))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifi_turn_off_during_emergency_call))
.thenReturn(true);
when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
@@ -678,7 +678,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
*/
@Test
public void testScanOnlyModeScanHiddenNetworks() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifiScanHiddenNetworksScanOnlyMode))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiScanHiddenNetworksScanOnlyMode))
.thenReturn(true);
mActiveModeWarden = createActiveModeWarden();
@@ -787,7 +787,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void testSwitchFromConnectModeToScanOnlyModeRemovesAdditionalCMMs() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
@@ -1498,7 +1498,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(false);
reset(mContext);
- when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getResourceCache()).thenReturn(mWifiResourceCache);
mActiveModeWarden = createActiveModeWarden();
mActiveModeWarden.start();
mLooper.dispatchAll();
@@ -1532,7 +1532,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
when(mSettingsStore.updateAirplaneModeTracker()).thenReturn(true);
reset(mContext);
- when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getResourceCache()).thenReturn(mWifiResourceCache);
mActiveModeWarden = createActiveModeWarden();
mActiveModeWarden.start();
mLooper.dispatchAll();
@@ -1647,7 +1647,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true);
reset(mContext);
- when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getResourceCache()).thenReturn(mWifiResourceCache);
mActiveModeWarden = createActiveModeWarden();
mActiveModeWarden.start();
mLooper.dispatchAll();
@@ -3027,16 +3027,16 @@ public class ActiveModeWardenTest extends WifiBaseTest {
assertFalse(mActiveModeWarden.isStaStaConcurrencySupportedForMbb());
assertFalse(mActiveModeWarden.isStaStaConcurrencySupportedForRestrictedConnections());
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.isStaStaConcurrencySupportedForLocalOnlyConnections());
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.isStaStaConcurrencySupportedForMbb());
- when(mResources.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.isStaStaConcurrencySupportedForRestrictedConnections());
}
@@ -3121,7 +3121,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void testRemoveDefaultClientModeManager() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false));
@@ -3361,7 +3361,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void requestRemoveLocalOnlyClientModeManager() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false));
@@ -3383,7 +3383,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void requestRemoveLocalOnlyClientModeManagerWhenFeatureDisabled() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(false);
assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false));
@@ -3396,7 +3396,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false));
@@ -3426,7 +3426,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void requestLocalOnlyClientModeManagerWhenAlreadyPresent() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false));
@@ -3438,7 +3438,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void requestLocalOnlyClientModeManagerWhenAlreadyPresentSameBssid() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false));
@@ -3450,7 +3450,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void requestLocalOnlyClientModeManagerWhenConnectingToPrimaryBssid() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false));
@@ -3463,7 +3463,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE, TEST_UID)).thenReturn(false);
@@ -3488,7 +3488,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE, TEST_UID)).thenReturn(false);
when(mWifiPermissionsUtil.isTargetSdkLessThan(
@@ -3506,7 +3506,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
// should be able to do for <S apps)
when(mWifiNative.isStaStaConcurrencySupported()).thenReturn(true);
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(false);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE, TEST_UID)).thenReturn(false);
when(mWifiPermissionsUtil.isTargetSdkLessThan(
@@ -3521,7 +3521,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
private void testLoFallbackAboveAndroidS(boolean isStaStaSupported) throws Exception {
when(mWifiNative.isStaStaConcurrencySupported()).thenReturn(isStaStaSupported);
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(false);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE, TEST_UID)).thenReturn(false);
when(mWifiPermissionsUtil.isTargetSdkLessThan(
@@ -3559,7 +3559,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void requestRemoveSecondaryLongLivedClientModeManager() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false));
@@ -3583,7 +3583,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
.thenReturn(false);
assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false));
@@ -3595,7 +3595,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void requestSecondaryLongLivedClientModeManagerWhenWifiIsOff() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false));
@@ -3607,7 +3607,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void requestSecondaryLongLivedClientModeManagerWhenAlreadyPresent() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false));
@@ -3620,7 +3620,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false));
@@ -3634,7 +3634,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_SECONDARY_LONG_LIVED, false));
@@ -3647,7 +3647,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void requestRemoveSecondaryTransientClientModeManager() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
@@ -3672,7 +3672,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(false);
assertFalse(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
@@ -3685,7 +3685,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void requestSecondaryTransientClientModeManagerWhenWifiIsOff() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
@@ -3698,7 +3698,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void requestSecondaryTransientClientModeManagerWhenAlreadyPresent() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
@@ -3712,7 +3712,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
@@ -3727,7 +3727,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
@@ -3742,10 +3742,10 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
@@ -3827,10 +3827,10 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
@@ -3908,7 +3908,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
@@ -3972,9 +3972,9 @@ public class ActiveModeWardenTest extends WifiBaseTest {
when(mWifiPermissionsUtil.checkEnterCarModePrioritized(anyInt())).thenReturn(true);
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false));
@@ -4032,9 +4032,9 @@ public class ActiveModeWardenTest extends WifiBaseTest {
when(mWifiPermissionsUtil.checkEnterCarModePrioritized(anyInt())).thenReturn(true);
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
TEST_WORKSOURCE, ROLE_CLIENT_LOCAL_ONLY, false));
@@ -4080,7 +4080,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
@@ -4357,7 +4357,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void testSwitchPrimaryClientModeManager() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(true);
assertTrue(mActiveModeWarden.canRequestMoreClientModeManagersInRole(
@@ -4435,7 +4435,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
ConcreteClientModeManager additionalClientModeManager =
@@ -4739,9 +4739,9 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void testRequestForSecondaryLocalOnlyForPreSAppWithUserConnect() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
.thenReturn(true);
when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE, TEST_UID)).thenReturn(false);
when(mWifiPermissionsUtil.isTargetSdkLessThan(
@@ -4804,7 +4804,7 @@ public class ActiveModeWardenTest extends WifiBaseTest {
public void testRequestForSecondaryLocalOnlyForAppWithUserConnect() throws Exception {
// Ensure that we can create more client ifaces.
when(mWifiNative.isItPossibleToCreateStaIface(any())).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
when(mWifiPermissionsUtil.isSystem(TEST_PACKAGE, TEST_UID)).thenReturn(false);
when(mWifiPermissionsUtil.isTargetSdkLessThan(
@@ -4896,14 +4896,14 @@ public class ActiveModeWardenTest extends WifiBaseTest {
assertEquals(supportedFeaturesFromWifiNative, mActiveModeWarden.getSupportedFeatureSet());
when(mWifiNative.isStaStaConcurrencySupported()).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaLocalOnlyConcurrencyEnabled))
.thenReturn(true);
mClientListener.onStarted(mClientModeManager);
assertEquals(supportedFeaturesFromWifiNative
| WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY,
mActiveModeWarden.getSupportedFeatureSet());
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifiMultiStaNetworkSwitchingMakeBeforeBreakEnabled))
.thenReturn(true);
mClientListener.onStarted(mClientModeManager);
@@ -4912,10 +4912,10 @@ public class ActiveModeWardenTest extends WifiBaseTest {
| WifiManager.WIFI_FEATURE_ADDITIONAL_STA_MBB,
mActiveModeWarden.getSupportedFeatureSet());
- when(mResources.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
- .thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiMultiStaMultiInternetConcurrencyEnabled))
+ when(mWifiResourceCache.getBoolean(R.bool.config_wifiMultiStaRestrictedConcurrencyEnabled))
.thenReturn(true);
+ when(mWifiResourceCache.getBoolean(
+ R.bool.config_wifiMultiStaMultiInternetConcurrencyEnabled)).thenReturn(true);
mClientListener.onStarted(mClientModeManager);
assertEquals(supportedFeaturesFromWifiNative
| WifiManager.WIFI_FEATURE_ADDITIONAL_STA_LOCAL_ONLY
@@ -4928,13 +4928,13 @@ public class ActiveModeWardenTest extends WifiBaseTest {
private long testGetSupportedFeaturesCaseForMacRandomization(
long supportedFeaturesFromWifiNative, boolean apMacRandomizationEnabled,
boolean staConnectedMacRandomizationEnabled, boolean p2pMacRandomizationEnabled) {
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifi_connected_mac_randomization_supported))
.thenReturn(staConnectedMacRandomizationEnabled);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifi_ap_mac_randomization_supported))
.thenReturn(apMacRandomizationEnabled);
- when(mResources.getBoolean(
+ when(mWifiResourceCache.getBoolean(
R.bool.config_wifi_p2p_mac_randomization_supported))
.thenReturn(p2pMacRandomizationEnabled);
when(mWifiNative.getSupportedFeatureSet(anyString()))
diff --git a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index fddabc74b8..2d114d20c4 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -1574,6 +1574,29 @@ public class ClientModeImplTest extends WifiBaseTest {
assertEquals("L3ProvisioningState", getCurrentState().getName());
}
+ private void setupCarrierConnectionNotSimBased() throws Exception {
+ mConnectedNetwork.carrierId = CARRIER_ID_1;
+ when(mWifiCarrierInfoManager.getBestMatchSubscriptionId(any(WifiConfiguration.class)))
+ .thenReturn(DATA_SUBID);
+ when(mWifiCarrierInfoManager.isSimReady(DATA_SUBID)).thenReturn(true);
+
+ triggerConnect();
+
+ when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID))
+ .thenReturn(mScanDetailCache);
+ when(mScanDetailCache.getScanDetail(TEST_BSSID_STR)).thenReturn(
+ getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq));
+ when(mScanDetailCache.getScanResult(TEST_BSSID_STR)).thenReturn(
+ getGoogleGuestScanDetail(TEST_RSSI, TEST_BSSID_STR, sFreq).getScanResult());
+
+ WifiSsid wifiSsid = WifiSsid.fromBytes(
+ NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(mConnectedNetwork.SSID)));
+ mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT,
+ new NetworkConnectionEventInfo(0, wifiSsid, TEST_BSSID_STR, false, null));
+ mLooper.dispatchAll();
+ assertEquals("L3ProvisioningState", getCurrentState().getName());
+ }
+
@Test
public void testUpdatingOobPseudonymToSupplicant() throws Exception {
when(mWifiCarrierInfoManager.isOobPseudonymFeatureEnabled(anyInt())).thenReturn(true);
@@ -1778,6 +1801,25 @@ public class ClientModeImplTest extends WifiBaseTest {
}
/**
+ * When the default data SIM is changed, if the current wifi connection is carrier wifi,
+ * the connection should be disconnected, and if the network is not SIM-based, no notification
+ * should be send
+ */
+ @Test
+ public void testDefaultDataSimChangedNotSimBased() throws Exception {
+ setupCarrierConnectionNotSimBased();
+ doReturn(false).when(mWifiCarrierInfoManager).isSimReady(eq(DATA_SUBID));
+ mCmi.sendMessage(ClientModeImpl.CMD_RESET_SIM_NETWORKS,
+ ClientModeImpl.RESET_SIM_REASON_DEFAULT_DATA_SIM_CHANGED);
+ mLooper.dispatchAll();
+
+ verify(mWifiNative, times(2)).removeAllNetworks(WIFI_IFACE_NAME);
+ verify(mWifiMetrics).logStaEvent(anyString(), eq(StaEvent.TYPE_FRAMEWORK_DISCONNECT),
+ eq(StaEvent.DISCONNECT_RESET_SIM_NETWORKS));
+ verify(mSimRequiredNotifier, never()).showSimRequiredNotification(any(), anyString());
+ }
+
+ /**
* Tests anonymous identity is set again whenever a connection is established for the carrier
* that supports encrypted IMSI and anonymous identity and no real pseudonym was provided.
*/
@@ -2607,6 +2649,17 @@ public class ClientModeImplTest extends WifiBaseTest {
verify(mActiveModeWarden).setCurrentNetwork(null);
}
+ @Test
+ public void testWifiInfoNetworkIdSetInScanningState() throws Exception {
+ triggerConnect();
+ assertEquals(WifiConfiguration.INVALID_NETWORK_ID, mWifiInfo.getNetworkId());
+ mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
+ new StateChangeResult(0, TEST_WIFI_SSID, TEST_BSSID_STR, sFreq,
+ SupplicantState.SCANNING));
+ mLooper.dispatchAll();
+ assertEquals(0, mWifiInfo.getNetworkId());
+ }
+
/**
* If caller tries to connect to a new network while still provisioning the current one,
* the connection attempt should succeed.
@@ -7800,12 +7853,14 @@ public class ClientModeImplTest extends WifiBaseTest {
final IpClientCallbacks callback = mIpClientCallback;
final ReachabilityLossInfoParcelable lossInfo =
new ReachabilityLossInfoParcelable("", lossReason);
+ assertNull(mCmi.getConnectingWifiConfiguration());
callback.onReachabilityFailure(lossInfo);
callback.onProvisioningFailure(new LinkProperties());
mLooper.dispatchAll();
verify(mWifiNetworkAgent).unregisterAfterReplacement(anyInt());
verify(mWifiNative, never()).disconnect(WIFI_IFACE_NAME);
assertEquals("L3ProvisioningState", getCurrentState().getName());
+ assertEquals(FRAMEWORK_NETWORK_ID, mCmi.getConnectingWifiConfiguration().networkId);
// Verify that onProvisioningFailure from the current IpClientCallbacks instance
// triggers wifi disconnection.
@@ -10099,6 +10154,8 @@ public class ClientModeImplTest extends WifiBaseTest {
assertTrue(mCmi.isAffiliatedLinkBssid(MacAddress.fromString(TEST_BSSID_STR)));
assertTrue(mCmi.isAffiliatedLinkBssid(MacAddress.fromString(TEST_BSSID_STR1)));
assertFalse(mCmi.isAffiliatedLinkBssid(MacAddress.fromString(TEST_BSSID_STR2)));
+ // Check for null BSSID
+ assertFalse(mCmi.isAffiliatedLinkBssid(null));
}
@Test
@@ -10126,6 +10183,8 @@ public class ClientModeImplTest extends WifiBaseTest {
mLooper.dispatchAll();
// Test isAffiliatedLinkBssid match fails with no NPE
assertFalse(mCmi.isAffiliatedLinkBssid(MacAddress.fromString(TEST_BSSID_STR)));
+ // Check for null BSSID
+ assertFalse(mCmi.isAffiliatedLinkBssid(null));
}
/**
@@ -11142,4 +11201,21 @@ public class ClientModeImplTest extends WifiBaseTest {
eq(WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_EAP_FAILURE),
anyInt(), eq(ClientModeImpl.EAP_FAILURE_CODE_CERTIFICATE_EXPIRED));
}
+
+ /**
+ * Verify that the Sae H2E Feature is set even though config_wifiSaeH2eSupported
+ * is not enabled through overlay.
+ */
+ @Test
+ public void testSaeH2eSetEvenThoughConfigForSaeH2eIsNotTrue() throws Exception {
+ when(mWifiNative.isSupplicantAidlServiceVersionAtLeast(3)).thenReturn(true);
+ when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn(
+ WifiManager.WIFI_FEATURE_WPA3_SAE);
+ initializeCmi();
+ if (SdkLevel.isAtLeastV()) {
+ verify(mWifiGlobals).enableWpa3SaeH2eSupport();
+ } else {
+ verify(mWifiGlobals, never()).enableWpa3SaeH2eSupport();
+ }
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java b/service/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
index 04536b8c55..40c46b08e8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/DeviceConfigFacadeTest.java
@@ -52,10 +52,14 @@ import java.util.function.Consumer;
*/
@SmallTest
public class DeviceConfigFacadeTest extends WifiBaseTest {
+ private static final String DRY_RUN_SCORER_PKG_NAME =
+ "com.google.android.apps.carrier.carrierwifi";
@Mock Context mContext;
@Mock WifiMetrics mWifiMetrics;
@Mock
Consumer<Boolean> mOobPseudonymFeatureFlagChangedListener;
+ @Mock
+ Consumer<String> mDryRunScorerPkgNameChangedListener;
final ArgumentCaptor<OnPropertiesChangedListener> mOnPropertiesChangedListenerCaptor =
ArgumentCaptor.forClass(OnPropertiesChangedListener.class);
@@ -105,6 +109,8 @@ public class DeviceConfigFacadeTest extends WifiBaseTest {
mOnPropertiesChangedListenerCaptor.capture()));
mDeviceConfigFacade.setOobPseudonymFeatureFlagChangedListener(
mOobPseudonymFeatureFlagChangedListener);
+ mDeviceConfigFacade.setDryRunScorerPkgNameChangedListener(
+ mDryRunScorerPkgNameChangedListener);
}
/**
@@ -229,8 +235,11 @@ public class DeviceConfigFacadeTest extends WifiBaseTest {
assertEquals(true, mDeviceConfigFacade.isAwareSuspensionEnabled());
assertEquals(true, mDeviceConfigFacade.isHighPerfLockDeprecated());
assertEquals(true, mDeviceConfigFacade.isOobPseudonymEnabled());
+ assertEquals(DeviceConfigFacade.DEFAULT_DRY_RUN_SCORER_PKG_NAME,
+ mDeviceConfigFacade.getDryRunScorerPkgName());
mLooper.dispatchAll();
verify(mOobPseudonymFeatureFlagChangedListener, never()).accept(anyBoolean());
+ verify(mDryRunScorerPkgNameChangedListener, never()).accept(anyString());
assertEquals(true, mDeviceConfigFacade.isApplicationQosPolicyApiEnabled());
assertEquals(false, mDeviceConfigFacade.isAdjustPollRssiIntervalEnabled());
assertEquals(true, mDeviceConfigFacade.includePasspointSsidsInPnoScans());
@@ -451,6 +460,8 @@ public class DeviceConfigFacadeTest extends WifiBaseTest {
assertEquals(true, mDeviceConfigFacade.isAwareSuspensionEnabled());
assertEquals(true, mDeviceConfigFacade.isHighPerfLockDeprecated());
assertEquals(true, mDeviceConfigFacade.isOobPseudonymEnabled());
+ assertEquals(DeviceConfigFacade.DEFAULT_DRY_RUN_SCORER_PKG_NAME,
+ mDeviceConfigFacade.getDryRunScorerPkgName());
assertEquals(true, mDeviceConfigFacade.isApplicationQosPolicyApiEnabled());
assertEquals(true, mDeviceConfigFacade.isAdjustPollRssiIntervalEnabled());
assertEquals(true, mDeviceConfigFacade.includePasspointSsidsInPnoScans());
@@ -463,10 +474,14 @@ public class DeviceConfigFacadeTest extends WifiBaseTest {
when(DeviceConfig.getBoolean(anyString(), eq("oob_pseudonym_enabled"),
anyBoolean())).thenReturn(false);
+ when(DeviceConfig.getString(anyString(), eq("dry_run_scorer_pkg_name"), anyString()))
+ .thenReturn(DRY_RUN_SCORER_PKG_NAME);
mOnPropertiesChangedListenerCaptor.getValue().onPropertiesChanged(null);
mLooper.dispatchAll();
assertEquals(false, mDeviceConfigFacade.isOobPseudonymEnabled());
verify(mOobPseudonymFeatureFlagChangedListener).accept(false);
+ assertEquals(DRY_RUN_SCORER_PKG_NAME, mDeviceConfigFacade.getDryRunScorerPkgName());
+ verify(mDryRunScorerPkgNameChangedListener).accept(DRY_RUN_SCORER_PKG_NAME);
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
index 36e54b0680..f4fe2814b8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java
@@ -23,6 +23,7 @@ import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP_BRIDG
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_NAN;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_P2P;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_STA;
+import static com.android.server.wifi.util.GeneralUtil.longToBitset;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
@@ -106,6 +107,7 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -1738,6 +1740,36 @@ public class HalDeviceManagerTest extends WifiBaseTest {
}
/**
+ * Validate {@link HalDeviceManager#canDeviceSupportCreateTypeCombo(SparseArray)} with stored
+ * static chip info.
+ */
+ @Test
+ public void testReportImpactToCreateIfaceChipV1WithStoredStaticChipInfo()
+ throws Exception {
+ TestChipV1 chipMock = new TestChipV1();
+ chipMock.initialize();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
+
+ // Try to query iface support before starting the HAL. Should return true with the stored
+ // static chip info.
+ when(mWifiMock.isStarted()).thenReturn(false);
+ when(mWifiSettingsConfigStore.get(WifiSettingsConfigStore.WIFI_STATIC_CHIP_INFO))
+ .thenReturn(TestChipV1.STATIC_CHIP_INFO_JSON_STRING);
+ assertTrue(mDut.reportImpactToCreateIface(
+ HDM_CREATE_IFACE_STA, true, TEST_WORKSOURCE_0).isEmpty());
+ assertTrue(mDut.reportImpactToCreateIface(
+ HDM_CREATE_IFACE_AP, true, TEST_WORKSOURCE_0).isEmpty());
+ assertNull(mDut.reportImpactToCreateIface(
+ HDM_CREATE_IFACE_AP_BRIDGE, true, TEST_WORKSOURCE_0));
+ assertTrue(mDut.reportImpactToCreateIface(
+ HDM_CREATE_IFACE_P2P, true, TEST_WORKSOURCE_0).isEmpty());
+ assertTrue(mDut.reportImpactToCreateIface(
+ HDM_CREATE_IFACE_NAN, true, TEST_WORKSOURCE_0).isEmpty());
+
+ verifyNoMoreInteractions(mManagerStatusListenerMock);
+ }
+
+ /**
* Validates that {@link HalDeviceManager#canDeviceSupportCreateTypeCombo(SparseArray)} with
* outdated stored static chip info will be updated once we load the chip info when the driver
* is up.
@@ -3987,6 +4019,104 @@ public class HalDeviceManagerTest extends WifiBaseTest {
);
}
+ /**
+ * Validate a P2P request from requestors not on the P2P/NAN concurrency allowlist.
+ */
+ @Test
+ public void testP2pNanConcurrencyNotAllowedTestChipV11()
+ throws Exception {
+ when(mResources.getStringArray(R.array.config_wifiP2pAwareConcurrencyAllowlist)).thenReturn(
+ new String[]{"Some other package"});
+
+ TestChipV11 chipMock = new TestChipV11();
+ chipMock.initialize();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
+ executeAndValidateStartupSequence();
+
+ InterfaceDestroyedListener idl = mock(InterfaceDestroyedListener.class);
+
+ // Create a NAN
+ WifiInterface nanIface = validateInterfaceSequence(chipMock,
+ false, // chipModeValid
+ -1000, // chipModeId (only used if chipModeValid is true)
+ HDM_CREATE_IFACE_NAN,
+ "wlan0",
+ TestChipV11.CHIP_MODE_ID,
+ null, // tearDownList
+ idl, // destroyedListener
+ TEST_WORKSOURCE_0 // requestorWs
+ );
+ collector.checkThat("interface was null", nanIface, IsNull.notNullValue());
+
+ // P2P request from Worksource 1 (lower priority) should be blocked.
+ when(mWorkSourceHelper1.getRequestorWsPriority())
+ .thenReturn(WorkSourceHelper.PRIORITY_FG_APP);
+ List<Pair<Integer, WorkSource>> p2pDetails = mDut.reportImpactToCreateIface(
+ HDM_CREATE_IFACE_P2P, true, TEST_WORKSOURCE_1);
+ if (SdkLevel.isAtLeastS()) {
+ assertNull("Should not be able to create this P2P", p2pDetails);
+ } else {
+ // Pre-S lets P2P/NAN destroy each other.
+ assertEquals(p2pDetails.get(0).second, TEST_WORKSOURCE_0);
+ }
+
+ // P2P request from Worksource 2 (same privileged priority) should tear down NAN.
+ WifiInterface p2pIface = validateInterfaceSequence(chipMock,
+ true, // chipModeValid
+ TestChipV11.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
+ HDM_CREATE_IFACE_P2P,
+ "wlan1",
+ TestChipV11.CHIP_MODE_ID,
+ new WifiInterface[]{nanIface}, // tearDownList
+ idl, // destroyedListener
+ TEST_WORKSOURCE_2 // requestorWs
+ );
+ collector.checkThat("interface was null", p2pIface, IsNull.notNullValue());
+ }
+
+ /**
+ * Validate a P2P request from a requestor on the P2P/NAN concurrency allowlist.
+ */
+ @Test
+ public void testP2pNanConcurrencyAllowedTestChipV11()
+ throws Exception {
+ when(mResources.getStringArray(R.array.config_wifiP2pAwareConcurrencyAllowlist)).thenReturn(
+ new String[]{TEST_WORKSOURCE_1.getPackageName(0)});
+
+ TestChipV11 chipMock = new TestChipV11();
+ chipMock.initialize();
+ mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock);
+ executeAndValidateStartupSequence();
+
+ InterfaceDestroyedListener idl = mock(InterfaceDestroyedListener.class);
+
+ // Create a NAN
+ WifiInterface nanIface = validateInterfaceSequence(chipMock,
+ false, // chipModeValid
+ -1000, // chipModeId (only used if chipModeValid is true)
+ HDM_CREATE_IFACE_NAN,
+ "wlan0",
+ TestChipV11.CHIP_MODE_ID,
+ null, // tearDownList
+ idl, // destroyedListener
+ TEST_WORKSOURCE_0 // requestorWs
+ );
+ collector.checkThat("interface was null", nanIface, IsNull.notNullValue());
+
+ // P2P request from Worksource 1 (on allowlist) should be allowed.
+ WifiInterface p2pIface = validateInterfaceSequence(chipMock,
+ true, // chipModeValid
+ TestChipV11.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true)
+ HDM_CREATE_IFACE_P2P,
+ "wlan1",
+ TestChipV11.CHIP_MODE_ID,
+ null, // tearDownList
+ idl, // destroyedListener
+ TEST_WORKSOURCE_1 // requestorWs
+ );
+ collector.checkThat("interface was null", p2pIface, IsNull.notNullValue());
+ }
+
///////////////////////////////////////////////////////////////////////////////////////
// utilities
///////////////////////////////////////////////////////////////////////////////////////
@@ -4361,9 +4491,9 @@ public class HalDeviceManagerTest extends WifiBaseTest {
mChipMockBase = chipMockBase;
}
- public WifiChip.Response<Long> answer() {
- WifiChip.Response<Long> response =
- new WifiChip.Response<>(mChipMockBase.chipCapabilities);
+ public WifiChip.Response<BitSet> answer() {
+ WifiChip.Response<BitSet> response =
+ new WifiChip.Response<>(longToBitset(mChipMockBase.chipCapabilities));
response.setStatusCode(mChipMockBase.allowGetCapsBeforeIfaceCreated
? WifiHal.WIFI_STATUS_SUCCESS : WifiHal.WIFI_STATUS_ERROR_UNKNOWN);
return response;
@@ -5285,4 +5415,37 @@ public class HalDeviceManagerTest extends WifiBaseTest {
configureDriverAvailableModes();
}
}
+
+ // Test chip configuration V11 for P2P/NAN concurrency
+ // mode:
+ // (STA + AP + NAN + P2P)
+ private class TestChipV11 extends ChipMockBase {
+ static final int CHIP_MODE_ID = 90;
+
+ void initialize() throws Exception {
+ super.initialize();
+
+ // chip Id configuration
+ ArrayList<Integer> chipIds;
+ chipId = 11;
+ chipIds = new ArrayList<>();
+ chipIds.add(chipId);
+ doAnswer(new GetChipIdsAnswer(true, chipIds)).when(mWifiMock).getChipIds();
+ doAnswer(new GetChipAnswer(true, chip)).when(mWifiMock).getChip(anyInt());
+
+ // Initialize availableModes
+ availableModes = new ArrayList<>();
+
+ // Mode 90 (only one): (1xSTA + 1xAP + 1xP2P + 1xNAN)
+ WifiChip.ChipConcurrencyCombination combo1 = createConcurrencyCombo(
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_P2P),
+ createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_NAN));
+ availableModes.add(createChipMode(CHIP_MODE_ID, combo1));
+
+ chipModeIdValidForRtt = CHIP_MODE_ID;
+ doAnswer(new GetAvailableModesAnswer(this)).when(chip).getAvailableModes();
+ }
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/HostapdHalAidlImpTest.java b/service/tests/wifitests/src/com/android/server/wifi/HostapdHalAidlImpTest.java
index 8328dd3618..0d54c8114f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/HostapdHalAidlImpTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/HostapdHalAidlImpTest.java
@@ -38,7 +38,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.test.MockAnswerUtil;
-import android.content.Context;
import android.hardware.wifi.hostapd.ApInfo;
import android.hardware.wifi.hostapd.BandMask;
import android.hardware.wifi.hostapd.ChannelBandwidth;
@@ -57,8 +56,10 @@ import android.net.MacAddress;
import android.net.wifi.OuiKeyedData;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApConfiguration.Builder;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiManager;
import android.net.wifi.util.PersistableBundleUtils;
+import android.net.wifi.util.WifiResourceCache;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -105,7 +106,7 @@ public class HostapdHalAidlImpTest extends WifiBaseTest {
private final int mBand256G = SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ
| SoftApConfiguration.BAND_6GHZ;
- private @Mock Context mContext;
+ private @Mock WifiContext mContext;
private @Mock IHostapd mIHostapdMock;
private @Mock IBinder mServiceBinderMock;
private @Mock WifiNative.HostapdDeathEventHandler mHostapdHalDeathHandler;
@@ -192,6 +193,7 @@ public class HostapdHalAidlImpTest extends WifiBaseTest {
mResources.setString(R.string.config_wifiSoftap6gChannelList, "");
when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getResourceCache()).thenReturn(new WifiResourceCache(mContext));
doNothing().when(mIHostapdMock).addAccessPoint(
mIfaceParamsCaptor.capture(), mNetworkParamsCaptor.capture());
doNothing().when(mIHostapdMock).removeAccessPoint(any());
@@ -1194,15 +1196,50 @@ public class HostapdHalAidlImpTest extends WifiBaseTest {
mHostapdHal.registerApCallback(IFACE_NAME, mSoftApHalCallback);
// Trigger on info changed and verify.
+ mockApInfoChangedAndVerify(IFACE_NAME, 1, mIHostapdCallback, mSoftApHalCallback);
mockApInfoChangedAndVerify(IFACE_NAME, 2, mIHostapdCallback, mSoftApHalCallback);
- // Trigger on failure from first instance.
+ // Trigger on instance failure from first instance.
mIHostapdCallback.onFailure(IFACE_NAME, TEST_AP_INSTANCE);
verify(mSoftApHalCallback).onInstanceFailure(TEST_AP_INSTANCE);
// Trigger on failure from second instance.
mIHostapdCallback.onFailure(IFACE_NAME, TEST_AP_INSTANCE_2);
- verify(mSoftApHalCallback).onFailure();
+ verify(mSoftApHalCallback).onInstanceFailure(TEST_AP_INSTANCE_2);
+ }
+
+ /**
+ * Verifies the onFailure is ignored if it's for an instance that was already removed.
+ */
+ @Test
+ public void testHostapdCallbackOnFailureIgnoredForAlreadyRemovedInstance() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastT());
+ executeAndValidateInitializationSequence(true);
+ Builder configurationBuilder = new SoftApConfiguration.Builder();
+ configurationBuilder.setSsid(NETWORK_SSID);
+ configurationBuilder.setBands(new int[] {SoftApConfiguration.BAND_2GHZ,
+ SoftApConfiguration.BAND_5GHZ});
+
+ doNothing().when(mIHostapdMock).addAccessPoint(any(), any());
+ assertTrue(mHostapdHal.addAccessPoint(IFACE_NAME,
+ configurationBuilder.build(), true,
+ () -> mSoftApHalCallback.onFailure()));
+ verify(mIHostapdMock).addAccessPoint(any(), any());
+
+ // Register SoftApManager callback
+ mHostapdHal.registerApCallback(IFACE_NAME, mSoftApHalCallback);
+
+ // Trigger on info changed and verify.
+ mockApInfoChangedAndVerify(IFACE_NAME, 1, mIHostapdCallback, mSoftApHalCallback);
+
+ // Trigger on failure from first instance.
+ mIHostapdCallback.onFailure(IFACE_NAME, TEST_AP_INSTANCE);
+ verify(mSoftApHalCallback).onInstanceFailure(TEST_AP_INSTANCE);
+
+ // Trigger on failure from first instance again.
+ mIHostapdCallback.onFailure(IFACE_NAME, TEST_AP_INSTANCE);
+ verify(mSoftApHalCallback, times(1)).onInstanceFailure(TEST_AP_INSTANCE);
+ verify(mSoftApHalCallback, never()).onFailure();
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/HostapdHalHidlImpTest.java b/service/tests/wifitests/src/com/android/server/wifi/HostapdHalHidlImpTest.java
index f1a3c312d7..a6a9010a18 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/HostapdHalHidlImpTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/HostapdHalHidlImpTest.java
@@ -15,16 +15,30 @@
*/
package com.android.server.wifi;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyList;
+import static org.mockito.Mockito.anyShort;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.app.test.MockAnswerUtil;
-import android.content.Context;
import android.hardware.wifi.hostapd.V1_0.HostapdStatus;
import android.hardware.wifi.hostapd.V1_0.HostapdStatusCode;
import android.hardware.wifi.hostapd.V1_0.IHostapd;
@@ -37,6 +51,7 @@ import android.hidl.manager.V1_0.IServiceNotification;
import android.net.MacAddress;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApConfiguration.Builder;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.IHwBinder;
@@ -75,7 +90,7 @@ public class HostapdHalHidlImpTest extends WifiBaseTest {
private final int mBand256G = SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ
| SoftApConfiguration.BAND_6GHZ;
- private @Mock Context mContext;
+ private @Mock WifiContext mContext;
private @Mock IServiceManager mServiceManagerMock;
private @Mock IHostapd mIHostapdMock;
private @Mock WifiNative.HostapdDeathEventHandler mHostapdHalDeathHandler;
@@ -86,7 +101,7 @@ public class HostapdHalHidlImpTest extends WifiBaseTest {
private android.hardware.wifi.hostapd.V1_3.IHostapd mIHostapdMockV13;
private IHostapdCallback mIHostapdCallback;
private android.hardware.wifi.hostapd.V1_3.IHostapdCallback mIHostapdCallback13;
- private MockResources mResources;
+ private MockResourceCache mResources;
HostapdStatus mStatusSuccess;
HostapdStatus mStatusFailure;
android.hardware.wifi.hostapd.V1_2.HostapdStatus mStatusSuccess12;
@@ -158,7 +173,7 @@ public class HostapdHalHidlImpTest extends WifiBaseTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mResources = new MockResources();
+ mResources = new MockResourceCache(mContext);
mResources.setBoolean(R.bool.config_wifi_softap_acs_supported, false);
mResources.setBoolean(R.bool.config_wifi_softap_ieee80211ac_supported, false);
mResources.setBoolean(R.bool.config_wifiSoftapIeee80211axSupported, false);
@@ -175,7 +190,7 @@ public class HostapdHalHidlImpTest extends WifiBaseTest {
mStatusSuccess12 = createHostapdStatus_1_2(HostapdStatusCode.SUCCESS);
mStatusFailure12 = createHostapdStatus_1_2(HostapdStatusCode.FAILURE_UNKNOWN);
- when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getResourceCache()).thenReturn(mResources);
when(mServiceManagerMock.linkToDeath(any(IHwBinder.DeathRecipient.class),
anyLong())).thenReturn(true);
when(mServiceManagerMock.registerForNotifications(anyString(), anyString(),
diff --git a/service/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java b/service/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
index 579e6f7816..a8ec7da515 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/HostapdHalTest.java
@@ -28,10 +28,10 @@ import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.Context;
import android.net.MacAddress;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApConfiguration.Builder;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.test.TestLooper;
@@ -53,7 +53,7 @@ public class HostapdHalTest extends WifiBaseTest {
private IHostapdHal mIHostapd;
private @Mock HostapdHalAidlImp mIHostapdAidlMock;
private @Mock HostapdHalHidlImp mIHostapdHidlMock;
- private @Mock Context mContext;
+ private @Mock WifiContext mContext;
private @Mock WifiNative.HostapdDeathEventHandler mHostapdHalDeathHandler;
private @Mock WifiNative.SoftApHalCallback mSoftApHalCallback;
private TestLooper mLooper = new TestLooper();
diff --git a/service/tests/wifitests/src/com/android/server/wifi/MockResourceCache.java b/service/tests/wifitests/src/com/android/server/wifi/MockResourceCache.java
new file mode 100644
index 0000000000..4f7b656814
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/MockResourceCache.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi;
+
+import android.content.Context;
+import android.net.wifi.util.WifiResourceCache;
+
+import java.util.HashMap;
+
+public class MockResourceCache extends WifiResourceCache {
+
+ private final HashMap<Integer, Boolean> mBooleanValues;
+ private final HashMap<Integer, Integer> mIntegerValues;
+ private final HashMap<Integer, String> mStringValues;
+ private final HashMap<Integer, int[]> mIntArrayValues;
+ private final HashMap<Integer, String[]> mStringArrayValues;
+
+ public MockResourceCache(Context context) {
+ super(context);
+ mBooleanValues = new HashMap<Integer, Boolean>();
+ mIntegerValues = new HashMap<Integer, Integer>();
+ mStringValues = new HashMap<Integer, String>();
+ mIntArrayValues = new HashMap<Integer, int[]>();
+ mStringArrayValues = new HashMap<Integer, String[]>();
+ }
+
+ @Override
+ public boolean getBoolean(int id) {
+ return mBooleanValues.getOrDefault(id, false);
+ }
+
+ @Override
+ public int getInteger(int id) {
+ return mIntegerValues.getOrDefault(id, 0);
+ }
+
+ @Override
+ public String getString(int id) {
+ return mStringValues.getOrDefault(id, null);
+ }
+
+ @Override
+ public int[] getIntArray(int id) {
+ return mIntArrayValues.getOrDefault(id, null);
+ }
+
+ @Override
+ public String[] getStringArray(int id) {
+ return mStringArrayValues.getOrDefault(id, null);
+ }
+
+ public void setBoolean(int id, boolean value) {
+ mBooleanValues.put(id, value);
+ }
+
+ public void setInteger(int id, int value) {
+ mIntegerValues.put(id, value);
+ }
+
+ public void setString(int id, String value) {
+ mStringValues.put(id, value);
+ }
+
+ public void setIntArray(int id, int[] value) {
+ mIntArrayValues.put(id, value);
+ }
+
+ public void setStringArray(int id, String[] value) {
+ mStringArrayValues.put(id, value);
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/MockResources.java b/service/tests/wifitests/src/com/android/server/wifi/MockResources.java
index e6ccb6e523..1473a1d23c 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/MockResources.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/MockResources.java
@@ -95,6 +95,11 @@ public class MockResources extends android.test.mock.MockResources {
return 0;
}
+ @Override
+ public String getResourceEntryName(int id) {
+ return String.valueOf(id);
+ }
+
public void setBoolean(int id, boolean value) {
mBooleanValues.put(id, value);
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/RssiMonitorTest.java b/service/tests/wifitests/src/com/android/server/wifi/RssiMonitorTest.java
index 60eff99ff2..6866d587cb 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/RssiMonitorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/RssiMonitorTest.java
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.when;
import android.net.wifi.WifiContext;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
+import android.net.wifi.util.WifiResourceCache;
import android.os.Handler;
import android.os.test.TestLooper;
@@ -63,6 +64,7 @@ public class RssiMonitorTest extends WifiBaseTest {
private TestLooper mLooper;
@Mock WifiContext mContext;
MockResources mMockResources = new MockResources();
+ WifiResourceCache mWifiResourceCache;
private final WifiInfo mWifiInfo = new ExtendedWifiInfo(mWifiGlobals, TEST_INTERFACE_NAME);
@Mock WifiNative mWifiNative;
@Mock Runnable mUpdateCapabilityRunnable;
@@ -76,6 +78,8 @@ public class RssiMonitorTest extends WifiBaseTest {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(mContext.getResources()).thenReturn(mMockResources);
+ mWifiResourceCache = new WifiResourceCache(mContext);
+ when(mContext.getResourceCache()).thenReturn(mWifiResourceCache);
when(mDeviceConfigFacade.isAdjustPollRssiIntervalEnabled()).thenReturn(true);
mMockResources.setInteger(R.integer.config_wifiPollRssiIntervalMilliseconds,
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
index aeb84c21e5..5ba7e3ae7b 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -61,7 +61,6 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.res.Resources;
import android.net.MacAddress;
import android.net.TetheringManager;
import android.net.wifi.CoexUnsafeChannel;
@@ -79,6 +78,7 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.nl80211.DeviceWiphyCapabilities;
import android.net.wifi.nl80211.NativeWifiClient;
+import android.net.wifi.util.WifiResourceCache;
import android.os.BatteryManager;
import android.os.Message;
import android.os.UserHandle;
@@ -195,7 +195,7 @@ public class SoftApManagerTest extends WifiBaseTest {
private List<ClientModeManager> mTestClientModeManagers = new ArrayList<>();
@Mock WifiContext mContext;
- @Mock Resources mResources;
+ @Mock WifiResourceCache mResourceCache;
@Mock WifiNative mWifiNative;
@Mock CoexManager mCoexManager;
@Mock WifiServiceImpl.SoftApCallbackInternal mCallback;
@@ -340,24 +340,25 @@ public class SoftApManagerTest extends WifiBaseTest {
mAlarmManager = new TestAlarmManager();
when(mContext.getSystemService(Context.ALARM_SERVICE))
.thenReturn(mAlarmManager.getAlarmManager());
- when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getResourceCache()).thenReturn(mResourceCache);
when(mContext.getWifiOverlayApkPkgName()).thenReturn("test.com.android.wifi.resources");
when(mContext.registerReceiver(any(), any())).thenReturn(new Intent());
- when(mResources.getInteger(R.integer.config_wifiFrameworkSoftApShutDownTimeoutMilliseconds))
+ when(mResourceCache.getInteger(
+ R.integer.config_wifiFrameworkSoftApShutDownTimeoutMilliseconds))
.thenReturn((int) TEST_DEFAULT_SHUTDOWN_TIMEOUT_MILLIS);
- when(mResources.getInteger(R.integer
+ when(mResourceCache.getInteger(R.integer
.config_wifiFrameworkSoftApShutDownIdleInstanceInBridgedModeTimeoutMillisecond))
.thenReturn(
(int) TEST_DEFAULT_SHUTDOWN_IDLE_INSTANCE_IN_BRIDGED_MODE_TIMEOUT_MILLIS);
- when(mResources.getBoolean(R.bool.config_wifiBridgedSoftApSupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiBridgedSoftApSupported))
.thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported))
.thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiSoftap24ghzSupported)).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiSoftap5ghzSupported)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftap24ghzSupported)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftap5ghzSupported)).thenReturn(true);
when(mWifiNative.setApCountryCode(
TEST_INTERFACE_NAME, TEST_COUNTRY_CODE.toUpperCase(Locale.ROOT)))
.thenReturn(true);
@@ -392,7 +393,7 @@ public class SoftApManagerTest extends WifiBaseTest {
any(), any(), anyInt(), any(), anyBoolean())).thenReturn(
InterfaceConflictManager.ICM_EXECUTE_COMMAND);
// Default init STA enabled
- when(mResources.getBoolean(R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported))
.thenReturn(true);
when(mWifiNative.isStaApConcurrencySupported()).thenReturn(true);
when(mActiveModeWarden.getClientModeManagers())
@@ -537,7 +538,7 @@ public class SoftApManagerTest extends WifiBaseTest {
verify(mWifiMetrics).writeSoftApStartedEvent(
eq(SoftApManager.START_RESULT_FAILURE_INTERFACE_CONFLICT_USER_REJECTED),
any(), anyInt(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean(), anyInt(),
- anyInt());
+ anyInt(), eq(TEST_WORKSOURCE));
}
/** Verifies startSoftAp will skip checking for user approval for the Tethering case. */
@@ -614,7 +615,7 @@ public class SoftApManagerTest extends WifiBaseTest {
verify(mWifiMetrics).writeSoftApStartedEvent(
eq(SoftApManager.START_RESULT_FAILURE_GENERAL),
any(), anyInt(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean(), anyInt(),
- anyInt());
+ anyInt(), eq(TEST_WORKSOURCE));
}
/**
@@ -652,7 +653,7 @@ public class SoftApManagerTest extends WifiBaseTest {
verify(mWifiMetrics).writeSoftApStartedEvent(
eq(SoftApManager.START_RESULT_FAILURE_GENERAL),
any(), anyInt(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean(), anyInt(),
- anyInt());
+ anyInt(), eq(TEST_WORKSOURCE));
}
/**
@@ -694,7 +695,7 @@ public class SoftApManagerTest extends WifiBaseTest {
verify(mWifiMetrics).writeSoftApStartedEvent(
eq(SoftApManager.START_RESULT_FAILURE_INTERFACE_CONFLICT),
any(), anyInt(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean(), anyInt(),
- anyInt());
+ anyInt(), eq(TEST_WORKSOURCE));
}
/**
@@ -733,7 +734,7 @@ public class SoftApManagerTest extends WifiBaseTest {
verify(mWifiMetrics).writeSoftApStartedEvent(
eq(SoftApManager.START_RESULT_FAILURE_CREATE_INTERFACE),
any(), anyInt(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean(), anyInt(),
- anyInt());
+ anyInt(), eq(TEST_WORKSOURCE));
}
/**
@@ -767,7 +768,7 @@ public class SoftApManagerTest extends WifiBaseTest {
verify(mWifiMetrics).writeSoftApStartedEvent(
eq(SoftApManager.START_RESULT_FAILURE_SET_COUNTRY_CODE),
any(), anyInt(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean(), anyInt(),
- anyInt());
+ anyInt(), eq(TEST_WORKSOURCE));
}
/**
@@ -1012,7 +1013,7 @@ public class SoftApManagerTest extends WifiBaseTest {
verify(mWifiMetrics).writeSoftApStartedEvent(
eq(SoftApManager.START_RESULT_FAILURE_ADD_AP_HOSTAPD),
any(), anyInt(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean(), anyInt(),
- anyInt());
+ anyInt(), eq(TEST_WORKSOURCE));
}
/**
@@ -1079,7 +1080,7 @@ public class SoftApManagerTest extends WifiBaseTest {
// reset to clear verified Intents for ap state change updates
reset(mContext);
- when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getResourceCache()).thenReturn(mResourceCache);
InOrder order = inOrder(mCallback, mListener, mContext);
@@ -1157,7 +1158,7 @@ public class SoftApManagerTest extends WifiBaseTest {
// reset to clear verified Intents for ap state change updates
reset(mContext, mCallback, mWifiNative);
- when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getResourceCache()).thenReturn(mResourceCache);
InOrder order = inOrder(mCallback, mListener, mContext);
@@ -1225,7 +1226,7 @@ public class SoftApManagerTest extends WifiBaseTest {
// reset to clear verified Intents for ap state change updates
reset(mContext, mCallback, mWifiNative);
- when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getResourceCache()).thenReturn(mResourceCache);
InOrder order = inOrder(mCallback, mListener, mContext);
mSoftApHalCallbackCaptor.getValue().onFailure();
@@ -1279,7 +1280,10 @@ public class SoftApManagerTest extends WifiBaseTest {
mLooper.dispatchAll();
verify(mCallback, times(2)).onConnectedClientsOrInfoChanged(
mTestSoftApInfoMap, mTestWifiClientsMap, true);
-
+ when(mWifiNative.getBridgedApInstances(any()))
+ .thenReturn(new ArrayList<>(ImmutableList.of(TEST_FIRST_INSTANCE_NAME,
+ TEST_SECOND_INSTANCE_NAME)),
+ new ArrayList<>(ImmutableList.of(TEST_FIRST_INSTANCE_NAME)));
// Trigger onInstanceFailure
mSoftApHalCallbackCaptor.getValue().onInstanceFailure(TEST_SECOND_INSTANCE_NAME);
mLooper.dispatchAll();
@@ -1311,6 +1315,11 @@ public class SoftApManagerTest extends WifiBaseTest {
mLooper.dispatchAll();
// Trigger onInstanceFailure on the second instance
+ when(mWifiNative.getBridgedApInstances(eq(TEST_INTERFACE_NAME)))
+ .thenReturn(new ArrayList<>(
+ ImmutableList.of(TEST_FIRST_INSTANCE_NAME, TEST_SECOND_INSTANCE_NAME)),
+ new ArrayList<>(
+ ImmutableList.of(TEST_FIRST_INSTANCE_NAME)));
mSoftApHalCallbackCaptor.getValue().onInstanceFailure(TEST_SECOND_INSTANCE_NAME);
mLooper.dispatchAll();
// Verify the remove correct iface and instance
@@ -1353,33 +1362,44 @@ public class SoftApManagerTest extends WifiBaseTest {
// SoftApInfo updated
mockSoftApInfoUpdateAndVerifyAfterSapStarted(true /* bridged mode*/, true);
mLooper.dispatchAll();
-
+ when(mWifiNative.getBridgedApInstances(any()))
+ .thenReturn(null);
// Trigger onInstanceFailure on the second instance
mSoftApHalCallbackCaptor.getValue().onInstanceFailure(TEST_SECOND_INSTANCE_NAME);
mLooper.dispatchAll();
- // Verify the remove correct iface and instance
+ // Verify the remove correct iface and instance but SAP off since it can't get instances.
verify(mWifiNative).removeIfaceInstanceFromBridgedApIface(eq(TEST_INTERFACE_NAME),
eq(TEST_SECOND_INSTANCE_NAME));
mLooper.dispatchAll();
mTestSoftApInfoMap.clear();
mTestWifiClientsMap.clear();
- mTestSoftApInfoMap.put(mTestSoftApInfoOnFirstInstance.getApInstanceIdentifier(),
- mTestSoftApInfoOnFirstInstance);
- mTestWifiClientsMap.put(mTestSoftApInfoOnFirstInstance.getApInstanceIdentifier(),
- new ArrayList<WifiClient>());
- verify(mCallback, times(3)).onConnectedClientsOrInfoChanged(
+ verify(mCallback, times(4)).onConnectedClientsOrInfoChanged(
mTestSoftApInfoMap, mTestWifiClientsMap, true);
+ }
+ @Test
+ public void testHostapdInstanceFailureBeforeSecondInstanceInitialized()
+ throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
+ WifiManager.IFACE_IP_MODE_TETHERED, generateBridgedModeSoftApConfig(null),
+ mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
+ startSoftApAndVerifyEnabled(apConfig);
when(mWifiNative.getBridgedApInstances(any()))
- .thenReturn(null);
+ .thenReturn(new ArrayList<>(ImmutableList.of(TEST_FIRST_INSTANCE_NAME,
+ TEST_SECOND_INSTANCE_NAME)),
+ new ArrayList<>(ImmutableList.of(TEST_SECOND_INSTANCE_NAME)));
+ // SoftApInfo updated for first instance only
+ mockApInfoChangedEvent(mTestSoftApInfoOnFirstInstance);
+ mLooper.dispatchAll();
- // Trigger onFailure since only left 1 instance
- mSoftApHalCallbackCaptor.getValue().onFailure();
+ // Trigger onInstanceFailure on the first instance
+ mSoftApHalCallbackCaptor.getValue().onInstanceFailure(TEST_FIRST_INSTANCE_NAME);
mLooper.dispatchAll();
- mTestSoftApInfoMap.clear();
- mTestWifiClientsMap.clear();
- verify(mCallback, times(4)).onConnectedClientsOrInfoChanged(
- mTestSoftApInfoMap, mTestWifiClientsMap, true);
+ // Verify AP remains up while waiting for the second instance.
+ verify(mWifiNative).removeIfaceInstanceFromBridgedApIface(eq(TEST_INTERFACE_NAME),
+ eq(TEST_FIRST_INSTANCE_NAME));
+ verify(mWifiNative, never()).teardownInterface(TEST_INTERFACE_NAME);
}
@Test
@@ -1953,9 +1973,9 @@ public class SoftApManagerTest extends WifiBaseTest {
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
- verify(mResources)
+ verify(mResourceCache)
.getInteger(R.integer.config_wifiFrameworkSoftApShutDownTimeoutMilliseconds);
- verify(mResources)
+ verify(mResourceCache)
.getInteger(R.integer
.config_wifiFrameworkSoftApShutDownIdleInstanceInBridgedModeTimeoutMillisecond);
@@ -2517,10 +2537,6 @@ public class SoftApManagerTest extends WifiBaseTest {
verify(mWifiNative, never()).isItPossibleToCreateApIface(any());
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mFakeSoftApNotifier).dismissSoftApShutdownTimeoutExpiredNotification();
- order.verify(mWifiNative).setupInterfaceForSoftApMode(
- mWifiNativeInterfaceCallbackCaptor.capture(), eq(TEST_WORKSOURCE),
- eq(expectedConfig.getBand()), eq(expectedConfig.getBands().length > 1),
- eq(mSoftApManager), anyList());
ArgumentCaptor<SoftApConfiguration> configCaptor =
ArgumentCaptor.forClass(SoftApConfiguration.class);
if (!TextUtils.isEmpty(softApConfig.getCountryCode())
@@ -2562,6 +2578,10 @@ public class SoftApManagerTest extends WifiBaseTest {
assertThat(mSoftApManager.getSoftApModeConfiguration().getCapability().getCountryCode())
.isEqualTo("some country");
}
+ order.verify(mWifiNative).setupInterfaceForSoftApMode(
+ mWifiNativeInterfaceCallbackCaptor.capture(), eq(TEST_WORKSOURCE),
+ eq(expectedConfig.getBand()), eq(expectedConfig.getBands().length > 1),
+ eq(mSoftApManager), anyList());
order.verify(mCallback).onStateChanged(eq(new SoftApState(
WifiManager.WIFI_AP_STATE_ENABLING, 0,
softApConfig.getTetheringRequest(), TEST_INTERFACE_NAME)));
@@ -2703,7 +2723,7 @@ public class SoftApManagerTest extends WifiBaseTest {
verify(mWifiMetrics).writeSoftApStartedEvent(
eq(SoftApManager.START_RESULT_FAILURE_UNSUPPORTED_CONFIG),
any(), anyInt(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean(), anyInt(),
- anyInt());
+ anyInt(), eq(TEST_WORKSOURCE));
}
@Test
@@ -2731,7 +2751,7 @@ public class SoftApManagerTest extends WifiBaseTest {
verify(mWifiMetrics).writeSoftApStartedEvent(
eq(SoftApManager.START_RESULT_FAILURE_UNSUPPORTED_CONFIG),
any(), anyInt(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean(), anyInt(),
- anyInt());
+ anyInt(), eq(TEST_WORKSOURCE));
}
@Test
@@ -2767,7 +2787,7 @@ public class SoftApManagerTest extends WifiBaseTest {
verify(mWifiMetrics).writeSoftApStartedEvent(
eq(SoftApManager.START_RESULT_FAILURE_UNSUPPORTED_CONFIG),
any(), anyInt(), anyInt(), anyBoolean(), anyBoolean(), anyBoolean(), anyInt(),
- anyInt());
+ anyInt(), eq(TEST_WORKSOURCE));
}
@Test
@@ -3161,9 +3181,9 @@ public class SoftApManagerTest extends WifiBaseTest {
mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
- verify(mResources)
+ verify(mResourceCache)
.getInteger(R.integer.config_wifiFrameworkSoftApShutDownTimeoutMilliseconds);
- verify(mResources)
+ verify(mResourceCache)
.getInteger(R.integer
.config_wifiFrameworkSoftApShutDownIdleInstanceInBridgedModeTimeoutMillisecond);
@@ -3197,9 +3217,9 @@ public class SoftApManagerTest extends WifiBaseTest {
mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
- verify(mResources)
+ verify(mResourceCache)
.getInteger(R.integer.config_wifiFrameworkSoftApShutDownTimeoutMilliseconds);
- verify(mResources)
+ verify(mResourceCache)
.getInteger(R.integer
.config_wifiFrameworkSoftApShutDownIdleInstanceInBridgedModeTimeoutMillisecond);
@@ -3308,9 +3328,9 @@ public class SoftApManagerTest extends WifiBaseTest {
mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
- verify(mResources)
+ verify(mResourceCache)
.getInteger(R.integer.config_wifiFrameworkSoftApShutDownTimeoutMilliseconds);
- verify(mResources)
+ verify(mResourceCache)
.getInteger(R.integer
.config_wifiFrameworkSoftApShutDownIdleInstanceInBridgedModeTimeoutMillisecond);
@@ -3342,9 +3362,9 @@ public class SoftApManagerTest extends WifiBaseTest {
mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
- verify(mResources)
+ verify(mResourceCache)
.getInteger(R.integer.config_wifiFrameworkSoftApShutDownTimeoutMilliseconds);
- verify(mResources)
+ verify(mResourceCache)
.getInteger(R.integer
.config_wifiFrameworkSoftApShutDownIdleInstanceInBridgedModeTimeoutMillisecond);
@@ -3519,8 +3539,8 @@ public class SoftApManagerTest extends WifiBaseTest {
throws Exception {
assumeTrue(SdkLevel.isAtLeastS());
String worldModeCC = "00";
- when(mContext.getResources()
- .getString(R.string.config_wifiDriverWorldModeCountryCode)).thenReturn(worldModeCC);
+ when(mResourceCache.getString(R.string.config_wifiDriverWorldModeCountryCode))
+ .thenReturn(worldModeCC);
SoftApCapability testCapability = new SoftApCapability(mTestSoftApCapability);
Builder configBuilder = new SoftApConfiguration.Builder(
@@ -3759,7 +3779,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void testBridgedModeKeepIfMovingFromUnsupportedCCtoSupportedCC() throws Exception {
assumeTrue(SdkLevel.isAtLeastS());
String worldModeCC = "00";
- when(mContext.getResources().getString(R.string.config_wifiDriverWorldModeCountryCode))
+ when(mResourceCache.getString(R.string.config_wifiDriverWorldModeCountryCode))
.thenReturn(worldModeCC);
// Simulate stale world mode CC without 5GHz band
@@ -3782,7 +3802,7 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testWaitForDriverCountryCode() throws Exception {
- when(mResources.getBoolean(
+ when(mResourceCache.getBoolean(
R.bool.config_wifiDriverSupportedNl80211RegChangedEvent)).thenReturn(true);
mIsDriverSupportedRegChangedEvent = true;
SoftApModeConfiguration apConfig =
@@ -3793,7 +3813,7 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testWaitForDriverCountryCodeTimedOut() throws Exception {
- when(mResources.getBoolean(
+ when(mResourceCache.getBoolean(
R.bool.config_wifiDriverSupportedNl80211RegChangedEvent)).thenReturn(true);
mIsDriverSupportedRegChangedEvent = true;
SoftApModeConfiguration apConfig =
@@ -3815,7 +3835,7 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testWaitForDriverCountryCodeWhenNoInitialCountryCodeFor5GHz() throws Exception {
- when(mResources.getBoolean(
+ when(mResourceCache.getBoolean(
R.bool.config_wifiDriverSupportedNl80211RegChangedEvent)).thenReturn(true);
mIsDriverSupportedRegChangedEvent = true;
Builder configBuilder = new SoftApConfiguration.Builder();
@@ -3832,7 +3852,7 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testUpdateCountryCodeWhenConfigDisabled() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifiSoftApDynamicCountryCodeUpdateSupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftApDynamicCountryCodeUpdateSupported))
.thenReturn(false);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
@@ -3846,7 +3866,7 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testUpdateCountryCodeWhenConfigEnabled() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifiSoftApDynamicCountryCodeUpdateSupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftApDynamicCountryCodeUpdateSupported))
.thenReturn(true);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
@@ -3860,7 +3880,7 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testUpdateSameCountryCodeWhenConfigEnabled() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifiSoftApDynamicCountryCodeUpdateSupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftApDynamicCountryCodeUpdateSupported))
.thenReturn(true);
SoftApModeConfiguration apConfig =
new SoftApModeConfiguration(WifiManager.IFACE_IP_MODE_TETHERED, null,
@@ -3876,7 +3896,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void testFallbackToSingleModeDueToStaExistButStaWithBridgedApNotSupportedByOverlay()
throws Exception {
assumeTrue(SdkLevel.isAtLeastS());
- when(mResources.getBoolean(R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported))
.thenReturn(false);
Builder configBuilder = new SoftApConfiguration.Builder(
generateBridgedModeSoftApConfig(null));
@@ -3894,7 +3914,7 @@ public class SoftApManagerTest extends WifiBaseTest {
public void testFallbackToSingleModeDueToStaExistButStaWithBridgedApNotSupportedByDriver()
throws Exception {
assumeTrue(SdkLevel.isAtLeastS());
- when(mResources.getBoolean(R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiStaWithBridgedSoftApConcurrencySupported))
.thenReturn(true);
mApBridgeWithStaIfaceCombinationSupported = false;
Builder configBuilder = new SoftApConfiguration.Builder(
@@ -3963,7 +3983,7 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testSchedulesTimeoutTimerWhenPluggedChanged() throws Exception {
assumeTrue(SdkLevel.isAtLeastT());
- when(mResources.getBoolean(R.bool
+ when(mResourceCache.getBoolean(R.bool
.config_wifiFrameworkSoftApDisableBridgedModeShutdownIdleInstanceWhenCharging))
.thenReturn(true);
@@ -3972,9 +3992,9 @@ public class SoftApManagerTest extends WifiBaseTest {
mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig);
- verify(mResources)
+ verify(mResourceCache)
.getInteger(R.integer.config_wifiFrameworkSoftApShutDownTimeoutMilliseconds);
- verify(mResources)
+ verify(mResourceCache)
.getInteger(R.integer
.config_wifiFrameworkSoftApShutDownIdleInstanceInBridgedModeTimeoutMillisecond);
@@ -4043,7 +4063,7 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testStartSoftApRemoves11BEIfNotSupportedByDeviceCapabilities() throws Exception {
assumeTrue(SdkLevel.isAtLeastT());
- when(mResources.getBoolean(R.bool.config_wifiSoftapIeee80211beSupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftapIeee80211beSupported))
.thenReturn(true);
when(mDeviceWiphyCapabilities.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11BE))
.thenReturn(false);
@@ -4067,7 +4087,7 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testStartSoftApRemoves11BEIfNotSupportedByOverlay() throws Exception {
assumeTrue(SdkLevel.isAtLeastT());
- when(mResources.getBoolean(R.bool.config_wifiSoftapIeee80211beSupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftapIeee80211beSupported))
.thenReturn(false);
when(mDeviceWiphyCapabilities.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11BE))
.thenReturn(true);
@@ -4091,7 +4111,7 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testStartSoftApRemoves11BEInWpa2()throws Exception {
assumeTrue(SdkLevel.isAtLeastT());
- when(mResources.getBoolean(R.bool.config_wifiSoftapIeee80211beSupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftapIeee80211beSupported))
.thenReturn(true);
when(mDeviceWiphyCapabilities.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11BE))
.thenReturn(true);
@@ -4117,9 +4137,9 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testStartSoftApRemoves11BEInBridgedModeIfNotSupportedByOverlay()throws Exception {
assumeTrue(SdkLevel.isAtLeastT());
- when(mResources.getBoolean(R.bool.config_wifiSoftapIeee80211beSupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftapIeee80211beSupported))
.thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiSoftApSingleLinkMloInBridgedModeSupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftApSingleLinkMloInBridgedModeSupported))
.thenReturn(false);
when(mDeviceWiphyCapabilities.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11BE))
.thenReturn(true);
@@ -4146,9 +4166,9 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testStartSoftApInBridgedMode11BEConfiguration()throws Exception {
assumeTrue(SdkLevel.isAtLeastT());
- when(mResources.getBoolean(R.bool.config_wifiSoftapIeee80211beSupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftapIeee80211beSupported))
.thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiSoftApSingleLinkMloInBridgedModeSupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftApSingleLinkMloInBridgedModeSupported))
.thenReturn(true);
when(mDeviceWiphyCapabilities.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11BE))
.thenReturn(true);
@@ -4173,7 +4193,7 @@ public class SoftApManagerTest extends WifiBaseTest {
@Test
public void testStartSoftApInSingleAp11BEConfiguration()throws Exception {
assumeTrue(SdkLevel.isAtLeastT());
- when(mResources.getBoolean(R.bool.config_wifiSoftapIeee80211beSupported))
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftapIeee80211beSupported))
.thenReturn(true);
when(mDeviceWiphyCapabilities.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11BE))
.thenReturn(true);
@@ -4189,4 +4209,112 @@ public class SoftApManagerTest extends WifiBaseTest {
mTestSoftApCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
startSoftApAndVerifyEnabled(apConfig, configBuilder.build(), false);
}
+
+ @Test
+ public void testStartSoftApAutoUpgradeTo2g5gDbs() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mResourceCache.getBoolean(
+ R.bool.config_wifiSoftapUpgradeTetheredTo2g5gBridgedIfBandsAreSubset))
+ .thenReturn(true);
+ int[] dual_bands = {SoftApConfiguration.BAND_2GHZ,
+ SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ};
+
+ SoftApConfiguration config = new SoftApConfiguration.Builder().setSsid(TEST_SSID)
+ .setSsid(TEST_SSID)
+ .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ
+ | SoftApConfiguration.BAND_6GHZ)
+ .build();
+ SoftApConfiguration dualBandConfig = new SoftApConfiguration.Builder(config)
+ .setBands(dual_bands)
+ .build();
+
+ SoftApCapability no6GhzCapability = new SoftApCapability(mTestSoftApCapability);
+ no6GhzCapability.setSupportedChannelList(WifiScanner.WIFI_BAND_6_GHZ, new int[0]);
+ SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
+ WifiManager.IFACE_IP_MODE_TETHERED, config,
+ no6GhzCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
+ startSoftApAndVerifyEnabled(apConfig, dualBandConfig, false);
+ }
+
+ @Test
+ public void testStartSoftApDoesNotAutoUpgradeTo2g5gDbsWhen6GhzAvailable() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mResourceCache.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftap6ghzSupported)).thenReturn(true);
+ when(mResourceCache.getBoolean(
+ R.bool.config_wifiSoftapUpgradeTetheredTo2g5gBridgedIfBandsAreSubset))
+ .thenReturn(true);
+
+ SoftApConfiguration config = new SoftApConfiguration.Builder().setSsid(TEST_SSID)
+ .setSsid(TEST_SSID)
+ .setPassphrase("somepassword", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
+ .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ
+ | SoftApConfiguration.BAND_6GHZ)
+ .build();
+
+ SoftApCapability with6GhzCapability = new SoftApCapability(mTestSoftApCapability);
+ with6GhzCapability.setSupportedChannelList(
+ SoftApConfiguration.BAND_6GHZ, new int[]{5, 21});
+ SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
+ WifiManager.IFACE_IP_MODE_TETHERED, config,
+ with6GhzCapability, TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
+ startSoftApAndVerifyEnabled(apConfig, config, false);
+ }
+
+ @Test
+ public void testStartSoftApAutoUpgradeTo2g5gDbsWithCountryCodeChange() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mResourceCache.getBoolean(
+ R.bool.config_wifiDriverSupportedNl80211RegChangedEvent)).thenReturn(true);
+ mIsDriverSupportedRegChangedEvent = true;
+ when(mResourceCache.getBoolean(
+ R.bool.config_wifiSoftapUpgradeTetheredTo2g5gBridgedIfBandsAreSubset))
+ .thenReturn(true);
+ int[] dual_bands = {SoftApConfiguration.BAND_2GHZ,
+ SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ};
+
+ SoftApConfiguration config = new SoftApConfiguration.Builder().setSsid(TEST_SSID)
+ .setSsid(TEST_SSID)
+ .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ
+ | SoftApConfiguration.BAND_6GHZ)
+ .build();
+ SoftApConfiguration dualBandConfig = new SoftApConfiguration.Builder(config)
+ .setBands(dual_bands)
+ .build();
+
+ when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ))
+ .thenReturn(new int[0]);
+ SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
+ WifiManager.IFACE_IP_MODE_TETHERED, config,
+ mTestSoftApCapability, "Not " + TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
+ startSoftApAndVerifyEnabled(apConfig, dualBandConfig, false);
+ }
+
+ @Test
+ public void testStartSoftApDoesNotAutoUpgradeTo2g5gDbsWhen6GhzAvailableWithCountryCodeChange()
+ throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mResourceCache.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftap6ghzSupported)).thenReturn(true);
+ when(mResourceCache.getBoolean(
+ R.bool.config_wifiDriverSupportedNl80211RegChangedEvent)).thenReturn(true);
+ mIsDriverSupportedRegChangedEvent = true;
+ when(mResourceCache.getBoolean(
+ R.bool.config_wifiSoftapUpgradeTetheredTo2g5gBridgedIfBandsAreSubset))
+ .thenReturn(true);
+
+ SoftApConfiguration config = new SoftApConfiguration.Builder().setSsid(TEST_SSID)
+ .setSsid(TEST_SSID)
+ .setPassphrase("somepassword", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
+ .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ
+ | SoftApConfiguration.BAND_6GHZ)
+ .build();
+
+ when(mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ))
+ .thenReturn(ALLOWED_6G_FREQS);
+ SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
+ WifiManager.IFACE_IP_MODE_TETHERED, config,
+ mTestSoftApCapability, "Not " + TEST_COUNTRY_CODE, TEST_TETHERING_REQUEST);
+ startSoftApAndVerifyEnabled(apConfig, config, false);
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SoftApStoreDataTest.java b/service/tests/wifitests/src/com/android/server/wifi/SoftApStoreDataTest.java
index 108d4faf6f..b87832c669 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SoftApStoreDataTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SoftApStoreDataTest.java
@@ -25,13 +25,16 @@ import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.validateMockitoUsage;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
import android.app.test.MockAnswerUtil;
import android.content.Context;
import android.net.MacAddress;
import android.net.wifi.SoftApConfiguration;
+import android.net.wifi.SoftApInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiMigration;
import android.net.wifi.WifiSsid;
@@ -40,12 +43,14 @@ import android.util.Xml;
import androidx.test.filters.SmallTest;
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.internal.util.FastXmlSerializer;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.util.EncryptedData;
import com.android.server.wifi.util.InformationElementUtil;
import com.android.server.wifi.util.SettingsMigrationDataHolder;
import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
+import com.android.wifi.flags.Flags;
import org.junit.After;
import org.junit.Before;
@@ -53,6 +58,7 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
@@ -108,6 +114,9 @@ public class SoftApStoreDataTest extends WifiBaseTest {
private static final boolean TEST_80211BE_ENABLED = false;
private static final boolean TEST_USER_CONFIGURATION = false;
private static final String TEST_TWO_VENDOR_ELEMENTS_HEX = "DD04AABBCCDDDD0401020304";
+ private static final int TEST_MAX_CHANNEL_WIDTH = SoftApInfo.CHANNEL_WIDTH_40MHZ;
+ private MockitoSession mSession;
+
private static final String TEST_CONFIG_STRING_FROM_WIFICONFIGURATION =
"<string name=\"WifiSsid\">"
@@ -293,6 +302,11 @@ public class SoftApStoreDataTest extends WifiBaseTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ // Mock WifiMigration to avoid calling into its static methods
+ mSession = ExtendedMockito.mockitoSession()
+ .mockStatic(Flags.class, withSettings().lenient())
+ .mockStatic(WifiMigration.class, withSettings().lenient())
+ .startMocking();
when(mSettingsMigrationDataHolder.retrieveData())
.thenReturn(mOemMigrationData);
when(mOemMigrationData.isSoftApTimeoutEnabled()).thenReturn(true);
@@ -312,6 +326,7 @@ public class SoftApStoreDataTest extends WifiBaseTest {
return mEncryptedDataMap.get(data);
}
}).when(mWifiConfigStoreEncryptionUtil).decrypt(any());
+ when(Flags.softapConfigStoreMaxChannelWidth()).thenReturn(false);
}
/**
@@ -321,6 +336,10 @@ public class SoftApStoreDataTest extends WifiBaseTest {
public void cleanup() {
TEST_BLOCKEDLIST.clear();
TEST_ALLOWEDLIST.clear();
+ validateMockitoUsage();
+ if (mSession != null) {
+ mSession.finishMocking();
+ }
}
/**
@@ -623,18 +642,16 @@ public class SoftApStoreDataTest extends WifiBaseTest {
assertEquals(softApConfig.getBand(), TEST_BAND);
}
- /**
- * Verify that the store data is serialized/deserialized correctly.
- *
- * @throws Exception
- */
- @Test
- public void serializeDeserializeSoftAp() throws Exception {
+ private void serializeDeserializeSoftAp(int expectedMaxChannelWidth, int actualMaxChannelWidth)
+ throws Exception {
SoftApConfiguration.Builder softApConfigBuilder = new SoftApConfiguration.Builder();
softApConfigBuilder.setSsid(TEST_SSID);
softApConfigBuilder.setPassphrase(TEST_PASSPHRASE,
SoftApConfiguration.SECURITY_TYPE_WPA2_PSK);
softApConfigBuilder.setBand(TEST_BAND);
+ if (SdkLevel.isAtLeastT()) {
+ softApConfigBuilder.setMaxChannelBandwidth(actualMaxChannelWidth);
+ }
SoftApConfiguration softApConfig = softApConfigBuilder.build();
// Serialize first.
@@ -657,6 +674,30 @@ public class SoftApStoreDataTest extends WifiBaseTest {
assertEquals(softApConfig.isHiddenSsid(), softApConfigDeserialized.isHiddenSsid());
assertEquals(softApConfig.getBand(), softApConfigDeserialized.getBand());
assertEquals(softApConfig.getChannel(), softApConfigDeserialized.getChannel());
+ if (SdkLevel.isAtLeastT()) {
+ assertEquals(expectedMaxChannelWidth,
+ softApConfigDeserialized.getMaxChannelBandwidth());
+ }
+ }
+
+ /**
+ * Verify that the store data is serialized/deserialized correctly with the feature
+ * Flags.softapConfigStoreMaxChannelWidth() disabled.
+ */
+ @Test
+ public void serializeDeserializeSoftAp() throws Exception {
+ when(Flags.softapConfigStoreMaxChannelWidth()).thenReturn(false);
+ serializeDeserializeSoftAp(SoftApInfo.CHANNEL_WIDTH_AUTO, TEST_MAX_CHANNEL_WIDTH);
+ }
+
+ /**
+ * Verify that the store data is serialized/deserialized correctly with the feature
+ * Flags.softapConfigStoreMaxChannelWidth() enabled.
+ */
+ @Test
+ public void serializeDeserializeSoftApWithMaxChannelWidth() throws Exception {
+ when(Flags.softapConfigStoreMaxChannelWidth()).thenReturn(true);
+ serializeDeserializeSoftAp(TEST_MAX_CHANNEL_WIDTH, TEST_MAX_CHANNEL_WIDTH);
}
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java
index 8747683c77..57e0c128f5 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java
@@ -24,9 +24,14 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_MBO;
import static android.net.wifi.WifiManager.WIFI_FEATURE_OCE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_TRUST_ON_FIRST_USE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WAPI;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
+import static android.os.Build.VERSION.SDK_INT;
+
+import static com.android.server.wifi.util.GeneralUtil.getCapabilityIndex;
+import static com.android.server.wifi.util.GeneralUtil.longToBitset;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -52,9 +57,11 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.validateMockitoUsage;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -114,7 +121,9 @@ import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiMigration;
import android.net.wifi.WifiSsid;
+import android.net.wifi.flags.Flags;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
@@ -124,6 +133,7 @@ import android.text.TextUtils;
import androidx.test.filters.SmallTest;
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.MboOceController.BtmFrameData;
import com.android.server.wifi.hal.HalTestUtils;
@@ -132,6 +142,7 @@ import com.android.server.wifi.hotspot2.IconEvent;
import com.android.server.wifi.hotspot2.WnmData;
import com.android.server.wifi.util.NativeUtil;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@@ -139,6 +150,7 @@ import org.mockito.Captor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
import org.mockito.stubbing.Answer;
import java.net.InetAddress;
@@ -178,6 +190,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
private static final String HS20_URL = "http://blahblah";
private static final long PMK_CACHE_EXPIRATION_IN_SEC = 1024;
private static final byte[] CONNECTED_MAC_ADDRESS_BYTES = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
+ private static final long TIME_START_MS = 0L;
private @Mock ISupplicant mISupplicantMock;
private @Mock IBinder mServiceBinderMock;
@@ -200,6 +213,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
IfaceInfo[] mIfaceInfoList;
ISupplicantStaIfaceCallback mISupplicantStaIfaceCallback;
+ private MockitoSession mSession;
private TestLooper mLooper = new TestLooper();
private Handler mHandler = null;
private SupplicantStaIfaceHalSpy mDut;
@@ -244,6 +258,11 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ // Mock WifiMigration to avoid calling into its static methods
+ mSession = ExtendedMockito.mockitoSession()
+ .mockStatic(Flags.class, withSettings().lenient())
+ .mockStatic(WifiMigration.class, withSettings().lenient())
+ .startMocking();
mIfaceInfoList = new IfaceInfo[3];
mIfaceInfoList[0] = createIfaceInfo(IfaceType.STA, WLAN0_IFACE_NAME);
mIfaceInfoList[1] = createIfaceInfo(IfaceType.STA, WLAN1_IFACE_NAME);
@@ -263,9 +282,18 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
return ssids;
});
when(mWifiInjector.getSettingsConfigStore()).thenReturn(mWifiSettingsConfigStore);
+ when(Flags.legacyKeystoreToWifiBlobstoreMigrationReadOnly()).thenReturn(true);
mDut = new SupplicantStaIfaceHalSpy();
}
+ @After
+ public void cleanup() {
+ validateMockitoUsage();
+ if (mSession != null) {
+ mSession.finishMocking();
+ }
+ }
+
/**
* Sunny day scenario for SupplicantStaIfaceHal initialization
* Asserts successful initialization
@@ -1409,6 +1437,9 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
public void testIeDiffers() throws Exception {
executeAndValidateInitializationSequence();
assertNotNull(mISupplicantStaIfaceCallback);
+ executeAndValidateConnectSequenceWithKeyMgmt(
+ SUPPLICANT_NETWORK_ID, false, TRANSLATED_SUPPLICANT_SSID.toString(),
+ WifiConfiguration.SECURITY_TYPE_PSK, null, false);
int reasonCode = StaIfaceReasonCode.IE_IN_4WAY_DIFFERS;
@@ -1433,6 +1464,9 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
public void testApBusy() throws Exception {
executeAndValidateInitializationSequence();
assertNotNull(mISupplicantStaIfaceCallback);
+ executeAndValidateConnectSequenceWithKeyMgmt(
+ SUPPLICANT_NETWORK_ID, false, TRANSLATED_SUPPLICANT_SSID.toString(),
+ WifiConfiguration.SECURITY_TYPE_PSK, null, false);
int reasonCode = StaIfaceReasonCode.DISASSOC_AP_BUSY;
@@ -1442,7 +1476,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
SUPPLICANT_NETWORK_ID,
NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(SUPPLICANT_SSID)), false);
mISupplicantStaIfaceCallback.onDisconnected(
- NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
+ NativeUtil.macAddressToByteArray(BSSID), false, reasonCode);
verify(mWifiMonitor, never()).broadcastAuthenticationFailureEvent(any(), anyInt(),
anyInt(), any(), any());
}
@@ -1798,12 +1832,12 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
/**
* Helper function for tests involving getAdvancedCapabilities.
*/
- private void checkKeyMgmtCapabilities(int serviceCapabilities, long expectedCapabilities)
+ private void checkKeyMgmtCapabilities(int serviceCapabilities, BitSet expectedCapabilities)
throws Exception {
executeAndValidateInitializationSequence();
doReturn(serviceCapabilities).when(mISupplicantStaIfaceMock).getKeyMgmtCapabilities();
expectedCapabilities = addDefaultKeyMgmtCap(expectedCapabilities);
- assertEquals(expectedCapabilities, mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
+ assertTrue(expectedCapabilities.equals(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME)));
}
/**
@@ -1811,7 +1845,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
*/
@Test
public void testGetKeyMgmtCapabilitiesWpa3Sae() throws Exception {
- checkKeyMgmtCapabilities(KeyMgmtMask.SAE, WIFI_FEATURE_WPA3_SAE);
+ checkKeyMgmtCapabilities(KeyMgmtMask.SAE, longToBitset(WIFI_FEATURE_WPA3_SAE));
}
/**
@@ -1819,7 +1853,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
*/
@Test
public void testGetKeyMgmtCapabilitiesWpa3SuiteB() throws Exception {
- checkKeyMgmtCapabilities(KeyMgmtMask.SUITE_B_192, WIFI_FEATURE_WPA3_SUITE_B);
+ checkKeyMgmtCapabilities(KeyMgmtMask.SUITE_B_192, longToBitset(WIFI_FEATURE_WPA3_SUITE_B));
}
/**
@@ -1827,7 +1861,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
*/
@Test
public void testGetKeyMgmtCapabilitiesOwe() throws Exception {
- checkKeyMgmtCapabilities(KeyMgmtMask.OWE, WIFI_FEATURE_OWE);
+ checkKeyMgmtCapabilities(KeyMgmtMask.OWE, longToBitset(WIFI_FEATURE_OWE));
}
/**
@@ -1836,7 +1870,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
@Test
public void testGetKeyMgmtCapabilitiesOweAndSae() throws Exception {
checkKeyMgmtCapabilities(KeyMgmtMask.OWE | KeyMgmtMask.SAE,
- WIFI_FEATURE_OWE | WIFI_FEATURE_WPA3_SAE);
+ longToBitset(WIFI_FEATURE_OWE | WIFI_FEATURE_WPA3_SAE));
}
/**
@@ -1844,8 +1878,8 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
*/
@Test
public void testGetKeyMgmtCapabilitiesDpp() throws Exception {
- checkKeyMgmtCapabilities(KeyMgmtMask.DPP, WIFI_FEATURE_DPP
- | WIFI_FEATURE_DPP_ENROLLEE_RESPONDER);
+ checkKeyMgmtCapabilities(KeyMgmtMask.DPP,
+ longToBitset(WIFI_FEATURE_DPP | WIFI_FEATURE_DPP_ENROLLEE_RESPONDER));
}
/**
@@ -1853,7 +1887,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
*/
@Test
public void testGetKeyMgmtCapabilitiesWapi() throws Exception {
- checkKeyMgmtCapabilities(KeyMgmtMask.WAPI_PSK, WIFI_FEATURE_WAPI);
+ checkKeyMgmtCapabilities(KeyMgmtMask.WAPI_PSK, longToBitset(WIFI_FEATURE_WAPI));
}
/**
@@ -1861,7 +1895,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
*/
@Test
public void testGetKeyMgmtCapabilitiesFilsSha256() throws Exception {
- checkKeyMgmtCapabilities(KeyMgmtMask.FILS_SHA256, WIFI_FEATURE_FILS_SHA256);
+ checkKeyMgmtCapabilities(KeyMgmtMask.FILS_SHA256, longToBitset(WIFI_FEATURE_FILS_SHA256));
}
/**
@@ -1869,7 +1903,7 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
*/
@Test
public void testGetKeyMgmtCapabilitiesFilsSha384() throws Exception {
- checkKeyMgmtCapabilities(KeyMgmtMask.FILS_SHA384, WIFI_FEATURE_FILS_SHA384);
+ checkKeyMgmtCapabilities(KeyMgmtMask.FILS_SHA384, longToBitset(WIFI_FEATURE_FILS_SHA384));
}
/**
@@ -2133,7 +2167,8 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
executeAndValidateInitializationSequence();
doReturn(WpaDriverCapabilitiesMask.MBO).when(mISupplicantStaIfaceMock)
.getWpaDriverCapabilities();
- assertEquals(WIFI_FEATURE_MBO, mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_MBO)
+ .equals(mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME)));
}
/**
@@ -2144,8 +2179,8 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
executeAndValidateInitializationSequence();
doReturn(WpaDriverCapabilitiesMask.MBO | WpaDriverCapabilitiesMask.OCE)
.when(mISupplicantStaIfaceMock).getWpaDriverCapabilities();
- assertEquals(WIFI_FEATURE_MBO | WIFI_FEATURE_OCE,
- mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_MBO | WIFI_FEATURE_OCE)
+ .equals(mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME)));
}
/**
@@ -2156,8 +2191,8 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
executeAndValidateInitializationSequence();
doReturn(WpaDriverCapabilitiesMask.TRUST_ON_FIRST_USE)
.when(mISupplicantStaIfaceMock).getWpaDriverCapabilities();
- assertEquals(WifiManager.WIFI_FEATURE_TRUST_ON_FIRST_USE,
- mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_TRUST_ON_FIRST_USE)
+ .equals(mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME)));
}
/**
@@ -2263,30 +2298,6 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
}
/**
- * Tests the handling of incorrect network passwords when
- * onStateChanged() is used, edge case.
- *
- * If the disconnect reason is "IE in 4way differs", do not call it a password mismatch.
- */
- @Test
- public void testIeDiffersWhenOnStateChangedIsUsed() throws Exception {
- executeAndValidateInitializationSequence();
- assertNotNull(mISupplicantStaIfaceCallback);
-
- int reasonCode = StaIfaceReasonCode.IE_IN_4WAY_DIFFERS;
-
- mISupplicantStaIfaceCallback.onStateChanged(
- StaIfaceCallbackState.FOURWAY_HANDSHAKE,
- NativeUtil.macAddressToByteArray(BSSID),
- SUPPLICANT_NETWORK_ID,
- NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(SUPPLICANT_SSID)), false);
- mISupplicantStaIfaceCallback.onDisconnected(
- NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
- verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt(),
- anyInt(), any(), any());
- }
-
- /**
* Tests the handling of state change notification to
* completed (with FILS HLP IE sent) after configuring a network.
*/
@@ -2374,6 +2385,16 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
assertNotNull(mISupplicantStaIfaceCallback);
executeAndValidateConnectSequence(SUPPLICANT_NETWORK_ID, false,
TRANSLATED_SUPPLICANT_SSID.toString());
+
+ // Do not broadcast NETWORK_NOT_FOUND for the specified duration.
+ mISupplicantStaIfaceCallback.onNetworkNotFound(NativeUtil.byteArrayFromArrayList(
+ NativeUtil.decodeSsid(SUPPLICANT_SSID)));
+ verify(mWifiMonitor, never()).broadcastNetworkNotFoundEvent(
+ eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
+
+ // NETWORK_NOT_FOUND should be broadcasted after the duration.
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(TIME_START_MS
+ + SupplicantStaIfaceHalHidlImpl.IGNORE_NETWORK_NOT_FOUND_DURATION_MS + 1);
mISupplicantStaIfaceCallback.onNetworkNotFound(NativeUtil.byteArrayFromArrayList(
NativeUtil.decodeSsid(SUPPLICANT_SSID)));
@@ -2399,28 +2420,75 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
});
executeAndValidateConnectSequence(SUPPLICANT_NETWORK_ID, false,
TRANSLATED_SUPPLICANT_SSID.toString());
+
+ // SSID was not found, but don't broadcast NETWORK_NOT_FOUND since we're still in
+ // the ignore duration.
mISupplicantStaIfaceCallback.onNetworkNotFound(NativeUtil.byteArrayFromArrayList(
NativeUtil.decodeSsid(SUPPLICANT_SSID)));
+ verify(mWifiMonitor, never()).broadcastNetworkNotFoundEvent(
+ eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
+ validateConnectSequence(false, 1, TRANSLATED_SUPPLICANT_SSID.toString());
- // Validate that we initiated another connect sequence to the fallback SUPPLICANT_SSID.
+ // Receive NETWORK_NOT_FOUND after the ignore duration. This should trigger a connection
+ // to the fallback without broadcasting NETWORK_NOT_FOUND yet.
+ long time = TIME_START_MS
+ + SupplicantStaIfaceHalHidlImpl.IGNORE_NETWORK_NOT_FOUND_DURATION_MS;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(time);
+ mISupplicantStaIfaceCallback.onNetworkNotFound(NativeUtil.byteArrayFromArrayList(
+ NativeUtil.decodeSsid(TRANSLATED_SUPPLICANT_SSID.toString())));
verify(mWifiMonitor, never()).broadcastNetworkNotFoundEvent(
eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
validateConnectSequence(false, 2, SUPPLICANT_SSID);
- // Fallback SSID was not found, finally broadcast NETWORK_NOT_FOUND and try the first SSID
- // again.
+ // Fallback SSID was not found, but don't broadcast NETWORK_NOT_FOUND because we're in the
+ // ignore duration for the fallback connection.
+ mISupplicantStaIfaceCallback.onNetworkNotFound(NativeUtil.byteArrayFromArrayList(
+ NativeUtil.decodeSsid(SUPPLICANT_SSID)));
+ verify(mWifiMonitor, never()).broadcastNetworkNotFoundEvent(
+ eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
+ validateConnectSequence(false, 2, SUPPLICANT_SSID);
+
+ // Receive NETWORK_NOT_FOUND after the new ignore duration. This should trigger a connection
+ // to the first SSID and finally broadcast the NETWORK_NOT_FOUND.
+ time += SupplicantStaIfaceHalHidlImpl.IGNORE_NETWORK_NOT_FOUND_DURATION_MS;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(time);
mISupplicantStaIfaceCallback.onNetworkNotFound(NativeUtil.byteArrayFromArrayList(
NativeUtil.decodeSsid(SUPPLICANT_SSID)));
verify(mWifiMonitor).broadcastNetworkNotFoundEvent(
eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
validateConnectSequence(false, 3, TRANSLATED_SUPPLICANT_SSID.toString());
+ }
- // First SSID not found, try the fallback without broadcasting NETWORK_NOT_FOUND.
+ /**
+ * Tests that network not found notification won't trigger connecting to the fallback SSIDs if
+ * the network has been disabled.
+ */
+ @Test
+ public void testNetworkNotFoundCallbackDoesNotConnectToFallbackAfterDisabled()
+ throws Exception {
+ when(mSupplicantStaNetworkMock.disable()).thenReturn(true);
+ executeAndValidateInitializationSequence();
+ assertNotNull(mISupplicantStaIfaceCallback);
+ // Setup mocks to return two possible original SSIDs. We will pick
+ // TRANSLATED_SUPPLICANT_SSID as the first SSID to try.
+ when(mSsidTranslator.getAllPossibleOriginalSsids(TRANSLATED_SUPPLICANT_SSID)).thenAnswer(
+ (Answer<List<WifiSsid>>) invocation -> {
+ List<WifiSsid> ssids = new ArrayList<>();
+ ssids.add(TRANSLATED_SUPPLICANT_SSID);
+ ssids.add(WifiSsid.fromString(SUPPLICANT_SSID));
+ return ssids;
+ });
+ executeAndValidateConnectSequence(SUPPLICANT_NETWORK_ID, false,
+ TRANSLATED_SUPPLICANT_SSID.toString());
+
+ // Disable the current network and issue a NETWORK_NOT_FOUND
+ assertTrue(mDut.disableCurrentNetwork(WLAN0_IFACE_NAME));
+ verify(mSupplicantStaNetworkMock).disable();
mISupplicantStaIfaceCallback.onNetworkNotFound(NativeUtil.byteArrayFromArrayList(
- NativeUtil.decodeSsid(TRANSLATED_SUPPLICANT_SSID.toString())));
- verify(mWifiMonitor, times(1)).broadcastNetworkNotFoundEvent(
- eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
- validateConnectSequence(false, 4, SUPPLICANT_SSID);
+ NativeUtil.decodeSsid(SUPPLICANT_SSID)));
+
+ // Validate that we don't initiate another connect sequence.
+ validateConnectSequence(false, 1, TRANSLATED_SUPPLICANT_SSID.toString());
}
/**
@@ -2786,9 +2854,10 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
* Indicate support for key mgmt features supported by default in HIDL HAL V1.4,
* i.e. the latest HIDL version before the conversion to AIDL.
*/
- private long addDefaultKeyMgmtCap(long capabilities) {
- return capabilities | WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS
- | WIFI_FEATURE_DECORATED_IDENTITY;
+ private BitSet addDefaultKeyMgmtCap(BitSet capabilities) {
+ capabilities.set(getCapabilityIndex(WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS));
+ capabilities.set(getCapabilityIndex(WIFI_FEATURE_DECORATED_IDENTITY));
+ return capabilities;
}
/**
@@ -3396,4 +3465,15 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest {
mDut.resendMscs(WLAN0_IFACE_NAME);
verify(mISupplicantStaIfaceMock, times(2)).configureMscs(halParamsCaptor.capture());
}
+
+ /**
+ * Verify that the Legacy Keystore migration only occurs once during the initial setup.
+ */
+ @Test
+ public void testLegacyKeystoreMigration() throws Exception {
+ assumeTrue(SDK_INT >= 36);
+ assertFalse(mDut.mHasMigratedLegacyKeystoreAliases);
+ executeAndValidateInitializationSequence();
+ assertTrue(mDut.mHasMigratedLegacyKeystoreAliases);
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java
index 5d4507c69d..4ba62fcd06 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalHidlImplTest.java
@@ -26,6 +26,9 @@ import static android.net.wifi.WifiManager.WIFI_FEATURE_WAPI;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
+import static com.android.server.wifi.util.GeneralUtil.getCapabilityIndex;
+import static com.android.server.wifi.util.GeneralUtil.longToBitset;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -107,6 +110,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -136,6 +140,7 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
private static final long PMK_CACHE_EXPIRATION_IN_SEC = 1024;
private static final byte[] CONNECTED_MAC_ADDRESS_BYTES =
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
+ private static final long TIME_START_MS = 0L;
private @Mock IServiceManager mServiceManagerMock;
private @Mock ISupplicant mISupplicantMock;
@@ -312,6 +317,7 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
ssids.add(TRANSLATED_SUPPLICANT_SSID);
return ssids;
});
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(TIME_START_MS);
mDut = new SupplicantStaIfaceHalSpy();
}
@@ -1638,6 +1644,9 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
public void testIeDiffers() throws Exception {
executeAndValidateInitializationSequence();
assertNotNull(mISupplicantStaIfaceCallback);
+ executeAndValidateConnectSequenceWithKeyMgmt(
+ SUPPLICANT_NETWORK_ID, false, TRANSLATED_SUPPLICANT_SSID.toString(),
+ WifiConfiguration.SECURITY_TYPE_PSK, null, false);
int reasonCode = ISupplicantStaIfaceCallback.ReasonCode.IE_IN_4WAY_DIFFERS;
@@ -1662,6 +1671,9 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
public void testApBusy() throws Exception {
executeAndValidateInitializationSequence();
assertNotNull(mISupplicantStaIfaceCallback);
+ executeAndValidateConnectSequenceWithKeyMgmt(
+ SUPPLICANT_NETWORK_ID, false, TRANSLATED_SUPPLICANT_SSID.toString(),
+ WifiConfiguration.SECURITY_TYPE_PSK, null, false);
int reasonCode = ISupplicantStaIfaceCallback.ReasonCode.DISASSOC_AP_BUSY;
@@ -1671,7 +1683,7 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
SUPPLICANT_NETWORK_ID,
NativeUtil.decodeSsid(SUPPLICANT_SSID));
mISupplicantStaIfaceCallback.onDisconnected(
- NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
+ NativeUtil.macAddressToByteArray(BSSID), false, reasonCode);
verify(mWifiMonitor, never()).broadcastAuthenticationFailureEvent(any(), anyInt(),
anyInt(), any(), any());
}
@@ -2179,7 +2191,7 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
}
/**
- * Test get advanced capabilities API on old HAL, should return 0 (not supported)
+ * Test get advanced capabilities API on old HAL, should return an empty BitSet (not supported)
*/
@Test
public void testGetKeyMgmtCapabilitiesOldHal() throws Exception {
@@ -2187,7 +2199,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
executeAndValidateInitializationSequenceV1_1(false, false);
- assertTrue(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME) == 0);
+ assertTrue(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME).equals(new BitSet()));
+
}
/**
@@ -2205,7 +2218,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
.getKeyMgmtCapabilitiesCallback.class));
- assertEquals(WIFI_FEATURE_WPA3_SAE, mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_WPA3_SAE)
+ .equals(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME)));
}
/**
@@ -2223,8 +2237,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
.getKeyMgmtCapabilitiesCallback.class));
- assertEquals(WIFI_FEATURE_WPA3_SUITE_B,
- mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_WPA3_SUITE_B)
+ .equals(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME)));
}
/**
@@ -2242,7 +2256,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
.getKeyMgmtCapabilitiesCallback.class));
- assertEquals(WIFI_FEATURE_OWE, mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_OWE)
+ .equals(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME)));
}
/**
@@ -2261,8 +2276,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
.getKeyMgmtCapabilitiesCallback.class));
- assertEquals(WIFI_FEATURE_OWE | WIFI_FEATURE_WPA3_SAE,
- mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_OWE | WIFI_FEATURE_WPA3_SAE)
+ .equals(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME)));
}
/**
@@ -2280,7 +2295,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface
.getKeyMgmtCapabilitiesCallback.class));
- assertEquals(WIFI_FEATURE_DPP, mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_DPP)
+ .equals(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME)));
}
/**
@@ -2297,9 +2313,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
.getKeyMgmtCapabilities_1_3Callback.class));
- assertTrue((WIFI_FEATURE_DPP_ENROLLEE_RESPONDER
- & mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME))
- == WIFI_FEATURE_DPP_ENROLLEE_RESPONDER);
+ assertTrue(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME)
+ .get(getCapabilityIndex(WIFI_FEATURE_DPP_ENROLLEE_RESPONDER)));
}
/**
@@ -2317,9 +2332,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
.getKeyMgmtCapabilities_1_3Callback.class));
- assertFalse((WIFI_FEATURE_DPP_ENROLLEE_RESPONDER
- & mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME))
- == WIFI_FEATURE_DPP_ENROLLEE_RESPONDER);
+ assertFalse(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME)
+ .get(getCapabilityIndex(WIFI_FEATURE_DPP_ENROLLEE_RESPONDER)));
}
/**
@@ -2337,7 +2351,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
.getKeyMgmtCapabilities_1_3Callback.class));
- assertEquals(WIFI_FEATURE_WAPI, mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_WAPI)
+ .equals(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME)));
}
/**
@@ -2355,8 +2370,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
.getKeyMgmtCapabilities_1_3Callback.class));
- assertEquals(WIFI_FEATURE_FILS_SHA256,
- mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_FILS_SHA256)
+ .equals(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME)));
}
/**
@@ -2374,8 +2389,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
.getKeyMgmtCapabilities_1_3Callback.class));
- assertEquals(WIFI_FEATURE_FILS_SHA384,
- mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_FILS_SHA384)
+ .equals(mDut.getAdvancedCapabilities(WLAN0_IFACE_NAME)));
}
/**
@@ -3506,15 +3521,15 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
/**
* Test To get wpa driver capabilities API on old HAL, should
- * return 0 (not supported)
+ * return an empty BitSet (not supported)
*/
@Test
- public void tetGetWpaDriverCapabilitiesOldHal() throws Exception {
+ public void testGetWpaDriverCapabilitiesOldHal() throws Exception {
setupMocksForHalV1_2();
executeAndValidateInitializationSequenceV1_2();
- assertEquals(0, mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME));
+ assertTrue(mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME).equals(new BitSet()));
}
/**
@@ -3532,7 +3547,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
.getWpaDriverCapabilitiesCallback.class));
- assertEquals(WIFI_FEATURE_MBO, mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_MBO)
+ .equals(mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME)));
}
/**
@@ -3552,8 +3568,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
.getWpaDriverCapabilitiesCallback.class));
- assertEquals(WIFI_FEATURE_MBO | WIFI_FEATURE_OCE,
- mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_MBO | WIFI_FEATURE_OCE)
+ .equals(mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME)));
}
/**
@@ -3573,8 +3589,8 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface
.getWpaDriverCapabilities_1_4Callback.class));
- assertEquals(WIFI_FEATURE_MBO | WIFI_FEATURE_OCE,
- mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME));
+ assertTrue(longToBitset(WIFI_FEATURE_MBO | WIFI_FEATURE_OCE)
+ .equals(mDut.getWpaDriverFeatureSet(WLAN0_IFACE_NAME)));
}
/**
@@ -3751,6 +3767,9 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
setupMocksForHalV1_3();
executeAndValidateInitializationSequenceV1_3();
assertNotNull(mISupplicantStaIfaceCallbackV13);
+ executeAndValidateConnectSequenceWithKeyMgmt(
+ SUPPLICANT_NETWORK_ID, false, TRANSLATED_SUPPLICANT_SSID.toString(),
+ WifiConfiguration.SECURITY_TYPE_PSK, null, false);
int reasonCode = ISupplicantStaIfaceCallback.ReasonCode.IE_IN_4WAY_DIFFERS;
@@ -3852,8 +3871,16 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
setupMocksForHalV1_4();
executeAndValidateInitializationSequenceV1_4();
assertNotNull(mISupplicantStaIfaceCallbackV14);
+
+ // Do not broadcast NETWORK_NOT_FOUND for the specified duration.
mISupplicantStaIfaceCallbackV14.onNetworkNotFound(NativeUtil.decodeSsid(SUPPLICANT_SSID));
+ verify(mWifiMonitor, never()).broadcastNetworkNotFoundEvent(
+ eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
+ // NETWORK_NOT_FOUND should be broadcasted after the duration.
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(TIME_START_MS
+ + SupplicantStaIfaceHalHidlImpl.IGNORE_NETWORK_NOT_FOUND_DURATION_MS + 1);
+ mISupplicantStaIfaceCallbackV14.onNetworkNotFound(NativeUtil.decodeSsid(SUPPLICANT_SSID));
verify(mWifiMonitor).broadcastNetworkNotFoundEvent(
eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
}
@@ -3877,26 +3904,72 @@ public class SupplicantStaIfaceHalHidlImplTest extends WifiBaseTest {
});
executeAndValidateConnectSequence(SUPPLICANT_NETWORK_ID, false,
TRANSLATED_SUPPLICANT_SSID.toString());
+
+ // SSID was not found, but don't broadcast NETWORK_NOT_FOUND since we're still in
+ // the ignore duration.
mISupplicantStaIfaceCallbackV14.onNetworkNotFound(NativeUtil.decodeSsid(SUPPLICANT_SSID));
+ verify(mWifiMonitor, never()).broadcastNetworkNotFoundEvent(
+ eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
+ validateConnectSequence(false, 1, TRANSLATED_SUPPLICANT_SSID.toString());
+
+ // Receive NETWORK_NOT_FOUND after the ignore duration. This should trigger a connection
+ // to the fallback without broadcasting NETWORK_NOT_FOUND yet.
+ long time = TIME_START_MS
+ + SupplicantStaIfaceHalHidlImpl.IGNORE_NETWORK_NOT_FOUND_DURATION_MS;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(time);
+ mISupplicantStaIfaceCallbackV14.onNetworkNotFound(NativeUtil.decodeSsid(
+ TRANSLATED_SUPPLICANT_SSID.toString()));
+ verify(mWifiMonitor, never()).broadcastNetworkNotFoundEvent(
+ eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
+ validateConnectSequence(false, 2, SUPPLICANT_SSID);
- // Validate that we initiated another connect sequence to the fallback SUPPLICANT_SSID.
+ // Fallback SSID was not found, but don't broadcast NETWORK_NOT_FOUND because we're in the
+ // ignore duration for the fallback connection.
+ mISupplicantStaIfaceCallbackV14.onNetworkNotFound(NativeUtil.decodeSsid(SUPPLICANT_SSID));
verify(mWifiMonitor, never()).broadcastNetworkNotFoundEvent(
eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
validateConnectSequence(false, 2, SUPPLICANT_SSID);
- // Fallback SSID was not found, finally broadcast NETWORK_NOT_FOUND and try the first SSID
- // again.
+ // Receive NETWORK_NOT_FOUND after the new ignore duration. This should trigger a connection
+ // to the first SSID and finally broadcast the NETWORK_NOT_FOUND.
+ time += SupplicantStaIfaceHalHidlImpl.IGNORE_NETWORK_NOT_FOUND_DURATION_MS;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(time);
mISupplicantStaIfaceCallbackV14.onNetworkNotFound(NativeUtil.decodeSsid(SUPPLICANT_SSID));
verify(mWifiMonitor).broadcastNetworkNotFoundEvent(
eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
validateConnectSequence(false, 3, TRANSLATED_SUPPLICANT_SSID.toString());
+ }
- // First SSID not found, try the fallback without broadcasting NETWORK_NOT_FOUND.
- mISupplicantStaIfaceCallbackV14.onNetworkNotFound(NativeUtil.decodeSsid(
- TRANSLATED_SUPPLICANT_SSID.toString()));
- verify(mWifiMonitor, times(1)).broadcastNetworkNotFoundEvent(
- eq(WLAN0_IFACE_NAME), eq(TRANSLATED_SUPPLICANT_SSID.toString()));
- validateConnectSequence(false, 4, SUPPLICANT_SSID);
+ /**
+ * Tests that network not found notification won't trigger connecting to the fallback SSIDs if
+ * the network has been disabled.
+ */
+ @Test
+ public void testNetworkNotFoundCallbackDoesNotConnectToFallbackAfterDisabled()
+ throws Exception {
+ when(mSupplicantStaNetworkMock.disable()).thenReturn(true);
+ setupMocksForHalV1_4();
+ executeAndValidateInitializationSequenceV1_4();
+ assertNotNull(mISupplicantStaIfaceCallbackV14);
+ // Setup mocks to return two possible original SSIDs. We will pick
+ // TRANSLATED_SUPPLICANT_SSID as the first SSID to try.
+ when(mSsidTranslator.getAllPossibleOriginalSsids(TRANSLATED_SUPPLICANT_SSID)).thenAnswer(
+ (Answer<List<WifiSsid>>) invocation -> {
+ List<WifiSsid> ssids = new ArrayList<>();
+ ssids.add(TRANSLATED_SUPPLICANT_SSID);
+ ssids.add(WifiSsid.fromString(SUPPLICANT_SSID));
+ return ssids;
+ });
+ executeAndValidateConnectSequence(SUPPLICANT_NETWORK_ID, false,
+ TRANSLATED_SUPPLICANT_SSID.toString());
+
+ // Disable the current network and issue a NETWORK_NOT_FOUND
+ assertTrue(mDut.disableCurrentNetwork(WLAN0_IFACE_NAME));
+ verify(mSupplicantStaNetworkMock).disable();
+ mISupplicantStaIfaceCallbackV14.onNetworkNotFound(NativeUtil.decodeSsid(SUPPLICANT_SSID));
+
+ // Validate that we don't initiate another connect sequence.
+ validateConnectSequence(false, 1, TRANSLATED_SUPPLICANT_SSID.toString());
}
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
index 6efeec6ebf..84de1f8d64 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
@@ -16,6 +16,8 @@
package com.android.server.wifi;
+import static com.android.server.wifi.util.GeneralUtil.longToBitset;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -49,6 +51,7 @@ import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.HashMap;
import java.util.Map;
@@ -925,9 +928,9 @@ public class SupplicantStaIfaceHalTest extends WifiBaseTest {
@Test
public void testGetAdvancedCapabilities() {
initializeWithAidlImpl(true);
- long capabilities = 0X1234;
+ BitSet capabilities = longToBitset(0X1234);
when(mStaIfaceHalAidlMock.getAdvancedCapabilities(anyString())).thenReturn(capabilities);
- assertEquals(capabilities, mDut.getAdvancedCapabilities(IFACE_NAME));
+ assertTrue(capabilities.equals(mDut.getAdvancedCapabilities(IFACE_NAME)));
verify(mStaIfaceHalAidlMock).getAdvancedCapabilities(eq(IFACE_NAME));
}
@@ -937,9 +940,9 @@ public class SupplicantStaIfaceHalTest extends WifiBaseTest {
@Test
public void testGetWpaDriverFeatureSet() {
initializeWithAidlImpl(true);
- long capabilities = 0X1234;
+ BitSet capabilities = longToBitset(0X1234);
when(mStaIfaceHalAidlMock.getWpaDriverFeatureSet(anyString())).thenReturn(capabilities);
- assertEquals(capabilities, mDut.getWpaDriverFeatureSet(IFACE_NAME));
+ assertTrue(capabilities.equals(mDut.getWpaDriverFeatureSet(IFACE_NAME)));
verify(mStaIfaceHalAidlMock).getWpaDriverFeatureSet(eq(IFACE_NAME));
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalAidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalAidlImplTest.java
index fbd03da9c8..9b08be96cf 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalAidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalAidlImplTest.java
@@ -15,6 +15,9 @@
*/
package com.android.server.wifi;
+import static com.android.server.wifi.util.GeneralUtil.getCapabilityIndex;
+import static com.android.server.wifi.util.GeneralUtil.longToBitset;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -104,8 +107,8 @@ public class SupplicantStaNetworkHalAidlImplTest extends WifiBaseTest {
@Mock private Context mContext;
@Mock private WifiMonitor mWifiMonitor;
@Mock private WifiGlobals mWifiGlobals;
- private long mAdvanceKeyMgmtFeatures = 0;
- private long mWpaDriverFeatures = 0;
+ private BitSet mAdvanceKeyMgmtFeatures = new BitSet();
+ private BitSet mWpaDriverFeatures = new BitSet();
private SupplicantNetworkVariables mSupplicantVariables;
private MockResources mResources;
@@ -122,7 +125,7 @@ public class SupplicantStaNetworkHalAidlImplTest extends WifiBaseTest {
when(mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(true);
when(mWifiGlobals.isWpaPersonalDeprecated()).thenReturn(false);
- mAdvanceKeyMgmtFeatures |= WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
+ mAdvanceKeyMgmtFeatures.set(getCapabilityIndex(WifiManager.WIFI_FEATURE_WPA3_SUITE_B));
mSupplicantNetwork = new SupplicantStaNetworkHalAidlImpl(1,
mISupplicantStaNetworkMock, IFACE_NAME, mContext, mWifiMonitor,
mWifiGlobals, mAdvanceKeyMgmtFeatures, mWpaDriverFeatures);
@@ -1193,7 +1196,7 @@ public class SupplicantStaNetworkHalAidlImplTest extends WifiBaseTest {
@Test
public void testSupportedCiphersNoGcmp256() throws Exception {
// Reinitialize mSupplicantNetwork without support for WPA3 SUITE-B
- mAdvanceKeyMgmtFeatures = 0;
+ mAdvanceKeyMgmtFeatures.clear();
mSupplicantNetwork = new SupplicantStaNetworkHalAidlImpl(1,
mISupplicantStaNetworkMock, IFACE_NAME, mContext, mWifiMonitor,
mWifiGlobals, mAdvanceKeyMgmtFeatures, mWpaDriverFeatures);
@@ -1329,7 +1332,7 @@ public class SupplicantStaNetworkHalAidlImplTest extends WifiBaseTest {
// Re-init mock to AIDL v2 without TLS v1.3 support.
mSupplicantNetwork = new SupplicantStaNetworkHalAidlImpl(2,
mISupplicantStaNetworkMock, IFACE_NAME, mContext, mWifiMonitor,
- mWifiGlobals, mAdvanceKeyMgmtFeatures, 0);
+ mWifiGlobals, mAdvanceKeyMgmtFeatures, mWpaDriverFeatures);
WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
config.enterpriseConfig.setMinimumTlsVersion(WifiEnterpriseConfig.TLS_V1_3);
// Assume that the default params is used for this test.
@@ -1347,10 +1350,10 @@ public class SupplicantStaNetworkHalAidlImplTest extends WifiBaseTest {
public void testEapMinimumTlsVersionWifiConfigurationSaveLoadWithAidlV2TlsV13Supported()
throws Exception {
// Re-init mock to AIDL v2 with TLS v1.3 support.
+ mWpaDriverFeatures = longToBitset(WifiManager.WIFI_FEATURE_TLS_V1_3);
mSupplicantNetwork = new SupplicantStaNetworkHalAidlImpl(2,
mISupplicantStaNetworkMock, IFACE_NAME, mContext, mWifiMonitor,
- mWifiGlobals, mAdvanceKeyMgmtFeatures,
- WifiManager.WIFI_FEATURE_TLS_V1_3);
+ mWifiGlobals, mAdvanceKeyMgmtFeatures, mWpaDriverFeatures);
WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
config.enterpriseConfig.setMinimumTlsVersion(WifiEnterpriseConfig.TLS_V1_3);
// Assume that the default params is used for this test.
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalHidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalHidlImplTest.java
index 191cc11135..b34402e793 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalHidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalHidlImplTest.java
@@ -15,6 +15,8 @@
*/
package com.android.server.wifi;
+import static com.android.server.wifi.util.GeneralUtil.longToBitset;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -96,7 +98,7 @@ public class SupplicantStaNetworkHalHidlImplTest extends WifiBaseTest {
@Mock private Context mContext;
@Mock private WifiMonitor mWifiMonitor;
@Mock private WifiGlobals mWifiGlobals;
- private long mAdvanceKeyMgmtFeatures = 0;
+ private BitSet mAdvanceKeyMgmtFeatures = new BitSet();
private SupplicantNetworkVariables mSupplicantVariables;
private MockResources mResources;
@@ -121,7 +123,7 @@ public class SupplicantStaNetworkHalHidlImplTest extends WifiBaseTest {
SupplicantStaNetworkHalSpyV1_2(ISupplicantStaNetwork iSupplicantStaNetwork,
String ifaceName,
Context context, WifiMonitor monitor, WifiGlobals wifiGlobals,
- long advanceKeyMgmtFeatures) {
+ BitSet advanceKeyMgmtFeatures) {
super(iSupplicantStaNetwork, ifaceName, context, monitor, wifiGlobals,
advanceKeyMgmtFeatures);
}
@@ -141,7 +143,7 @@ public class SupplicantStaNetworkHalHidlImplTest extends WifiBaseTest {
SupplicantStaNetworkHalSpyV1_3(ISupplicantStaNetwork iSupplicantStaNetwork,
String ifaceName,
Context context, WifiMonitor monitor, WifiGlobals wifiGlobals,
- long advanceKeyMgmtFeatures) {
+ BitSet advanceKeyMgmtFeatures) {
super(iSupplicantStaNetwork, ifaceName, context, monitor, wifiGlobals,
advanceKeyMgmtFeatures);
}
@@ -161,7 +163,7 @@ public class SupplicantStaNetworkHalHidlImplTest extends WifiBaseTest {
SupplicantStaNetworkHalSpyV1_4(ISupplicantStaNetwork iSupplicantStaNetwork,
String ifaceName,
Context context, WifiMonitor monitor, WifiGlobals wifiGlobals,
- long advanceKeyMgmtFeatures) {
+ BitSet advanceKeyMgmtFeatures) {
super(iSupplicantStaNetwork, ifaceName, context, monitor, wifiGlobals,
advanceKeyMgmtFeatures);
}
@@ -190,7 +192,7 @@ public class SupplicantStaNetworkHalHidlImplTest extends WifiBaseTest {
when(mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()).thenReturn(true);
when(mWifiGlobals.isWpaPersonalDeprecated()).thenReturn(false);
- mAdvanceKeyMgmtFeatures |= WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
+ mAdvanceKeyMgmtFeatures = longToBitset(WifiManager.WIFI_FEATURE_WPA3_SUITE_B);
createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_0);
}
@@ -1608,7 +1610,7 @@ public class SupplicantStaNetworkHalHidlImplTest extends WifiBaseTest {
@Test
public void testUnsupportingGcmp256Ciphers1_2OrHigher()
throws Exception {
- mAdvanceKeyMgmtFeatures = 0;
+ mAdvanceKeyMgmtFeatures.clear();
createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_2);
WifiConfiguration config = WifiConfigurationTestUtil.createSaeNetwork();
int expectedHalPairwiseCiphers =
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
index d1642fa328..77274c17ec 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java
@@ -42,7 +42,6 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.MacAddress;
@@ -50,6 +49,7 @@ import android.net.wifi.SoftApCapability;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApConfiguration.Builder;
import android.net.wifi.SoftApInfo;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiInfo;
import android.os.Build;
import android.os.Handler;
@@ -100,7 +100,7 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
private final int mBand25660G = SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ
| SoftApConfiguration.BAND_6GHZ | SoftApConfiguration.BAND_60GHZ;
- @Mock private Context mContext;
+ @Mock private WifiContext mContext;
@Mock private WifiInjector mWifiInjector;
@Mock private WifiNative mWifiNative;
@Mock private WifiMetrics mWifiMetrics;
@@ -116,7 +116,7 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
@Mock private WifiSettingsConfigStore mWifiSettingsConfigStore;
private Random mRandom;
- private MockResources mResources;
+ private MockResourceCache mResources;
@Mock private ApplicationInfo mMockApplInfo;
@Mock private MacAddressUtil mMacAddressUtil;
private SoftApStoreData.DataSource mDataStoreSource;
@@ -138,7 +138,7 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
// Default assume true for all old test cases.
when(mHalDeviceManager.isConcurrencyComboLoadedFromDriver()).thenReturn(true);
/* Setup expectations for Resources to return some default settings. */
- mResources = new MockResources();
+ mResources = new MockResourceCache(mContext);
mResources.setString(R.string.config_wifiSoftap2gChannelList,
TEST_DEFAULT_2G_CHANNEL_LIST);
mResources.setString(R.string.wifi_tether_configure_ssid_default,
@@ -148,7 +148,7 @@ public class WifiApConfigStoreTest extends WifiBaseTest {
mResources.setBoolean(R.bool.config_wifiSoftapPassphraseAsciiEncodableCheck, true);
setupAllBandsSupported();
- when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getResourceCache()).thenReturn(mResources);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
// build the known good 2G channel list: TEST_DEFAULT_2G_CHANNEL_LIST
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java
index 71a7a82dd2..2c629de390 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiCarrierInfoManagerTest.java
@@ -2531,4 +2531,67 @@ public class WifiCarrierInfoManagerTest extends WifiBaseTest {
wifiCaptor.capture());
assertThat(wifiCaptor.getValue()).containsExactly(DATA_SUBID, NON_DATA_SUBID);
}
+
+ @Test
+ public void isMobileDataEnabled_true() {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mDataTelephonyManager.isDataEnabled()).thenReturn(true);
+ assertTrue(mWifiCarrierInfoManager.isMobileDataEnabled());
+ }
+
+ @Test
+ public void isMobileDataEnabled_false_null() {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mSubscriptionManager.getCompleteActiveSubscriptionInfoList())
+ .thenReturn(null);
+ mListenerArgumentCaptor.getValue().onSubscriptionsChanged();
+ mLooper.dispatchAll();
+
+ assertFalse(mWifiCarrierInfoManager.isMobileDataEnabled());
+ }
+ @Test
+ public void isMobileDataEnabled_false_empty() {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mSubscriptionManager.getCompleteActiveSubscriptionInfoList())
+ .thenReturn(new ArrayList<>());
+ mListenerArgumentCaptor.getValue().onSubscriptionsChanged();
+ mLooper.dispatchAll();
+
+ assertFalse(mWifiCarrierInfoManager.isMobileDataEnabled());
+ }
+
+ @Test
+ public void isMobileDataEnabled_false_present() {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mDataTelephonyManager.isDataEnabled()).thenReturn(false);
+ when(mNonDataTelephonyManager.isDataEnabled()).thenReturn(false);
+ mListenerArgumentCaptor.getValue().onSubscriptionsChanged();
+ mLooper.dispatchAll();
+
+ assertFalse(mWifiCarrierInfoManager.isMobileDataEnabled());
+ }
+
+ @Test
+ public void hasActiveSubInfo_true() {
+ assertTrue(mWifiCarrierInfoManager.hasActiveSubInfo());
+ }
+
+ @Test
+ public void hasActiveSubInfo_false_null() {
+ when(mSubscriptionManager.getCompleteActiveSubscriptionInfoList()).thenReturn(null);
+ mListenerArgumentCaptor.getValue().onSubscriptionsChanged();
+ mLooper.dispatchAll();
+
+ assertFalse(mWifiCarrierInfoManager.hasActiveSubInfo());
+ }
+
+ @Test
+ public void hasActiveSubInfo_false_empty() {
+ when(mSubscriptionManager.getCompleteActiveSubscriptionInfoList())
+ .thenReturn(new ArrayList<>());
+ mListenerArgumentCaptor.getValue().onSubscriptionsChanged();
+ mLooper.dispatchAll();
+
+ assertFalse(mWifiCarrierInfoManager.hasActiveSubInfo());
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index d5709575ed..6e88ddb744 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -5551,6 +5551,43 @@ public class WifiConfigManagerTest extends WifiBaseTest {
assertTrue(mWifiConfigManager.isNonCarrierMergedNetworkTemporarilyDisabled(visibleNetwork));
mWifiConfigManager.onCellularConnectivityChanged(WifiDataStall.CELLULAR_DATA_NOT_AVAILABLE);
+ assertTrue(mWifiConfigManager.isNonCarrierMergedNetworkTemporarilyDisabled(
+ visibleNetwork));
+
+ mWifiConfigManager.considerStopRestrictingAutoJoinToSubscriptionId();
+ assertFalse(mWifiConfigManager.isNonCarrierMergedNetworkTemporarilyDisabled(
+ visibleNetwork));
+ }
+
+ @Test
+ public void testFlakyNoCellularNotEnableNonCarrierMergedWifi() {
+ verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createOpenNetwork());
+ List<WifiConfiguration> retrievedNetworks =
+ mWifiConfigManager.getConfiguredNetworksWithPasswords();
+ WifiConfiguration visibleNetwork = retrievedNetworks.get(0);
+ ScanDetail scanDetail = createScanDetailForNetwork(visibleNetwork, TEST_BSSID,
+ TEST_RSSI, TEST_FREQUENCY_1);
+ mWifiConfigManager.updateScanDetailCacheFromScanDetailForSavedNetwork(scanDetail);
+
+ // verify the network is disabled after startRestrictingAutoJoinToSubscriptionId is called
+ when(mClock.getWallClockMillis()).thenReturn(0L);
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
+ mWifiConfigManager.startRestrictingAutoJoinToSubscriptionId(5);
+ mWifiConfigManager.updateUserDisabledList(new ArrayList<String>());
+ assertTrue(mWifiConfigManager.isNonCarrierMergedNetworkTemporarilyDisabled(visibleNetwork));
+
+ // Simulate flaky cellular connection
+ mWifiConfigManager.onCellularConnectivityChanged(WifiDataStall.CELLULAR_DATA_NOT_AVAILABLE);
+ mWifiConfigManager.onCellularConnectivityChanged(WifiDataStall.CELLULAR_DATA_AVAILABLE);
+ // wifi should still be disabled since cellular recovered
+ mWifiConfigManager.considerStopRestrictingAutoJoinToSubscriptionId();
+ assertTrue(mWifiConfigManager.isNonCarrierMergedNetworkTemporarilyDisabled(
+ visibleNetwork));
+
+ // Cellular lost again
+ mWifiConfigManager.onCellularConnectivityChanged(WifiDataStall.CELLULAR_DATA_NOT_AVAILABLE);
+ mWifiConfigManager.considerStopRestrictingAutoJoinToSubscriptionId();
+ // wifi should be enabled now
assertFalse(mWifiConfigManager.isNonCarrierMergedNetworkTemporarilyDisabled(
visibleNetwork));
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
index 8dbe628f5c..81b182c9df 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
@@ -18,6 +18,7 @@ package com.android.server.wifi;
import static android.net.wifi.WifiEnterpriseConfig.OCSP_NONE;
import static android.net.wifi.WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS;
+import static android.net.wifi.hotspot2.PasspointConfiguration.MAX_URL_BYTES;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -53,6 +54,7 @@ import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
+import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
@@ -77,6 +79,7 @@ public class WifiConfigurationUtilTest extends WifiBaseTest {
new UserInfo(CURRENT_USER_ID, "owner", 0),
new UserInfo(CURRENT_USER_MANAGED_PROFILE_USER_ID, "managed profile", 0));
private static final long SUPPORTED_FEATURES_ALL = Long.MAX_VALUE;
+ private final String mGeneratedString256 = "a".repeat(256);
private MockitoSession mSession;
@@ -1606,4 +1609,76 @@ public class WifiConfigurationUtilTest extends WifiBaseTest {
assertTrue(WifiConfigurationUtil.isConfigLinkable(saeConfig));
assertFalse(WifiConfigurationUtil.isConfigLinkable(saeDisabledConfig));
}
+
+ @Test
+ public void testWepKeyOnNonWepConfig() {
+ WifiConfiguration pskConfig = WifiConfigurationTestUtil.createPskNetwork();
+ pskConfig.wepKeys = new String[4];
+ pskConfig.wepKeys[0] = mGeneratedString256;
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ }
+
+ @Test
+ public void testInvalidFqdnAndFriendlyName() {
+ WifiConfiguration pskConfig = WifiConfigurationTestUtil.createPskNetwork();
+
+ pskConfig.FQDN = mGeneratedString256;
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+
+ pskConfig.FQDN = null;
+ pskConfig.providerFriendlyName = mGeneratedString256;
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ }
+
+ @Test
+ public void testInvalidDhcpAndGtw() {
+ WifiConfiguration pskConfig = WifiConfigurationTestUtil.createPskNetwork();
+ pskConfig.dhcpServer = TEST_BSSID;
+ pskConfig.defaultGwMacAddress = TEST_BSSID;
+ assertTrue(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ pskConfig.dhcpServer = mGeneratedString256;
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ pskConfig.dhcpServer = TEST_BSSID;
+ pskConfig.defaultGwMacAddress = mGeneratedString256;
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ }
+
+ @Test
+ public void testInvalidSecurityParameter() {
+ WifiConfiguration pskConfig = WifiConfigurationTestUtil.createPskNetwork();
+ List<SecurityParams> securityParamsList = new ArrayList<>();
+ securityParamsList.add(SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_PSK));
+ securityParamsList.add(SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_PSK));
+
+ pskConfig.setSecurityParams(securityParamsList);
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ }
+
+ @Test
+ public void testInvalidUserConnectChoice() {
+ WifiConfiguration pskConfig = WifiConfigurationTestUtil.createPskNetwork();
+ String generatedString513 = "a".repeat(513);
+ pskConfig.getNetworkSelectionStatus().setConnectChoice(generatedString513);
+
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ }
+
+ @Test
+ public void testInvalidDppConfig() {
+ WifiConfiguration pskConfig = WifiConfigurationTestUtil.createPskNetwork();
+ String generatedString = "a".repeat(MAX_URL_BYTES + 1);
+ pskConfig.setDppConfigurator(generatedString.getBytes(StandardCharsets.UTF_8));
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
index e5ddabb0e1..d0f3ad65f6 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
@@ -107,6 +107,7 @@ import com.android.server.wifi.proto.nano.WifiMetricsProto;
import com.android.server.wifi.scanner.WifiScannerInternal;
import com.android.server.wifi.util.LruConnectionTracker;
import com.android.server.wifi.util.WifiPermissionsUtil;
+import com.android.wifi.flags.FeatureFlags;
import com.android.wifi.resources.R;
import org.junit.After;
@@ -179,6 +180,10 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
when(mPrimaryClientModeManager.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_PRIMARY);
when(mPrimaryClientModeManager.getConnectionInfo()).thenReturn(mWifiInfo);
when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(mPrimaryClientModeManager);
+ when(mDeviceConfigFacade.getFeatureFlags()).thenReturn(mFeatureFlags);
+ when(mFeatureFlags.delayedCarrierNetworkSelection()).thenReturn(true);
+ when(mWifiCarrierInfoManager.isCarrierNetworkOffloadEnabled(anyInt(), anyBoolean()))
+ .thenReturn(true);
doAnswer(new AnswerWithArguments() {
public void answer(ExternalClientModeManagerRequestListener listener,
WorkSource requestorWs, String ssid, String bssid) {
@@ -267,6 +272,10 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
resources.setInteger(R.integer.config_wifiPnoScanIterations, EXPECTED_PNO_ITERATIONS);
resources.setInteger(R.integer.config_wifiPnoScanIntervalMultiplier,
EXPECTED_PNO_MULTIPLIER);
+ resources.setIntArray(R.array.config_wifiDelayedSelectionCarrierIds,
+ DELAYED_SELECTION_CARRIER_IDS);
+ resources.setInteger(R.integer.config_wifiDelayedCarrierSelectionTimeMs,
+ DELAYED_CARRIER_SELECTION_TIME_MS);
}
/**
@@ -313,6 +322,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
@Mock private WifiNetworkSuggestion mWifiNetworkSuggestion;
@Mock private IPowerManager mPowerManagerService;
@Mock private DeviceConfigFacade mDeviceConfigFacade;
+ @Mock private FeatureFlags mFeatureFlags;
@Mock private ActiveModeWarden mActiveModeWarden;
@Mock private ConcreteClientModeManager mPrimaryClientModeManager;
@Mock private ConcreteClientModeManager mSecondaryClientModeManager;
@@ -350,6 +360,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
@Captor ArgumentCaptor<MultiInternetManager.ConnectionStatusListener>
mMultiInternetConnectionStatusListenerCaptor;
@Captor ArgumentCaptor<WifiDialogManager.SimpleDialogCallback> mSimpleDialogCallbackCaptor;
+ @Captor ArgumentCaptor<WifiScannerInternal.ScanListener> mAllSingleScanListenerCaptor;
private MockitoSession mSession;
private MockResources mResources;
@@ -408,6 +419,8 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
private static final int EXPECTED_PNO_MULTIPLIER = 4;
private static final int TEST_FREQUENCY_2G = 2412;
private static final int TEST_FREQUENCY_5G = 5262;
+ private static final int[] DELAYED_SELECTION_CARRIER_IDS = new int[]{123};
+ private static final int DELAYED_CARRIER_SELECTION_TIME_MS = 100_000;
/**
* A test Handler that stores one single incoming Message with delayed time internally, to be
@@ -477,10 +490,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
}
void mockWifiScanner() {
- ArgumentCaptor<WifiScannerInternal.ScanListener> allSingleScanListenerCaptor =
- ArgumentCaptor.forClass(WifiScannerInternal.ScanListener.class);
-
- doNothing().when(mWifiScanner).registerScanListener(allSingleScanListenerCaptor.capture());
+ doNothing().when(mWifiScanner).registerScanListener(mAllSingleScanListenerCaptor.capture());
ScanData[] scanDatas = new ScanData[1];
scanDatas[0] = mScanData;
@@ -493,11 +503,11 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// same as onResult for single scans).
if (mScanData != null && mScanData.getResults() != null) {
for (int i = 0; i < mScanData.getResults().length; i++) {
- allSingleScanListenerCaptor.getValue().getWifiScannerListener()
+ mAllSingleScanListenerCaptor.getValue().getWifiScannerListener()
.onFullResult(mScanData.getResults()[i]);
}
}
- allSingleScanListenerCaptor.getValue().getWifiScannerListener().onResults(
+ mAllSingleScanListenerCaptor.getValue().getWifiScannerListener().onResults(
scanDatas);
}}).when(mWifiScanner).startScan(anyObject(), anyObject());
@@ -752,6 +762,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
assertEquals(WifiConnectivityManager.WIFI_STATE_DISCONNECTED,
mWifiConnectivityManager.getWifiState());
mLooper.dispatchAll();
+ verify(mWifiConfigManager).considerStopRestrictingAutoJoinToSubscriptionId();
verify(mPrimaryClientModeManager).startConnectToNetwork(
CANDIDATE_NETWORK_ID, Process.WIFI_UID, "any");
verify(mPrimaryClientModeManager).enableRoaming(true);
@@ -2272,6 +2283,130 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
}
}
+ private void setAllScanCandidatesToDelayedCarrierCandidates() {
+ WifiConfiguration delayedCarrierSelectionConfig =
+ getTestWifiConfig(CANDIDATE_NETWORK_ID, "DelayedSelectionCarrier");
+ delayedCarrierSelectionConfig.carrierId = DELAYED_SELECTION_CARRIER_IDS[0];
+ when(mWifiConfigManager.getConfiguredNetwork(anyInt()))
+ .thenReturn(delayedCarrierSelectionConfig);
+ }
+
+ /**
+ * Verify that candidates with a carrier ID in the delayed selection list are only considered
+ * for network selection after the specified delay.
+ */
+ @Test
+ public void testDelayedCarrierCandidateSelection() {
+ ScanData[] scanDatas = new ScanData[]{mScanData};
+ setAllScanCandidatesToDelayedCarrierCandidates();
+
+ // Produce results for the initial scan. Expect no connection,
+ // since this is the first time we're seeing the carrier network.
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
+ mAllSingleScanListenerCaptor.getValue().getWifiScannerListener().onResults(scanDatas);
+ verify(mPrimaryClientModeManager, never()).startConnectToNetwork(
+ CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+
+ // Complete an additional scan before the delay period has ended. Expect no connection.
+ when(mClock.getElapsedSinceBootMillis())
+ .thenReturn(DELAYED_CARRIER_SELECTION_TIME_MS - 1000L);
+ mAllSingleScanListenerCaptor.getValue().getWifiScannerListener().onResults(scanDatas);
+ verify(mPrimaryClientModeManager, never()).startConnectToNetwork(
+ CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+
+ // Complete a scan after the delay period has ended. Expect a connection.
+ when(mClock.getElapsedSinceBootMillis())
+ .thenReturn(DELAYED_CARRIER_SELECTION_TIME_MS + 1000L);
+ mAllSingleScanListenerCaptor.getValue().getWifiScannerListener().onResults(scanDatas);
+ verify(mPrimaryClientModeManager).startConnectToNetwork(
+ CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+ }
+
+ /**
+ * Verify that a partial scan containing no results does not affect the delayed carrier
+ * selection cache. Partial scans may be running on channels where carrier networks
+ * are not operating.
+ */
+ @Test
+ public void testDelayedCarrierSelectionEmptyPartialScan() {
+ ScanData[] scanDatas = new ScanData[]{mScanData};
+ setAllScanCandidatesToDelayedCarrierCandidates();
+
+ // Issue a full scan to add the carrier candidate to the cache.
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
+ when(mScanData.getScannedBandsInternal()).thenReturn(WifiScanner.WIFI_BAND_ALL);
+ mAllSingleScanListenerCaptor.getValue().getWifiScannerListener().onResults(scanDatas);
+ verify(mPrimaryClientModeManager, never()).startConnectToNetwork(
+ CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+
+ // Issue a partial scan that does not locate any candidates. This should not affect
+ // the cache populated by the full scan.
+ when(mWifiNS.getCandidatesFromScan(any(), any(), any(), anyBoolean(), anyBoolean(),
+ anyBoolean(), any(), anyBoolean())).thenReturn(null);
+ when(mScanData.getScannedBandsInternal()).thenReturn(WifiScanner.WIFI_BAND_6_GHZ);
+ when(mClock.getElapsedSinceBootMillis())
+ .thenReturn(DELAYED_CARRIER_SELECTION_TIME_MS - 1000L);
+ mAllSingleScanListenerCaptor.getValue().getWifiScannerListener().onResults(scanDatas);
+ verify(mPrimaryClientModeManager, never()).startConnectToNetwork(
+ CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+
+ // Issue a full scan after the delay period has passed. Since the cache was not modified by
+ // the partial scan, the delayed carrier candidate should still be in the timestamp cache.
+ when(mWifiNS.getCandidatesFromScan(any(), any(), any(), anyBoolean(), anyBoolean(),
+ anyBoolean(), any(), anyBoolean())).thenReturn(Arrays.asList(mCandidate1));
+ when(mScanData.getScannedBandsInternal()).thenReturn(WifiScanner.WIFI_BAND_ALL);
+ when(mClock.getElapsedSinceBootMillis())
+ .thenReturn(DELAYED_CARRIER_SELECTION_TIME_MS + 1000L);
+ mAllSingleScanListenerCaptor.getValue().getWifiScannerListener().onResults(scanDatas);
+ verify(mPrimaryClientModeManager).startConnectToNetwork(
+ CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID);
+ }
+
+ /**
+ * Verify that a partial scan is scheduled when a full scan locates delayed carrier
+ * selection candidates.
+ */
+ @Test
+ public void testDelayedCarrierSelectionSchedulePartialScan() {
+ ScanData[] scanDatas = new ScanData[]{mScanData};
+ setAllScanCandidatesToDelayedCarrierCandidates();
+
+ // Initial full scan with a delayed carrier candidate should schedule a partial scan.
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
+ mAllSingleScanListenerCaptor.getValue().getWifiScannerListener().onResults(scanDatas);
+
+ // Move time forward and verify that the delayed partial scan is started.
+ when(mClock.getElapsedSinceBootMillis())
+ .thenReturn(DELAYED_CARRIER_SELECTION_TIME_MS + 1L);
+ mLooper.dispatchAll();
+ verify(mWifiScanner).startScan(
+ (ScanSettings) argThat(new WifiPartialScanSettingMatcher()), any());
+ }
+
+ /**
+ * Verify that if a delayed carrier partial scan is cancelled, no scan is triggered
+ * at the end of the delay period.
+ */
+ @Test
+ public void testDelayedCarrierSelectionCancelPartialScan() {
+ ScanData[] scanDatas = new ScanData[]{mScanData};
+ setAllScanCandidatesToDelayedCarrierCandidates();
+
+ // Initial full scan with a delayed carrier candidate should schedule a partial scan.
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
+ mAllSingleScanListenerCaptor.getValue().getWifiScannerListener().onResults(scanDatas);
+
+ // Turn off Wifi to cancel the partial scan.
+ setWifiEnabled(false);
+
+ // Move time forward and verify that a delayed partial scan is not started.
+ when(mClock.getElapsedSinceBootMillis())
+ .thenReturn(DELAYED_CARRIER_SELECTION_TIME_MS + 1L);
+ mLooper.dispatchAll();
+ verify(mWifiScanner, never()).startScan(
+ (ScanSettings) argThat(new WifiPartialScanSettingMatcher()), any());
+ }
+
/**
* Verify that when there are we obtain more than one valid candidates from scan results and
* network connection fails, connection is immediately retried on the remaining candidates.
@@ -2330,6 +2465,41 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
}
@Test
+ public void testNoRetryConnectionOnNetworkNotFoundFailure() {
+ // Setup WifiNetworkSelector to return 2 valid candidates from scan results
+ MacAddress macAddress = MacAddress.fromString(CANDIDATE_BSSID_2);
+ WifiCandidates.Key key = new WifiCandidates.Key(mock(ScanResultMatchInfo.class),
+ macAddress, 0, WifiConfiguration.SECURITY_TYPE_OPEN);
+ WifiCandidates.Candidate otherCandidate = mock(WifiCandidates.Candidate.class);
+ when(otherCandidate.getKey()).thenReturn(key);
+ List<WifiCandidates.Candidate> candidateList = new ArrayList<>();
+ candidateList.add(mCandidate1);
+ candidateList.add(otherCandidate);
+ when(mWifiNS.getCandidatesFromScan(any(), any(), any(), anyBoolean(), anyBoolean(),
+ anyBoolean(), any(), anyBoolean())).thenReturn(candidateList);
+
+ // Set WiFi to disconnected state to trigger scan
+ mWifiConnectivityManager.handleConnectionStateChanged(
+ mPrimaryClientModeManager,
+ WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
+ mLooper.dispatchAll();
+ // Verify a connection starting
+ verify(mWifiNS).selectNetwork((List<WifiCandidates.Candidate>)
+ argThat(new WifiCandidatesListSizeMatcher(2)));
+ verify(mPrimaryClientModeManager).startConnectToNetwork(anyInt(), anyInt(), any());
+
+ // Simulate the connection failing due to FAILURE_NO_RESPONSE
+ WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork(CANDIDATE_SSID);
+ mWifiConnectivityManager.handleConnectionAttemptEnded(
+ mPrimaryClientModeManager,
+ WifiMetrics.ConnectionEvent.FAILURE_NO_RESPONSE,
+ WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, CANDIDATE_BSSID,
+ config);
+ // Verify there is no retry
+ verify(mPrimaryClientModeManager).startConnectToNetwork(anyInt(), anyInt(), any());
+ }
+
+ @Test
public void testRetryConnectionEapFailureIgnoreSameNetwork() {
// Setup WifiNetworkSelector to return 2 valid candidates with the same
// ScanResultMatchInfo so they are the same network, but different BSSID.
@@ -2857,6 +3027,26 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
verify(mOpenNetworkNotifier).handleScreenStateChanged(true);
}
+ @Test
+ public void testInitialFastScanAfterStartup() {
+ // Enable the fast initial scan feature
+ mResources.setBoolean(R.bool.config_wifiEnablePartialInitialScan, true);
+ // return 2 available frequencies
+ when(mWifiScoreCard.lookupNetwork(anyString())).thenReturn(mPerNetwork);
+ when(mPerNetwork.getFrequencies(anyLong())).thenReturn(new ArrayList<>(
+ Arrays.asList(TEST_FREQUENCY_1, TEST_FREQUENCY_2)));
+
+ // Simulate wifi toggle
+ setScreenState(true);
+ setWifiEnabled(false);
+ setWifiEnabled(true);
+
+ // verify initial fast scan is triggered
+ assertEquals(WifiConnectivityManager.INITIAL_SCAN_STATE_AWAITING_RESPONSE,
+ mWifiConnectivityManager.getInitialScanState());
+ verify(mWifiMetrics).incrementInitialPartialScanCount();
+ }
+
/**
* Verify that the initial fast scan schedules the scan timer just like regular scans.
*/
@@ -5737,11 +5927,14 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
WifiConfiguration network3 = WifiConfigurationTestUtil.createOpenHiddenNetwork();
WifiConfiguration network4 = WifiConfigurationTestUtil.createEapNetwork(
WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE);
+ WifiConfiguration network5 = WifiConfigurationTestUtil.createPskNetwork();
+ network5.subscriptionId = 2;
network4.carrierId = 123; // Assign a valid carrier ID
network1.getNetworkSelectionStatus().setHasEverConnected(true);
network2.getNetworkSelectionStatus().setHasEverConnected(true);
network3.getNetworkSelectionStatus().setHasEverConnected(true);
network4.getNetworkSelectionStatus().setHasEverConnected(true);
+ network5.getNetworkSelectionStatus().setHasEverConnected(true);
when(mWifiCarrierInfoManager.isSimReady(anyInt())).thenReturn(true);
List<WifiConfiguration> networkList = new ArrayList<>();
@@ -5749,6 +5942,8 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
networkList.add(network2);
networkList.add(network3);
networkList.add(network4);
+ networkList.add(network5);
+ mLruConnectionTracker.addNetwork(network5);
mLruConnectionTracker.addNetwork(network4);
mLruConnectionTracker.addNetwork(network3);
mLruConnectionTracker.addNetwork(network2);
@@ -5758,12 +5953,13 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
List<WifiScanner.PnoSettings.PnoNetwork> pnoNetworks =
mWifiConnectivityManager.retrievePnoNetworkList();
verify(mWifiNetworkSuggestionsManager).getAllScanOptimizationSuggestionNetworks();
- assertEquals(5, pnoNetworks.size());
+ assertEquals(6, pnoNetworks.size());
assertEquals(network1.SSID, pnoNetworks.get(0).ssid);
assertEquals(UNTRANSLATED_HEX_SSID, pnoNetworks.get(1).ssid); // Possible untranslated SSID
assertEquals(network2.SSID, pnoNetworks.get(2).ssid);
assertEquals(network3.SSID, pnoNetworks.get(3).ssid);
assertEquals(network4.SSID, pnoNetworks.get(4).ssid);
+ assertEquals(network5.SSID, pnoNetworks.get(5).ssid);
// Now permanently disable |network3|. This should remove network 3 from the list.
network3.getNetworkSelectionStatus().setNetworkSelectionStatus(
@@ -5773,7 +5969,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// Retrieve the Pno network list & verify.
pnoNetworks = mWifiConnectivityManager.retrievePnoNetworkList();
- assertEquals(3, pnoNetworks.size());
+ assertEquals(4, pnoNetworks.size());
assertEquals(network1.SSID, pnoNetworks.get(0).ssid);
assertEquals(UNTRANSLATED_HEX_SSID, pnoNetworks.get(1).ssid); // Possible untranslated SSID
assertEquals(network2.SSID, pnoNetworks.get(2).ssid);
@@ -5782,7 +5978,7 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
network1.allowAutojoin = false;
// Retrieve the Pno network list & verify.
pnoNetworks = mWifiConnectivityManager.retrievePnoNetworkList();
- assertEquals(2, pnoNetworks.size());
+ assertEquals(3, pnoNetworks.size());
assertEquals(network2.SSID, pnoNetworks.get(0).ssid);
assertEquals(UNTRANSLATED_HEX_SSID, pnoNetworks.get(1).ssid); // Possible untranslated SSID
@@ -5790,6 +5986,14 @@ public class WifiConnectivityManagerTest extends WifiBaseTest {
// from the list.
when(mWifiConfigManager.isNetworkTemporarilyDisabledByUser(network2.SSID)).thenReturn(true);
pnoNetworks = mWifiConnectivityManager.retrievePnoNetworkList();
+ assertEquals(2, pnoNetworks.size());
+ assertEquals(network5.SSID, pnoNetworks.get(0).ssid);
+ assertEquals(UNTRANSLATED_HEX_SSID, pnoNetworks.get(1).ssid); // Possible untranslated SSID
+
+ // Set carrier offload to disabled. Should remove the last network
+ when(mWifiCarrierInfoManager.isCarrierNetworkOffloadEnabled(anyInt(), anyBoolean()))
+ .thenReturn(false);
+ pnoNetworks = mWifiConnectivityManager.retrievePnoNetworkList();
assertEquals(0, pnoNetworks.size());
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
index dacf2cc178..5941feeafd 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiCountryCodeTest.java
@@ -17,6 +17,7 @@
package com.android.server.wifi;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY;
+import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SCAN_ONLY;
import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_LONG_LIVED;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_DEFAULT_COUNTRY_CODE;
@@ -32,6 +33,7 @@ import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -40,6 +42,7 @@ import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.wifi.ScanResult;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.telephony.TelephonyManager;
@@ -90,8 +93,9 @@ public class WifiCountryCodeTest extends WifiBaseTest {
private boolean mDriverSupportedNl80211RegChangedEvent = false;
private boolean mForcedSoftApRestateWhenCountryCodeChanged = false;
private boolean mCallingSupported;
- @Mock Context mContext;
- MockResources mResources = new MockResources();
+ @Mock
+ WifiContext mContext;
+ private MockResourceCache mResourceCache;
@Mock TelephonyManager mTelephonyManager;
@Mock PackageManager mPackageManager;
@Mock ActiveModeWarden mActiveModeWarden;
@@ -150,6 +154,8 @@ public class WifiCountryCodeTest extends WifiBaseTest {
when(mContext.getSystemService(Context.TELEPHONY_SERVICE))
.thenReturn(mTelephonyManager);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ mResourceCache = new MockResourceCache(mContext);
+ when(mContext.getResourceCache()).thenReturn(mResourceCache);
setCallingSupported(true);
@@ -172,16 +178,17 @@ public class WifiCountryCodeTest extends WifiBaseTest {
}
private void createWifiCountryCode() {
- mResources.setBoolean(R.bool.config_wifi_revert_country_code_on_cellular_loss,
+ mResourceCache.setBoolean(R.bool.config_wifi_revert_country_code_on_cellular_loss,
mRevertCountryCodeOnCellularLoss);
- mResources.setBoolean(R.bool.config_wifiStaDynamicCountryCodeUpdateSupported,
+ mResourceCache.setBoolean(R.bool.config_wifiStaDynamicCountryCodeUpdateSupported,
mStaDynamicCountryCodeUpdateSupported);
- mResources.setBoolean(R.bool.config_wifiDriverSupportedNl80211RegChangedEvent,
+ mResourceCache.setBoolean(R.bool.config_wifiDriverSupportedNl80211RegChangedEvent,
mDriverSupportedNl80211RegChangedEvent);
- mResources.setBoolean(R.bool.config_wifiForcedSoftApRestartWhenCountryCodeChanged,
+ mResourceCache.setBoolean(R.bool.config_wifiForcedSoftApRestartWhenCountryCodeChanged,
mForcedSoftApRestateWhenCountryCodeChanged);
- mResources.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, false);
- mResources.setString(R.string.config_wifiDriverWorldModeCountryCode, mWorldModeCountryCode);
+ mResourceCache.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, false);
+ mResourceCache.setString(R.string.config_wifiDriverWorldModeCountryCode,
+ mWorldModeCountryCode);
doAnswer((invocation) -> {
if (SdkLevel.isAtLeastS()) {
mChangeListenerCaptor.getValue()
@@ -194,7 +201,6 @@ public class WifiCountryCodeTest extends WifiBaseTest {
return true;
}).when(mClientModeManager).setCountryCode(
mSetCountryCodeCaptor.capture());
- when(mContext.getResources()).thenReturn(mResources);
mWifiCountryCode = new WifiCountryCode(
mContext,
mActiveModeWarden,
@@ -284,7 +290,6 @@ public class WifiCountryCodeTest extends WifiBaseTest {
assertEquals(mTelephonyCountryCode, mWifiCountryCode.getCurrentDriverCountryCode());
}
-
/**
* Test if we receive country code from Telephony after supplicant stop.
* @throws Exception
@@ -720,18 +725,18 @@ public class WifiCountryCodeTest extends WifiBaseTest {
@Test
public void testUpdateountryCodeGenericDisabled() {
- mResources.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, false);
+ mResourceCache.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, false);
mWifiCountryCode.updateCountryCodeFromScanResults(mScanDetails);
assertEquals(mDefaultCountryCode, mWifiCountryCode.getCountryCode());
}
@Test
public void testUpdateountryCodeGenericEnabled() {
- mResources.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, true);
+ mResourceCache.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, true);
mWifiCountryCode.updateCountryCodeFromScanResults(mScanDetails);
assertEquals(TEST_COUNTRY_CODE, mWifiCountryCode.getCountryCode());
- mResources.setBoolean(R.bool.config_wifiDriverSupportedNl80211RegChangedEvent, false);
+ mResourceCache.setBoolean(R.bool.config_wifiDriverSupportedNl80211RegChangedEvent, false);
mChangeListenerCaptor.getValue().onSetCountryCodeSucceeded(TEST_COUNTRY_CODE_2);
mScanDetails = setupScanDetails(TEST_COUNTRY_CODE_2);
mWifiCountryCode.updateCountryCodeFromScanResults(mScanDetails);
@@ -741,7 +746,7 @@ public class WifiCountryCodeTest extends WifiBaseTest {
@Test
public void testUpdateCountryCodeGenericWithTelephonyCountryCode() {
when(mTelephonyManager.getNetworkCountryIso()).thenReturn(TEST_COUNTRY_CODE_2);
- mResources.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, true);
+ mResourceCache.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, true);
mWifiCountryCode.updateCountryCodeFromScanResults(mScanDetails);
assertEquals(TEST_COUNTRY_CODE_2, mWifiCountryCode.getCountryCode());
}
@@ -749,14 +754,14 @@ public class WifiCountryCodeTest extends WifiBaseTest {
@Test
public void testUpdateountryCodeGenericMismatchScanResult() {
when(mNetworkDetail2.getCountryCode()).thenReturn(TEST_COUNTRY_CODE_2);
- mResources.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, true);
+ mResourceCache.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, true);
mWifiCountryCode.updateCountryCodeFromScanResults(mScanDetails);
assertEquals(mDefaultCountryCode, mWifiCountryCode.getCountryCode());
}
@Test
public void testUpdateountryCodeGenericOneGoodScanResult() {
- mResources.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, true);
+ mResourceCache.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, true);
mScanResult2.level = WifiCountryCode.MIN_SCAN_RSSI_DBM - 1;
mWifiCountryCode.updateCountryCodeFromScanResults(mScanDetails);
assertEquals(mDefaultCountryCode, mWifiCountryCode.getCountryCode());
@@ -764,11 +769,63 @@ public class WifiCountryCodeTest extends WifiBaseTest {
@Test
public void testUpdateountryCodeGenericTwoGoodScanResultUs() {
- mResources.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, true);
+ mResourceCache.setBoolean(R.bool.config_wifiUpdateCountryCodeFromScanResultGeneric, true);
mScanDetails = setupScanDetails("US");
mDefaultCountryCode = "CA";
when(mSettingsConfigStore.get(WIFI_DEFAULT_COUNTRY_CODE)).thenReturn(mDefaultCountryCode);
mWifiCountryCode.updateCountryCodeFromScanResults(mScanDetails);
assertEquals(mDefaultCountryCode, mWifiCountryCode.getCountryCode());
}
+
+ /**
+ * Test if we receive country code from Telephony after supplicant stop.
+ */
+ @Test
+ public void testCountryCodeDoesntChangeWhenIfClientModeChanged() {
+ // Start in scan only mode.
+ mModeChangeCallbackCaptor.getValue().onActiveModeManagerAdded(mClientModeManager);
+ assertEquals(mDefaultCountryCode, mWifiCountryCode.getCurrentDriverCountryCode());
+ // Supplicant starts.
+ when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
+ mModeChangeCallbackCaptor.getValue().onActiveModeManagerRoleChanged(mClientModeManager);
+ assertEquals(mDefaultCountryCode, mWifiCountryCode.getCurrentDriverCountryCode());
+ verify(mClientModeManager).setCountryCode(mDefaultCountryCode);
+ assertEquals(mDefaultCountryCode, mWifiCountryCode.getCurrentDriverCountryCode());
+
+ reset(mClientModeManager);
+ when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
+ // Wifi is connected and disconnected but there is no CC changed again
+ mClientModeImplListenerCaptor.getValue().onConnectionStart(mClientModeManager);
+ mClientModeImplListenerCaptor.getValue().onConnectionEnd(mClientModeManager);
+ verify(mClientModeManager, never()).setCountryCode(anyString());
+
+ when(mClientModeManager.setCountryCode(anyString())).thenReturn(false);
+ when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_SCAN_ONLY);
+ // Telephony country code arrives but set country code fail due to mode is being
+ // changed to scan mode.
+ mModeChangeCallbackCaptor.getValue().onActiveModeManagerRoleChanged(mClientModeManager);
+ mWifiCountryCode.setTelephonyCountryCodeAndUpdate(mTelephonyCountryCode);
+ verify(mClientModeManager).setCountryCode(mTelephonyCountryCode);
+ assertEquals(mDefaultCountryCode, mWifiCountryCode.getCurrentDriverCountryCode());
+
+ reset(mClientModeManager);
+ when(mClientModeManager.setCountryCode(anyString())).thenReturn(true);
+ when(mClientModeManager.getRole()).thenReturn(ROLE_CLIENT_PRIMARY);
+ doAnswer((invocation) -> {
+ if (SdkLevel.isAtLeastS()) {
+ mChangeListenerCaptor.getValue()
+ .onSetCountryCodeSucceeded(mSetCountryCodeCaptor.getValue());
+ }
+ if (mDriverSupportedNl80211RegChangedEvent) {
+ mChangeListenerCaptor.getValue()
+ .onDriverCountryCodeChanged(mSetCountryCodeCaptor.getValue());
+ }
+ return true;
+ }).when(mClientModeManager).setCountryCode(
+ mSetCountryCodeCaptor.capture());
+ // Mode is added back, country code should update to telephony country code.
+ mModeChangeCallbackCaptor.getValue().onActiveModeManagerRoleChanged(mClientModeManager);
+ verify(mClientModeManager).setCountryCode(mTelephonyCountryCode);
+ assertEquals(mTelephonyCountryCode, mWifiCountryCode.getCurrentDriverCountryCode());
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
index 61b6884dc5..592b16c420 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiDataStallTest.java
@@ -288,6 +288,23 @@ public class WifiDataStallTest extends WifiBaseTest {
WifiDataStall.CELLULAR_DATA_AVAILABLE);
}
+ @Test
+ public void verifyGetThroughputPredictorSpeeds() throws Exception {
+ WifiDataStall.Speeds speeds;
+
+ speeds = mWifiDataStall.getThrouhgputPredictorSpeeds(mWifiInfo, mCapabilities);
+ assertEquals(150_000, speeds.DownstreamKbps);
+ assertEquals(50_000, speeds.UpstreamKbps);
+
+ speeds = mWifiDataStall.getThrouhgputPredictorSpeeds(null, mCapabilities);
+ assertEquals(WifiDataStall.INVALID_THROUGHPUT, speeds.DownstreamKbps);
+ assertEquals(WifiDataStall.INVALID_THROUGHPUT, speeds.UpstreamKbps);
+
+ speeds = mWifiDataStall.getThrouhgputPredictorSpeeds(mWifiInfo, null);
+ assertEquals(WifiDataStall.INVALID_THROUGHPUT, speeds.DownstreamKbps);
+ assertEquals(WifiDataStall.INVALID_THROUGHPUT, speeds.UpstreamKbps);
+ }
+
/**
* Verify throughput when Rx link speed is unavailable.
* Also verify the logging of channel utilization and throughput.
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java
index dab681fca6..0fefd7ab9e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiGlobalsTest.java
@@ -47,6 +47,7 @@ public class WifiGlobalsTest extends WifiBaseTest {
private WifiGlobals mWifiGlobals;
private MockResources mResources;
+ private WifiResourceCache mWifiResourceCache;
@Mock private WifiContext mContext;
@@ -65,7 +66,8 @@ public class WifiGlobalsTest extends WifiBaseTest {
new String[] {TEST_SSID});
mResources.setStringArray(R.array.config_wifiAfcServerUrlsForCountry, new String[] {});
when(mContext.getResources()).thenReturn(mResources);
- when(mContext.getResourceCache()).thenReturn(new WifiResourceCache(mContext));
+ mWifiResourceCache = new WifiResourceCache(mContext);
+ when(mContext.getResourceCache()).thenReturn(mWifiResourceCache);
mWifiGlobals = new WifiGlobals(mContext);
}
@@ -75,6 +77,7 @@ public class WifiGlobalsTest extends WifiBaseTest {
public void testPollRssiIntervalIsSetCorrectly() throws Exception {
assertEquals(3000, mWifiGlobals.getPollRssiIntervalMillis());
mResources.setInteger(R.integer.config_wifiPollRssiIntervalMilliseconds, 9000);
+ mWifiResourceCache.reset();
assertEquals(9000, new WifiGlobals(mContext).getPollRssiIntervalMillis());
}
@@ -111,6 +114,7 @@ public class WifiGlobalsTest extends WifiBaseTest {
assertFalse(mWifiGlobals.isWpa3SaeH2eSupported());
mResources.setBoolean(R.bool.config_wifiSaeH2eSupported, true);
+ mWifiResourceCache.reset();
mWifiGlobals = new WifiGlobals(mContext);
assertTrue(mWifiGlobals.isWpa3SaeH2eSupported());
}
@@ -169,18 +173,21 @@ public class WifiGlobalsTest extends WifiBaseTest {
// Test config with too few items don't get added.
mResources.setStringArray(R.array.config_wifiEapFailureConfig,
new String[] {"1, 2, 3"});
+ mWifiResourceCache.reset();
mWifiGlobals = new WifiGlobals(mContext);
assertEquals(0, mWifiGlobals.getCarrierSpecificEapFailureConfigMapSize());
// Test config that fail to parse to int don't get added.
mResources.setStringArray(R.array.config_wifiEapFailureConfig,
new String[] {"1839, bad_config, 1, 1, 1440"});
+ mWifiResourceCache.reset();
mWifiGlobals = new WifiGlobals(mContext);
assertEquals(0, mWifiGlobals.getCarrierSpecificEapFailureConfigMapSize());
// Test correct config
mResources.setStringArray(R.array.config_wifiEapFailureConfig,
new String[] {"1839, 1031, 1, 1, 1440"});
+ mWifiResourceCache.reset();
mWifiGlobals = new WifiGlobals(mContext);
assertEquals(1, mWifiGlobals.getCarrierSpecificEapFailureConfigMapSize());
WifiBlocklistMonitor.CarrierSpecificEapFailureConfig config =
@@ -242,8 +249,8 @@ public class WifiGlobalsTest extends WifiBaseTest {
String afcServerUS3 = "https://www.android.com/";
mResources.setStringArray(R.array.config_wifiAfcServerUrlsForCountry,
new String[] {"US," + afcServerUS1 + "," + afcServerUS2 + "," + afcServerUS3});
+ mWifiResourceCache.reset();
mWifiGlobals = new WifiGlobals(mContext);
-
List<String> afcServersForUS = mWifiGlobals.getAfcServerUrlsForCountry("US");
assertEquals(3, afcServersForUS.size());
assertEquals(afcServerUS1, afcServersForUS.get(0));
@@ -281,7 +288,6 @@ public class WifiGlobalsTest extends WifiBaseTest {
@Test
public void testSetWepAllowedWhenWepIsNotDeprecated() {
mResources.setBoolean(R.bool.config_wifiWepAllowedControlSupported, true);
- mWifiGlobals = new WifiGlobals(mContext);
assertTrue(mWifiGlobals.isWepSupported());
// Default is not allow
assertFalse(mWifiGlobals.isWepAllowed());
@@ -296,7 +302,7 @@ public class WifiGlobalsTest extends WifiBaseTest {
// Test WEP allowed control is NOT supported.
mResources.setBoolean(R.bool.config_wifiWepAllowedControlSupported, false);
- mWifiGlobals = new WifiGlobals(mContext);
+ mWifiResourceCache.reset();
// Default is not allow, but don't care it since control is not supported.
assertFalse(mWifiGlobals.isWepAllowed());
// But we won't consider WEP is allowed since control is NOT supported.
@@ -308,10 +314,9 @@ public class WifiGlobalsTest extends WifiBaseTest {
@Test
public void isSwPnoEnabled() {
mResources.setBoolean(R.bool.config_wifiSwPnoEnabled, true);
- mWifiGlobals = new WifiGlobals(mContext);
assertTrue(mWifiGlobals.isSwPnoEnabled());
mResources.setBoolean(R.bool.config_wifiSwPnoEnabled, false);
- mWifiGlobals = new WifiGlobals(mContext);
+ mWifiResourceCache.reset();
assertFalse(mWifiGlobals.isSwPnoEnabled());
}
@@ -319,7 +324,6 @@ public class WifiGlobalsTest extends WifiBaseTest {
public void testIsD2dSupportedWhenInfraStaDisabled() {
mResources.setBoolean(R.bool.config_wifiD2dAllowedControlSupportedWhenInfraStaDisabled,
false);
- mWifiGlobals = new WifiGlobals(mContext);
mWifiGlobals.setD2dStaConcurrencySupported(true);
assertFalse(mWifiGlobals.isD2dSupportedWhenInfraStaDisabled());
mWifiGlobals.setD2dStaConcurrencySupported(false);
@@ -327,7 +331,7 @@ public class WifiGlobalsTest extends WifiBaseTest {
mResources.setBoolean(R.bool.config_wifiD2dAllowedControlSupportedWhenInfraStaDisabled,
true);
- mWifiGlobals = new WifiGlobals(mContext);
+ mWifiResourceCache.reset();
mWifiGlobals.setD2dStaConcurrencySupported(true);
assertFalse(mWifiGlobals.isD2dSupportedWhenInfraStaDisabled());
mWifiGlobals.setD2dStaConcurrencySupported(false);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
index 3c4f6c4db1..8035444dbc 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -36,11 +36,37 @@ import static com.android.server.wifi.WifiMetricsTestUtil.buildInt32Count;
import static com.android.server.wifi.WifiMetricsTestUtil.buildLinkProbeFailureReasonCount;
import static com.android.server.wifi.WifiMetricsTestUtil.buildLinkProbeFailureStaEvent;
import static com.android.server.wifi.WifiMetricsTestUtil.buildLinkProbeSuccessStaEvent;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_CELLULAR_MODEM;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_SIM_INSERTED;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_SCORING_DISABLED;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_CELLULAR_OFF;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_CELLULAR_UNAVAILABLE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_OTHERS;
import static com.android.server.wifi.proto.WifiStatsLog.WIFI_CONFIG_SAVED;
import static com.android.server.wifi.proto.WifiStatsLog.WIFI_IS_UNUSABLE_REPORTED;
import static com.android.server.wifi.proto.WifiStatsLog.WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_UNKNOWN;
import static com.android.server.wifi.proto.WifiStatsLog.WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE;
import static com.android.server.wifi.proto.nano.WifiMetricsProto.StaEvent.TYPE_LINK_PROBE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__UNKNOWN;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__TRUE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__FALSE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__UNKNOWN;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__TRUE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__FALSE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__UNKNOWN;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__TRUE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__FALSE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__UNKNOWN;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__TRUE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__FALSE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_FRAMEWORK_DATA_STALL;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_FIRMWARE_ALERT;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_IP_REACHABILITY_LOST;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_NONE;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_AWAKENING;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_CONNECTED;
+import static com.android.server.wifi.proto.WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_LINGERING;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -60,12 +86,16 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
import static java.lang.StrictMath.toIntExact;
import android.app.ActivityManager;
import android.content.Context;
+import android.net.ConnectivityManager;
import android.net.MacAddress;
+import android.net.Network;
+import android.net.NetworkCapabilities;
import android.net.wifi.EAPConstants;
import android.net.wifi.IOnWifiUsabilityStatsListener;
import android.net.wifi.MloLink;
@@ -138,6 +168,7 @@ import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiUsabilityStats;
import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiUsabilityStatsEntry;
import com.android.server.wifi.rtt.RttMetrics;
import com.android.server.wifi.util.InformationElementUtil;
+import com.android.wifi.flags.Flags;
import com.android.wifi.resources.R;
import org.junit.After;
@@ -186,6 +217,8 @@ public class WifiMetricsTest extends WifiBaseTest {
private static final String MLO_LINK_STA_MAC_ADDRESS = "12:34:56:78:9a:bc";
private static final String MLO_LINK_AP_MAC_ADDRESS = "bc:9a:78:56:34:12";
private static final int TEST_CHANNEL = 36;
+ private static final int POLLING_INTERVAL_DEFAULT = 3000;
+ private static final int POLLING_INTERVAL_NOT_DEFAULT = 6000;
private MockitoSession mSession;
@Mock Context mContext;
@@ -213,6 +246,11 @@ public class WifiMetricsTest extends WifiBaseTest {
@Mock WifiMonitor mWifiMonitor;
@Mock ActiveModeWarden mActiveModeWarden;
@Mock WifiDeviceStateChangeManager mWifiDeviceStateChangeManager;
+ @Mock ConnectivityManager mConnectivityManager;
+ @Mock NetworkCapabilities mNetworkCapabilities;
+ @Mock Network mNetwork;
+ @Mock WifiInfo mWifiInfo;
+ @Mock WifiNative.ConnectionCapabilities mCapabilities;
@Captor ArgumentCaptor<ActiveModeWarden.ModeChangeCallback> mModeChangeCallbackArgumentCaptor;
@Captor ArgumentCaptor<Handler> mHandlerCaptor;
@Captor
@@ -227,6 +265,13 @@ public class WifiMetricsTest extends WifiBaseTest {
mTestLooper = new TestLooper();
mResources = new MockResources();
when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
+ when(mConnectivityManager.getActiveNetwork()).thenReturn(mNetwork);
+ when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn(mNetworkCapabilities);
+ when(mNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
+ .thenReturn(true);
+ when(mNetworkCapabilities.getLinkDownstreamBandwidthKbps()).thenReturn(-1);
+ when(mNetworkCapabilities.getLinkUpstreamBandwidthKbps()).thenReturn(-1);
mWifiMetrics =
new WifiMetrics(
mContext,
@@ -274,7 +319,15 @@ public class WifiMetricsTest extends WifiBaseTest {
mSession = ExtendedMockito.mockitoSession()
.strictness(Strictness.LENIENT)
.mockStatic(WifiStatsLog.class)
+ .mockStatic(Flags.class, withSettings().lenient())
.startMocking();
+
+ when(mWifiInfo.getLinkSpeed()).thenReturn(10);
+ when(mWifiInfo.getRxLinkSpeedMbps()).thenReturn(10);
+ when(mWifiInfo.getFrequency()).thenReturn(5850);
+ when(mWifiInfo.getBSSID()).thenReturn("5G_WiFi");
+ when(mWifiInfo.getRssi()).thenReturn(-55);
+
}
@After
@@ -7316,4 +7369,470 @@ public class WifiMetricsTest extends WifiBaseTest {
eq(true), // mIsEcpsPriorityAccessSupported
eq(WifiStatsLog.WIFI_AP_CAPABILITIES_REPORTED__CHANNEL_WIDTH_MHZ__CHANNEL_WIDTH_160MHZ))); // mChannelWidth
}
+
+ @Test
+ public void getDeviceStateForScorer() {
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_CELLULAR_MODEM,
+ mWifiMetrics.getDeviceStateForScorer(false, false, false, false, false));
+
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_SIM_INSERTED,
+ mWifiMetrics.getDeviceStateForScorer(true, false, false, false, false));
+
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_SCORING_DISABLED,
+ mWifiMetrics.getDeviceStateForScorer(true, true, false, false, false));
+
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_CELLULAR_OFF,
+ mWifiMetrics.getDeviceStateForScorer(true, true, false, false, true));
+
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_CELLULAR_UNAVAILABLE,
+ mWifiMetrics.getDeviceStateForScorer(true, true, true, false, true));
+
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_OTHERS,
+ mWifiMetrics.getDeviceStateForScorer(true, true, true, true, true));
+ }
+
+ @Test
+ public void convertWifiUnusableTypeForScorer() {
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_FRAMEWORK_DATA_STALL,
+ mWifiMetrics.convertWifiUnusableTypeForScorer(
+ WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX));
+
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_FRAMEWORK_DATA_STALL,
+ mWifiMetrics.convertWifiUnusableTypeForScorer(
+ WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX));
+
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_FRAMEWORK_DATA_STALL,
+ mWifiMetrics.convertWifiUnusableTypeForScorer(
+ WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH));
+
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_FIRMWARE_ALERT,
+ mWifiMetrics.convertWifiUnusableTypeForScorer(
+ WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT));
+
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_IP_REACHABILITY_LOST,
+ mWifiMetrics.convertWifiUnusableTypeForScorer(
+ WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST));
+
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_NONE,
+ mWifiMetrics.convertWifiUnusableTypeForScorer(WifiIsUnusableEvent.TYPE_UNKNOWN));
+ }
+
+ @Test
+ public void getFrameworkStateForScorer() {
+ mWifiMetrics.mLastScreenOffTimeMillis = 3000;
+ mWifiMetrics.mLastIgnoredPollTimeMillis = 1000;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 4000);
+ assertEquals(
+ SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_AWAKENING,
+ mWifiMetrics.getFrameworkStateForScorer(false));
+ assertEquals(
+ SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_CONNECTED,
+ mWifiMetrics.getFrameworkStateForScorer(false));
+ assertEquals(
+ SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_LINGERING,
+ mWifiMetrics.getFrameworkStateForScorer(true));
+ }
+
+ @Test
+ public void calcNetworkCapabilitiesSufficient() {
+ WifiMetrics.Speeds speeds = new WifiMetrics.Speeds();
+ WifiMetrics.SpeedSufficient speedSufficient;
+
+ // Invalid / invalid
+ speeds.DownstreamKbps = WifiMetrics.INVALID_SPEED;
+ speeds.UpstreamKbps = WifiMetrics.INVALID_SPEED;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientNetworkCapabilities(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__UNKNOWN,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__UNKNOWN,
+ speedSufficient.Upstream);
+
+ // Low / invalid
+ speeds.DownstreamKbps = 0;
+ speeds.UpstreamKbps = WifiMetrics.INVALID_SPEED;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientNetworkCapabilities(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__FALSE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__UNKNOWN,
+ speedSufficient.Upstream);
+
+ // Barely bad / invalid
+ speeds.DownstreamKbps = 999;
+ speeds.UpstreamKbps = WifiMetrics.INVALID_SPEED;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientNetworkCapabilities(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__FALSE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__UNKNOWN,
+ speedSufficient.Upstream);
+
+ // Barely good / invalid
+ speeds.DownstreamKbps = 1000;
+ speeds.UpstreamKbps = WifiMetrics.INVALID_SPEED;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientNetworkCapabilities(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__TRUE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__UNKNOWN,
+ speedSufficient.Upstream);
+
+ // Good / invalid
+ speeds.DownstreamKbps = 2000;
+ speeds.UpstreamKbps = WifiMetrics.INVALID_SPEED;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientNetworkCapabilities(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__TRUE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__UNKNOWN,
+ speedSufficient.Upstream);
+
+ // Good / low
+ speeds.DownstreamKbps = 2000;
+ speeds.UpstreamKbps = 0;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientNetworkCapabilities(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__TRUE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__FALSE,
+ speedSufficient.Upstream);
+
+ // Good / Barely bad
+ speeds.DownstreamKbps = 2000;
+ speeds.UpstreamKbps = 999;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientNetworkCapabilities(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__TRUE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__FALSE,
+ speedSufficient.Upstream);
+
+ // Good / Barely good
+ speeds.DownstreamKbps = 2000;
+ speeds.UpstreamKbps = 1000;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientNetworkCapabilities(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__TRUE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__TRUE,
+ speedSufficient.Upstream);
+
+ // Good / Good
+ speeds.DownstreamKbps = 2000;
+ speeds.UpstreamKbps = 2000;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientNetworkCapabilities(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__TRUE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__TRUE,
+ speedSufficient.Upstream);
+
+ }
+
+ @Test
+ public void calcSpeedSufficientThroughputPredictor() {
+ WifiDataStall.Speeds speeds = new WifiDataStall.Speeds();
+ WifiMetrics.SpeedSufficient speedSufficient;
+
+ // Invalid / invalid
+ speeds.DownstreamKbps = WifiMetrics.INVALID_SPEED;
+ speeds.UpstreamKbps = WifiMetrics.INVALID_SPEED;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientThroughputPredictor(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__UNKNOWN,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__UNKNOWN,
+ speedSufficient.Upstream);
+
+ // Low / invalid
+ speeds.DownstreamKbps = 0;
+ speeds.UpstreamKbps = WifiMetrics.INVALID_SPEED;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientThroughputPredictor(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__FALSE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__UNKNOWN,
+ speedSufficient.Upstream);
+
+ // Barely bad / invalid
+ speeds.DownstreamKbps = 999;
+ speeds.UpstreamKbps = WifiMetrics.INVALID_SPEED;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientThroughputPredictor(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__FALSE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__UNKNOWN,
+ speedSufficient.Upstream);
+
+ // Barely good / invalid
+ speeds.DownstreamKbps = 1000;
+ speeds.UpstreamKbps = WifiMetrics.INVALID_SPEED;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientThroughputPredictor(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__TRUE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__UNKNOWN,
+ speedSufficient.Upstream);
+
+ // Good / invalid
+ speeds.DownstreamKbps = 2000;
+ speeds.UpstreamKbps = WifiMetrics.INVALID_SPEED;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientThroughputPredictor(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__TRUE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__UNKNOWN,
+ speedSufficient.Upstream);
+
+ // Good / low
+ speeds.DownstreamKbps = 2000;
+ speeds.UpstreamKbps = 0;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientThroughputPredictor(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__TRUE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__FALSE,
+ speedSufficient.Upstream);
+
+ // Good / Barely bad
+ speeds.DownstreamKbps = 2000;
+ speeds.UpstreamKbps = 999;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientThroughputPredictor(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__TRUE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__FALSE,
+ speedSufficient.Upstream);
+
+ // Good / Barely good
+ speeds.DownstreamKbps = 2000;
+ speeds.UpstreamKbps = 1000;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientThroughputPredictor(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__TRUE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__TRUE,
+ speedSufficient.Upstream);
+
+ // Good / Good
+ speeds.DownstreamKbps = 2000;
+ speeds.UpstreamKbps = 2000;
+ speedSufficient = mWifiMetrics.calcSpeedSufficientThroughputPredictor(speeds);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__TRUE,
+ speedSufficient.Downstream);
+ assertEquals(SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__TRUE,
+ speedSufficient.Upstream);
+
+ }
+
+ @Test
+ public void logScorerPredictionResult_withoutExternalScorer() {
+ when(mWifiDataStall.isThroughputSufficient()).thenReturn(false);
+ when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 10000);
+
+ WifiMetrics.ConnectionEvent connectionEvent = mWifiMetrics.new ConnectionEvent();
+ WifiMetrics.SessionData currentSession =
+ new WifiMetrics.SessionData(connectionEvent, "", (long) 1000, 0, 0);
+ mWifiMetrics.mCurrentSession = currentSession;
+
+ mWifiMetrics.logScorerPredictionResult(false, false, false, POLLING_INTERVAL_DEFAULT,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ true, mWifiInfo, mCapabilities);
+
+ ExtendedMockito.verify(() -> WifiStatsLog.write_non_chained(
+ SCORER_PREDICTION_RESULT_REPORTED,
+ Process.WIFI_UID, null,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_NONE,
+ false,
+ SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_CELLULAR_MODEM,
+ POLLING_INTERVAL_DEFAULT,
+ SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_AWAKENING,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__UNKNOWN
+ ));
+ }
+
+ @Test
+ public void logScorerPredictionResult_withExternalScorer() {
+ mWifiMetrics.setIsExternalWifiScorerOn(true, TEST_UID);
+ when(mWifiDataStall.isThroughputSufficient()).thenReturn(false);
+ when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 10000);
+
+ WifiMetrics.ConnectionEvent connectionEvent = mWifiMetrics.new ConnectionEvent();
+ WifiMetrics.SessionData currentSession =
+ new WifiMetrics.SessionData(connectionEvent, "", (long) 1000, 0, 0);
+ mWifiMetrics.mCurrentSession = currentSession;
+
+ mWifiMetrics.logScorerPredictionResult(false, false, false, POLLING_INTERVAL_DEFAULT,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ true, mWifiInfo, mCapabilities);
+
+ ExtendedMockito.verify(() -> WifiStatsLog.write_non_chained(
+ SCORER_PREDICTION_RESULT_REPORTED,
+ Process.WIFI_UID, null,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_NONE,
+ false,
+ SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_CELLULAR_MODEM,
+ POLLING_INTERVAL_DEFAULT,
+ SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_AWAKENING,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__UNKNOWN
+ ));
+ ExtendedMockito.verify(() -> WifiStatsLog.write_non_chained(
+ SCORER_PREDICTION_RESULT_REPORTED,
+ TEST_UID, null,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_NONE,
+ false,
+ SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_CELLULAR_MODEM,
+ POLLING_INTERVAL_DEFAULT,
+ SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_AWAKENING,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__UNKNOWN
+ ));
+ }
+
+ @Test
+ public void logScorerPredictionResult_notDefaultPollingInterval() {
+ when(mWifiDataStall.isThroughputSufficient()).thenReturn(false);
+ when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 10000);
+
+ WifiMetrics.ConnectionEvent connectionEvent = mWifiMetrics.new ConnectionEvent();
+ WifiMetrics.SessionData currentSession =
+ new WifiMetrics.SessionData(connectionEvent, "", (long) 1000, 0, 0);
+ mWifiMetrics.mCurrentSession = currentSession;
+
+ mWifiMetrics.logScorerPredictionResult(false, false, false, POLLING_INTERVAL_NOT_DEFAULT,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ true, mWifiInfo, mCapabilities);
+
+ ExtendedMockito.verify(() -> WifiStatsLog.write_non_chained(
+ SCORER_PREDICTION_RESULT_REPORTED,
+ Process.WIFI_UID, null,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_NONE,
+ false,
+ SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_CELLULAR_MODEM,
+ POLLING_INTERVAL_NOT_DEFAULT,
+ SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_AWAKENING,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__UNKNOWN
+ ));
+ }
+
+ @Test
+ public void logScorerPredictionResult_withUnusableEvent() {
+ when(mWifiDataStall.isThroughputSufficient()).thenReturn(false);
+ when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 10000);
+
+ WifiMetrics.ConnectionEvent connectionEvent = mWifiMetrics.new ConnectionEvent();
+ WifiMetrics.SessionData currentSession =
+ new WifiMetrics.SessionData(connectionEvent, "", (long) 1000, 0, 0);
+ mWifiMetrics.mCurrentSession = currentSession;
+
+ mWifiMetrics.logWifiIsUnusableEvent(TEST_IFACE_NAME,
+ WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX);
+
+ mWifiMetrics.logScorerPredictionResult(false, false, false, POLLING_INTERVAL_DEFAULT,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ true, mWifiInfo, mCapabilities);
+
+ ExtendedMockito.verify(() -> WifiStatsLog.write_non_chained(
+ SCORER_PREDICTION_RESULT_REPORTED,
+ Process.WIFI_UID, null,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_FRAMEWORK_DATA_STALL,
+ false,
+ SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_CELLULAR_MODEM,
+ POLLING_INTERVAL_DEFAULT,
+ SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_AWAKENING,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__UNKNOWN
+ ));
+ }
+
+ @Test
+ public void logScorerPredictionResult_wifiSufficient() {
+ when(mWifiDataStall.isThroughputSufficient()).thenReturn(true);
+ when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 10000);
+
+ WifiMetrics.ConnectionEvent connectionEvent = mWifiMetrics.new ConnectionEvent();
+ WifiMetrics.SessionData currentSession =
+ new WifiMetrics.SessionData(connectionEvent, "", (long) 1000, 0, 0);
+ mWifiMetrics.mCurrentSession = currentSession;
+
+ mWifiMetrics.logScorerPredictionResult(false, false, false, POLLING_INTERVAL_DEFAULT,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ true, mWifiInfo, mCapabilities);
+
+ ExtendedMockito.verify(() -> WifiStatsLog.write_non_chained(
+ SCORER_PREDICTION_RESULT_REPORTED,
+ Process.WIFI_UID, null,
+ WIFI_IS_UNUSABLE_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ SCORER_PREDICTION_RESULT_REPORTED__UNUSABLE_EVENT__EVENT_NONE,
+ true,
+ SCORER_PREDICTION_RESULT_REPORTED__DEVICE_STATE__STATE_NO_CELLULAR_MODEM,
+ POLLING_INTERVAL_DEFAULT,
+ SCORER_PREDICTION_RESULT_REPORTED__WIFI_FRAMEWORK_STATE__FRAMEWORK_STATE_AWAKENING,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_DS__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_NETWORK_CAPABILITIES_US__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_DS__UNKNOWN,
+ SCORER_PREDICTION_RESULT_REPORTED__SPEED_SUFFICIENT_THROUGHPUT_PREDICTOR_US__UNKNOWN
+ ));
+ }
+
+ @Test
+ public void resetWifiUnusableEvent() {
+ long eventTime = 0;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(eventTime);
+
+ mWifiMetrics.logWifiIsUnusableEvent(TEST_IFACE_NAME,
+ WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX);
+ assertEquals(WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX, mWifiMetrics.mUnusableEventType);
+ mWifiMetrics.resetWifiUnusableEvent();
+ assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN, mWifiMetrics.mUnusableEventType);
+
+ eventTime += WifiMetrics.MIN_DATA_STALL_WAIT_MS;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(eventTime);
+ mWifiMetrics.logWifiIsUnusableEvent(TEST_IFACE_NAME,
+ WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX);
+ assertEquals(WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX,
+ mWifiMetrics.mUnusableEventType);
+ mWifiMetrics.resetWifiUnusableEvent();
+ assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN, mWifiMetrics.mUnusableEventType);
+
+ eventTime += WifiMetrics.MIN_DATA_STALL_WAIT_MS;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(eventTime);
+ mWifiMetrics.logWifiIsUnusableEvent(TEST_IFACE_NAME,
+ WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH);
+ assertEquals(WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH, mWifiMetrics.mUnusableEventType);
+ mWifiMetrics.resetWifiUnusableEvent();
+ assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN, mWifiMetrics.mUnusableEventType);
+
+ eventTime += WifiMetrics.MIN_DATA_STALL_WAIT_MS;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(eventTime);
+ mWifiMetrics.logWifiIsUnusableEvent(TEST_IFACE_NAME,
+ WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT);
+ assertEquals(WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT, mWifiMetrics.mUnusableEventType);
+ mWifiMetrics.resetWifiUnusableEvent();
+ assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN, mWifiMetrics.mUnusableEventType);
+
+ eventTime += WifiMetrics.MIN_DATA_STALL_WAIT_MS;
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(eventTime);
+ mWifiMetrics.logWifiIsUnusableEvent(TEST_IFACE_NAME,
+ WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST);
+ assertEquals(WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST, mWifiMetrics.mUnusableEventType);
+ mWifiMetrics.resetWifiUnusableEvent();
+ assertEquals(WifiIsUnusableEvent.TYPE_UNKNOWN, mWifiMetrics.mUnusableEventType);
+ }
+
+ /** Verifies WiFi Scorer new stats collection flag could be set properly */
+ @Test
+ public void verifyWifiScorerNewStatsCollectionFlagTrue() {
+ when(Flags.wifiScorerNewStatsCollection()).thenReturn(true);
+ assertEquals(mWifiMetrics.isWiFiScorerNewStatsCollected(), true);
+ when(Flags.wifiScorerNewStatsCollection()).thenReturn(false);
+ assertEquals(mWifiMetrics.isWiFiScorerNewStatsCollected(), false);
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
index 0fcc471052..e2806fe6de 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeInterfaceManagementTest.java
@@ -72,6 +72,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.List;
import java.util.Set;
@@ -85,7 +86,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
private static final String IFACE_NAME_1 = "mockWlan1";
private static final String SELF_RECOVERY_IFACE_NAME = "mockWlan2";
private static final WorkSource TEST_WORKSOURCE = new WorkSource();
- private static final long TEST_SUPPORTED_FEATURES = 0;
+ private static final long[] TEST_SUPPORTED_FEATURES = new long[]{ 0 };
private static final int STA_FAILURE_CODE_START_DAEMON = 1;
private static final int STA_FAILURE_CODE_SETUP_INTERFACE = 2;
private static final int STA_FAILURE_CODE_WIFICOND_SETUP_INTERFACE = 3;
@@ -180,6 +181,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
new ArrayList<>());
when(mWifiVendorHal.enableStaChannelForPeerNetwork(anyBoolean(), anyBoolean())).thenReturn(
true);
+ when(mWifiVendorHal.getSupportedFeatureSet(anyString())).thenReturn(new BitSet());
when(mBuildProperties.isEngBuild()).thenReturn(false);
when(mBuildProperties.isUserdebugBuild()).thenReturn(false);
@@ -202,6 +204,8 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
when(mSupplicantStaIfaceHal.startDaemon()).thenReturn(true);
when(mSupplicantStaIfaceHal.setupIface(any())).thenReturn(true);
when(mSupplicantStaIfaceHal.teardownIface(any())).thenReturn(true);
+ when(mSupplicantStaIfaceHal.getAdvancedCapabilities(anyString())).thenReturn(new BitSet());
+ when(mSupplicantStaIfaceHal.getWpaDriverFeatureSet(anyString())).thenReturn(new BitSet());
when(mHostapdHal.registerDeathHandler(mHostapdDeathHandlerCaptor.capture()))
.thenReturn(true);
@@ -231,7 +235,7 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
when(mDeviceConfigFacade.isInterfaceFailureBugreportEnabled()).thenReturn(false);
when(mWifiSettingsConfigStore.get(
- eq(WifiSettingsConfigStore.WIFI_NATIVE_SUPPORTED_FEATURES)))
+ eq(WifiSettingsConfigStore.WIFI_NATIVE_EXTENDED_SUPPORTED_FEATURES)))
.thenReturn(TEST_SUPPORTED_FEATURES);
when(mWifiSettingsConfigStore.get(
eq(WifiSettingsConfigStore.WIFI_NATIVE_SUPPORTED_STA_BANDS)))
@@ -581,8 +585,8 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mSupplicantStaIfaceHal).isInitializationStarted();
mInOrder.verify(mSupplicantStaIfaceHal).terminate();
mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mWifiVendorHal).getTwtCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
}
@@ -609,8 +613,8 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mNetdWrapper).isInterfaceUp(ifaceName);
mInOrder.verify(mWifiVendorHal).enableLinkLayerStats(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mWifiVendorHal).getTwtCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
mInOrder.verify(mWifiVendorHal).enableStaChannelForPeerNetwork(anyBoolean(), anyBoolean());
@@ -622,8 +626,8 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mNetdWrapper).registerObserver(networkObserverCaptor.capture());
mInOrder.verify(mNetdWrapper).isInterfaceUp(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mWifiVendorHal).getTwtCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
}
@@ -1377,8 +1381,8 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mWifiMetrics).incrementNumSetupClientInterfaceFailureDueToSupplicant();
} else {
mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mWifiVendorHal).getTwtCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
}
@@ -1829,8 +1833,8 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mNetdWrapper).isInterfaceUp(ifaceName);
mInOrder.verify(mWifiVendorHal).enableLinkLayerStats(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mWifiVendorHal).getTwtCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
mInOrder.verify(mWifiVendorHal).enableStaChannelForPeerNetwork(anyBoolean(), anyBoolean());
@@ -2045,8 +2049,8 @@ public class WifiNativeInterfaceManagementTest extends WifiBaseTest {
mInOrder.verify(mNetdWrapper).registerObserver(networkObserverCaptor.capture());
mInOrder.verify(mNetdWrapper).isInterfaceUp(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getAdvancedCapabilities(ifaceName);
- mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mSupplicantStaIfaceHal).getWpaDriverFeatureSet(ifaceName);
+ mInOrder.verify(mWifiVendorHal).getSupportedFeatureSet(ifaceName);
mInOrder.verify(mWifiVendorHal).getTwtCapabilities(ifaceName);
mInOrder.verify(mWifiVendorHal).getUsableChannels(anyInt(), anyInt(), anyInt());
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
index cff25254dd..a970e187a1 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
@@ -20,6 +20,8 @@ import static android.net.wifi.WifiScanner.WIFI_BAND_24_GHZ;
import static android.net.wifi.WifiScanner.WIFI_BAND_5_GHZ;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_NATIVE_SUPPORTED_FEATURES;
+import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_NATIVE_EXTENDED_SUPPORTED_FEATURES;
+import static com.android.server.wifi.util.GeneralUtil.longToBitset;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -43,6 +45,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.validateMockitoUsage;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
import android.net.MacAddress;
import android.net.wifi.CoexUnsafeChannel;
@@ -52,6 +55,7 @@ import android.net.wifi.WifiAvailableChannel;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiContext;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiMigration;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiScanner.ScanData;
import android.net.wifi.WifiSsid;
@@ -73,6 +77,7 @@ import com.android.server.wifi.hal.WifiChip;
import com.android.server.wifi.proto.WifiStatsLog;
import com.android.server.wifi.util.NativeUtil;
import com.android.server.wifi.util.NetdWrapper;
+import com.android.wifi.flags.Flags;
import com.android.wifi.resources.R;
import org.junit.After;
@@ -89,6 +94,7 @@ import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.Collections;
import java.util.List;
import java.util.Random;
@@ -250,7 +256,7 @@ public class WifiNativeTest extends WifiBaseTest {
return result;
}
- public static final long WIFI_TEST_FEATURE = 0x800000000L;
+ private static final BitSet WIFI_TEST_FEATURE = longToBitset(0x800000000L);
private static final RadioChainInfo MOCK_NATIVE_RADIO_CHAIN_INFO_1 = new RadioChainInfo(1, -89);
private static final RadioChainInfo MOCK_NATIVE_RADIO_CHAIN_INFO_2 = new RadioChainInfo(0, -78);
@@ -302,6 +308,7 @@ public class WifiNativeTest extends WifiBaseTest {
.thenReturn(WIFI_IFACE_NAME);
when(mWifiVendorHal.createApIface(any(), any(), anyInt(), anyBoolean(), any(), anyList()))
.thenReturn(WIFI_IFACE_NAME);
+ when(mWifiVendorHal.getSupportedFeatureSet(anyString())).thenReturn(new BitSet());
when(mBuildProperties.isEngBuild()).thenReturn(false);
when(mBuildProperties.isUserdebugBuild()).thenReturn(false);
@@ -316,6 +323,8 @@ public class WifiNativeTest extends WifiBaseTest {
when(mStaIfaceHal.initialize()).thenReturn(true);
when(mStaIfaceHal.startDaemon()).thenReturn(true);
when(mStaIfaceHal.setupIface(any())).thenReturn(true);
+ when(mStaIfaceHal.getAdvancedCapabilities(anyString())).thenReturn(new BitSet());
+ when(mStaIfaceHal.getWpaDriverFeatureSet(anyString())).thenReturn(new BitSet());
when(mHostapdHal.isInitializationStarted()).thenReturn(true);
when(mHostapdHal.startDaemon()).thenReturn(true);
@@ -332,8 +341,8 @@ public class WifiNativeTest extends WifiBaseTest {
mResources = getMockResources();
mResources.setBoolean(R.bool.config_wifiNetworkCentricQosPolicyFeatureEnabled, false);
when(mContext.getResources()).thenReturn(mResources);
- when(mSettingsConfigStore.get(eq(WIFI_NATIVE_SUPPORTED_FEATURES)))
- .thenReturn(WIFI_TEST_FEATURE);
+ when(mSettingsConfigStore.get(eq(WIFI_NATIVE_EXTENDED_SUPPORTED_FEATURES)))
+ .thenReturn(WIFI_TEST_FEATURE.toLongArray());
when(mSsidTranslator.getTranslatedSsidAndRecordBssidCharset(any(), any()))
.thenAnswer((Answer<WifiSsid>) invocation ->
getTranslatedSsid(invocation.getArgument(0)));
@@ -344,8 +353,12 @@ public class WifiNativeTest extends WifiBaseTest {
mSession = ExtendedMockito.mockitoSession()
.strictness(Strictness.LENIENT)
.mockStatic(WifiStatsLog.class)
+ .mockStatic(Flags.class, withSettings().lenient())
+ .mockStatic(WifiMigration.class, withSettings().lenient())
.startMocking();
+ when(Flags.rsnOverriding()).thenReturn(false);
+
mWifiNative = new WifiNative(
mWifiVendorHal, mStaIfaceHal, mHostapdHal, mWificondControl,
mWifiMonitor, mPropertyService, mWifiMetrics,
@@ -1586,13 +1599,34 @@ public class WifiNativeTest extends WifiBaseTest {
/**
* Tests that getSupportedFeatureSet() guaranteed to include the feature set stored in config
- * store even when interface doesn't exist.
- *
+ * store even when interface doesn't exist. If both legacy and extended features are stored in
+ * the config store, then the extended features should be returned.
*/
@Test
- public void testGetSupportedFeatureSetWhenInterfaceDoesntExist() throws Exception {
- long featureSet = mWifiNative.getSupportedFeatureSet(null);
- assertEquals(featureSet, WIFI_TEST_FEATURE);
+ public void testGetExtendedFeaturesWhenInterfaceDoesntExist() throws Exception {
+ long legacyFeatures = 0x321;
+ when(mSettingsConfigStore.get(eq(WIFI_NATIVE_SUPPORTED_FEATURES)))
+ .thenReturn(legacyFeatures);
+ when(mSettingsConfigStore.get(eq(WIFI_NATIVE_EXTENDED_SUPPORTED_FEATURES)))
+ .thenReturn(WIFI_TEST_FEATURE.toLongArray());
+ BitSet featureSet = longToBitset(mWifiNative.getSupportedFeatureSet(null));
+ assertTrue(featureSet.equals(WIFI_TEST_FEATURE));
+ }
+
+ /**
+ * Tests that getSupportedFeatureSet() guaranteed to include the feature set stored in config
+ * store even when interface doesn't exist. If only legacy features are stored in the
+ * config store, then they should be returned.
+ */
+ @Test
+ public void testGetLegacyFeaturesWhenInterfaceDoesntExist() throws Exception {
+ long legacyFeatures = 0x321;
+ when(mSettingsConfigStore.get(eq(WIFI_NATIVE_SUPPORTED_FEATURES)))
+ .thenReturn(legacyFeatures);
+ when(mSettingsConfigStore.get(eq(WIFI_NATIVE_EXTENDED_SUPPORTED_FEATURES)))
+ .thenReturn(new long[0]); // no extended features
+ BitSet featureSet = longToBitset(mWifiNative.getSupportedFeatureSet(null));
+ assertTrue(featureSet.equals(longToBitset(legacyFeatures)));
}
/**
@@ -1820,4 +1854,18 @@ public class WifiNativeTest extends WifiBaseTest {
WifiManager.ROAMING_MODE_NORMAL));
verify(mWifiVendorHal).setRoamingMode(WIFI_IFACE_NAME, WifiManager.ROAMING_MODE_NORMAL);
}
+
+ @Test
+ public void testRsnOverridingFeatureFlag() throws Exception {
+ mResources.setBoolean(R.bool.config_wifiRsnOverridingEnabled, true);
+ when(Flags.rsnOverriding()).thenReturn(false);
+ mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE,
+ mConcreteClientModeManager);
+ assertFalse(mWifiNative.mIsRsnOverridingSupported);
+ mWifiNative.teardownAllInterfaces();
+ when(Flags.rsnOverriding()).thenReturn(true);
+ mWifiNative.setupInterfaceForClientInScanMode(null, TEST_WORKSOURCE,
+ mConcreteClientModeManager);
+ assertTrue(mWifiNative.mIsRsnOverridingSupported);
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
index 87dce767a5..14048100e0 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
@@ -18,6 +18,7 @@ package com.android.server.wifi;
import static android.net.wifi.WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_AUTHENTICATION;
import static android.net.wifi.WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_IP_PROVISIONING;
+import static android.net.wifi.WifiManager.STATUS_LOCAL_ONLY_CONNECTION_FAILURE_USER_REJECT;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.server.wifi.WifiNetworkFactory.PERIODIC_SCAN_INTERVAL_MS;
@@ -105,6 +106,7 @@ import com.android.server.wifi.proto.nano.WifiMetricsProto;
import com.android.server.wifi.util.ActionListenerWrapper;
import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.WifiPermissionsUtil;
+import com.android.wifi.flags.FeatureFlags;
import com.android.wifi.resources.R;
import org.junit.After;
@@ -154,6 +156,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
private static final String TEST_BSSID_1_2_OUI = "12:34:23:00:00:00";
private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
private static final String TEST_WPA_PRESHARED_KEY = "\"password123\"";
+ private static final int TEST_PREFERRED_CHANNEL_FREQ = 5260;
@Mock WifiContext mContext;
@Mock Resources mResources;
@@ -187,6 +190,8 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
private @Mock ClientModeManager mPrimaryClientModeManager;
private @Mock WifiGlobals mWifiGlobals;
@Mock WifiDeviceStateChangeManager mWifiDeviceStateChangeManager;
+ @Mock FeatureFlags mFeatureFlags;
+ @Mock DeviceConfigFacade mDeviceConfigFacade;
private MockitoSession mStaticMockSession = null;
NetworkCapabilities mNetworkCapabilities;
TestLooper mLooper;
@@ -264,11 +269,13 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
when(mPackageManager.getApplicationLabel(any())).thenReturn(TEST_APP_NAME);
mockPackageImportance(TEST_PACKAGE_NAME_1, true, false);
mockPackageImportance(TEST_PACKAGE_NAME_2, true, false);
+ when(mDeviceConfigFacade.getFeatureFlags()).thenReturn(mFeatureFlags);
when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner);
when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden);
when(mWifiInjector.getWifiGlobals()).thenReturn(mWifiGlobals);
when(mWifiInjector.getWifiDeviceStateChangeManager())
.thenReturn(mWifiDeviceStateChangeManager);
+ when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade);
when(mWifiGlobals.isWpa3SaeUpgradeEnabled()).thenReturn(true);
when(mWifiGlobals.isOweUpgradeEnabled()).thenReturn(true);
when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), anyString(), eq(false)))
@@ -712,7 +719,8 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testHandleNetworkRequestWithSpecifier() {
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0], false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false,
+ new int[]{TEST_PREFERRED_CHANNEL_FREQ}, false);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Verify UI start.
@@ -721,7 +729,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
// Verify scan settings.
verify(mWifiScanner).startScan(mScanSettingsArgumentCaptor.capture(), any(), any(),
mWorkSourceArgumentCaptor.capture());
- validateScanSettings(null, new int[0]);
+ validateScanSettings(null, new int[]{TEST_PREFERRED_CHANNEL_FREQ});
verify(mWifiMetrics).incrementNetworkRequestApiNumRequest();
}
@@ -764,7 +772,8 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testHandleNetworkRequestWithSpecifierForHiddenNetwork() {
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, true, new int[0], false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, true,
+ new int[]{TEST_PREFERRED_CHANNEL_FREQ}, false);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Verify UI start.
@@ -775,7 +784,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
mWorkSourceArgumentCaptor.capture());
validateScanSettings(
((WifiNetworkSpecifier) mNetworkCapabilities.getNetworkSpecifier())
- .ssidPatternMatcher.getPath(), new int[0]);
+ .ssidPatternMatcher.getPath(), new int[]{TEST_PREFERRED_CHANNEL_FREQ});
verify(mWifiMetrics).incrementNetworkRequestApiNumRequest();
}
@@ -789,25 +798,27 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
@Test
public void testHandleNetworkRequestWithSpecifierAfterPreviousHiddenNetworkRequest() {
// Hidden request 1.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, true, new int[0], false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, true,
+ new int[]{TEST_PREFERRED_CHANNEL_FREQ}, false);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Verify scan settings.
verify(mWifiScanner, times(1)).startScan(mScanSettingsArgumentCaptor.capture(), any(),
any(), mWorkSourceArgumentCaptor.capture());
validateScanSettings(
((WifiNetworkSpecifier) mNetworkCapabilities.getNetworkSpecifier())
- .ssidPatternMatcher.getPath(), new int[0]);
+ .ssidPatternMatcher.getPath(), new int[]{TEST_PREFERRED_CHANNEL_FREQ});
// Release request 1.
mWifiNetworkFactory.releaseNetworkFor(mNetworkRequest);
// Regular request 2.
- attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false, new int[0], false);
+ attachDefaultWifiNetworkSpecifierAndAppInfo(TEST_UID_1, false,
+ new int[]{TEST_PREFERRED_CHANNEL_FREQ}, false);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
// Verify scan settings.
verify(mWifiScanner, times(2)).startScan(mScanSettingsArgumentCaptor.capture(), any(),
any(), mWorkSourceArgumentCaptor.capture());
- validateScanSettings(null, new int[0]);
+ validateScanSettings(null, new int[]{TEST_PREFERRED_CHANNEL_FREQ});
verify(mWifiMetrics, times(2)).incrementNetworkRequestApiNumRequest();
}
@@ -1682,8 +1693,10 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
*/
@Test
public void testNetworkSpecifierHandleUserSelectionReject() throws Exception {
+ when(mFeatureFlags.localOnlyConnectionOptimization()).thenReturn(true);
sendNetworkRequestAndSetupForUserSelection();
-
+ mWifiNetworkFactory.addLocalOnlyConnectionStatusListener(mLocalOnlyConnectionStatusListener,
+ TEST_PACKAGE_NAME_1, null);
INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
mNetworkRequestUserSelectionCallback.getValue();
assertNotNull(networkRequestUserSelectionCallback);
@@ -1698,6 +1711,9 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mConnectivityManager).declareNetworkRequestUnfulfillable(eq(mNetworkRequest));
verify(mWifiMetrics).incrementNetworkRequestApiNumUserReject();
+ verify(mLocalOnlyConnectionStatusListener).onConnectionStatus(
+ eq((WifiNetworkSpecifier) mNetworkRequest.getNetworkSpecifier()),
+ eq(STATUS_LOCAL_ONLY_CONNECTION_FAILURE_USER_REJECT));
// Verify we did not attempt to trigger a connection.
verifyNoMoreInteractions(mClientModeManager, mWifiConfigManager);
@@ -4047,7 +4063,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
private void validateScanSettings(@Nullable String hiddenSsid, int[] channels) {
ScanSettings scanSettings = mScanSettingsArgumentCaptor.getValue();
assertNotNull(scanSettings);
- assertEquals(WifiScanner.WIFI_BAND_ALL, scanSettings.band);
+ assertEquals(WifiScanner.WIFI_BAND_UNSPECIFIED, scanSettings.band);
assertEquals(WifiScanner.SCAN_TYPE_HIGH_ACCURACY, scanSettings.type);
assertEquals(WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, scanSettings.reportEvents);
if (hiddenSsid == null) {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
index 131f7de508..09f5969952 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
@@ -89,6 +89,7 @@ import android.os.UserHandle;
import android.os.test.TestLooper;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.LocalLog;
import android.view.LayoutInflater;
@@ -156,7 +157,8 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
private static final String TEST_IMSI = "123456*";
private static final int DEFAULT_PRIORITY_GROUP = 0;
private static final int TEST_PRIORITY_GROUP = 1;
- private static final String TEST_ANONYMOUS_IDENTITY = "AnonymousIdentity";
+ private static final String TEST_ANONYMOUS_IDENTITY_1 = "AnonymousIdentity1";
+ private static final String TEST_ANONYMOUS_IDENTITY_2 = "AnonymousIdentity2";
private static final String USER_CONNECT_CHOICE = "SomeNetworkProfileId";
private static final int TEST_RSSI = -50;
private static final ParcelUuid GROUP_UUID = ParcelUuid
@@ -750,7 +752,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
config.ephemeral = true;
config.creatorName = TEST_PACKAGE_1;
config.creatorUid = TEST_UID_1;
- config.enterpriseConfig.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY);
+ config.enterpriseConfig.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY_1);
WifiConfigManager.OnNetworkUpdateListener listener = mNetworkListenerCaptor.getValue();
listener.onConnectChoiceSet(List.of(config), USER_CONNECT_CHOICE, TEST_RSSI);
mWifiNetworkSuggestionsManager.setAnonymousIdentity(config);
@@ -786,7 +788,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
// As user changes the auto-join, will keep the user choice.
assertFalse(matchedSuggestion.isAutojoinEnabled);
// Verify user connect choice and Anonymous Identity are preserved during the modify.
- assertEquals(TEST_ANONYMOUS_IDENTITY, matchedSuggestion.anonymousIdentity);
+ assertEquals(TEST_ANONYMOUS_IDENTITY_1, matchedSuggestion.anonymousIdentity);
assertEquals(USER_CONNECT_CHOICE, matchedSuggestion.connectChoice);
assertEquals(TEST_RSSI, matchedSuggestion.connectChoiceRssi);
@@ -4722,7 +4724,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
.thenReturn(true);
WifiConfiguration eapSimConfig = WifiConfigurationTestUtil.createWpa2Wpa3EnterpriseNetwork(
WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE);
- eapSimConfig.enterpriseConfig.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY);
+ eapSimConfig.enterpriseConfig.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY_1);
WifiNetworkSuggestion networkSuggestion = createWifiNetworkSuggestion(
new WifiConfiguration(eapSimConfig), null, false, false, true, true,
DEFAULT_PRIORITY_GROUP);
@@ -4738,25 +4740,26 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
configuration.ephemeral = true;
configuration.creatorName = TEST_PACKAGE_1;
configuration.creatorUid = TEST_UID_1;
- configuration.enterpriseConfig.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY);
+ configuration.enterpriseConfig.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY_1);
Set<ExtendedWifiNetworkSuggestion> matchedSuggestions = mWifiNetworkSuggestionsManager
.getNetworkSuggestionsForWifiConfiguration(configuration,
TEST_BSSID);
for (ExtendedWifiNetworkSuggestion ewns : matchedSuggestions) {
assertNull(ewns.anonymousIdentity);
- assertEquals(TEST_ANONYMOUS_IDENTITY,
+ assertEquals(TEST_ANONYMOUS_IDENTITY_1,
ewns.createInternalWifiConfiguration(mWifiCarrierInfoManager)
.enterpriseConfig.getAnonymousIdentity());
}
+ configuration.enterpriseConfig.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY_2);
mWifiNetworkSuggestionsManager.setAnonymousIdentity(configuration);
matchedSuggestions = mWifiNetworkSuggestionsManager
.getNetworkSuggestionsForWifiConfiguration(configuration,
TEST_BSSID);
for (ExtendedWifiNetworkSuggestion ewns : matchedSuggestions) {
- assertEquals(TEST_ANONYMOUS_IDENTITY, ewns.anonymousIdentity);
+ assertEquals(TEST_ANONYMOUS_IDENTITY_2, ewns.anonymousIdentity);
}
// Reset SIM network suggestion, Anonymous Identity should gone.
@@ -4766,7 +4769,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
TEST_BSSID);
for (ExtendedWifiNetworkSuggestion ewns : matchedSuggestions) {
assertEquals(null, ewns.anonymousIdentity);
- assertEquals(TEST_ANONYMOUS_IDENTITY,
+ assertEquals(TEST_ANONYMOUS_IDENTITY_1,
ewns.createInternalWifiConfiguration(mWifiCarrierInfoManager)
.enterpriseConfig.getAnonymousIdentity());
}
@@ -4774,6 +4777,68 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest {
}
@Test
+ public void testSetAnonymousIdentityNullOnSuggestionNetwork() {
+ when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(TEST_UID_1))
+ .thenReturn(true);
+ WifiConfiguration eapSimConfig = WifiConfigurationTestUtil.createWpa2Wpa3EnterpriseNetwork(
+ WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE);
+ eapSimConfig.enterpriseConfig.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY_1);
+ WifiNetworkSuggestion networkSuggestion = createWifiNetworkSuggestion(
+ new WifiConfiguration(eapSimConfig), null, false, false, true, true,
+ DEFAULT_PRIORITY_GROUP);
+ List<WifiNetworkSuggestion> networkSuggestionList = List.of(networkSuggestion);
+ assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
+ mWifiNetworkSuggestionsManager.add(networkSuggestionList, TEST_UID_1,
+ TEST_PACKAGE_1, TEST_FEATURE));
+ WifiConfiguration configuration =
+ new WifiConfiguration(eapSimConfig);
+ configuration.fromWifiNetworkSuggestion = true;
+ configuration.shared = false;
+ configuration.ephemeral = true;
+ configuration.creatorName = TEST_PACKAGE_1;
+ configuration.creatorUid = TEST_UID_1;
+ configuration.enterpriseConfig.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY_1);
+
+ Set<ExtendedWifiNetworkSuggestion> matchedSuggestions = mWifiNetworkSuggestionsManager
+ .getNetworkSuggestionsForWifiConfiguration(configuration,
+ TEST_BSSID);
+ for (ExtendedWifiNetworkSuggestion ewns : matchedSuggestions) {
+ assertNull(ewns.anonymousIdentity);
+ assertEquals(TEST_ANONYMOUS_IDENTITY_1,
+ ewns.createInternalWifiConfiguration(mWifiCarrierInfoManager)
+ .enterpriseConfig.getAnonymousIdentity());
+ }
+
+ configuration.enterpriseConfig.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY_2);
+ mWifiNetworkSuggestionsManager.setAnonymousIdentity(configuration);
+
+ matchedSuggestions = mWifiNetworkSuggestionsManager
+ .getNetworkSuggestionsForWifiConfiguration(configuration,
+ TEST_BSSID);
+ for (ExtendedWifiNetworkSuggestion ewns : matchedSuggestions) {
+ assertEquals(TEST_ANONYMOUS_IDENTITY_2, ewns.anonymousIdentity);
+ }
+
+ when(mWifiConfigManager.getConfiguredNetwork(anyString())).thenReturn(configuration);
+ when(mWifiConfigManager.addOrUpdateNetwork(any(), eq(TEST_UID_1), eq(TEST_PACKAGE_1),
+ eq(false))).thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID));
+ configuration.enterpriseConfig.setAnonymousIdentity(null);
+ mWifiNetworkSuggestionsManager.setAnonymousIdentity(configuration);
+ matchedSuggestions = mWifiNetworkSuggestionsManager
+ .getNetworkSuggestionsForWifiConfiguration(configuration,
+ TEST_BSSID);
+ for (ExtendedWifiNetworkSuggestion ewns : matchedSuggestions) {
+ assertTrue(TextUtils.isEmpty(ewns.anonymousIdentity));
+ assertEquals(TEST_ANONYMOUS_IDENTITY_1,
+ ewns.createInternalWifiConfiguration(mWifiCarrierInfoManager)
+ .enterpriseConfig.getAnonymousIdentity());
+ }
+ verify(mWifiConfigManager).addOrUpdateNetwork(any(), eq(TEST_UID_1), eq(TEST_PACKAGE_1),
+ eq(false));
+ verify(mWifiConfigManager, times(3)).saveToStore();
+ }
+
+ @Test
public void testSetUserConnectChoice() {
WifiConfigManager.OnNetworkUpdateListener listener = mNetworkListenerCaptor.getValue();
WifiConfiguration config = WifiConfigurationTestUtil.createOpenOweNetwork();
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiRoamingConfigStoreTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiRoamingConfigStoreTest.java
index bba85549bc..000cb52693 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiRoamingConfigStoreTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiRoamingConfigStoreTest.java
@@ -18,7 +18,6 @@ package com.android.server.wifi;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.validateMockitoUsage;
import static org.mockito.Mockito.verify;
@@ -30,7 +29,6 @@ import android.util.Xml;
import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
-import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.util.XmlUtil;
import org.junit.After;
@@ -78,7 +76,6 @@ public class WifiRoamingConfigStoreTest extends WifiBaseTest {
@Test
public void testRoamingModeByDeviceAdmin() {
- assumeTrue(SdkLevel.isAtLeastV());
assertTrue(mWifiRoamingConfigStore.getRoamingMode(TEST_SSID) == TEST_DEFAULT_ROAMING_MODE);
mWifiRoamingConfigStore.addRoamingMode(TEST_SSID, TEST_ROAMING_MODE, true);
assertTrue(mWifiRoamingConfigStore.getRoamingMode(TEST_SSID) == TEST_ROAMING_MODE);
@@ -95,7 +92,6 @@ public class WifiRoamingConfigStoreTest extends WifiBaseTest {
@Test
public void testRoamingModeByNonAdmin() {
- assumeTrue(SdkLevel.isAtLeastV());
assertTrue(mWifiRoamingConfigStore.getRoamingMode(TEST_SSID) == TEST_DEFAULT_ROAMING_MODE);
mWifiRoamingConfigStore.addRoamingMode(TEST_SSID, TEST_ROAMING_MODE, false);
assertTrue(mWifiRoamingConfigStore.getRoamingMode(TEST_SSID) == TEST_ROAMING_MODE);
@@ -112,7 +108,6 @@ public class WifiRoamingConfigStoreTest extends WifiBaseTest {
@Test
public void testSaveAndLoadFromStore() throws Exception {
- assumeTrue(SdkLevel.isAtLeastV());
ArgumentCaptor<WifiConfigStore.StoreData> storeDataCaptor = ArgumentCaptor.forClass(
WifiConfigStore.StoreData.class);
verify(mWifiConfigStore).registerStoreData(storeDataCaptor.capture());
@@ -140,7 +135,6 @@ public class WifiRoamingConfigStoreTest extends WifiBaseTest {
private XmlPullParser createRoamingPolicyTestXmlForParsing(String ssid, Integer roamingMode,
boolean isDeviceOwner)
throws Exception {
- assumeTrue(SdkLevel.isAtLeastV());
Map<String, Integer> roamingPolicies = new ArrayMap<>();
// Serialize
roamingPolicies.put(ssid, roamingMode);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
index 4f5aaf7e21..1459a43717 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
@@ -40,6 +40,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.MacAddress;
import android.net.Network;
@@ -61,6 +62,7 @@ import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
import com.android.modules.utils.build.SdkLevel;
+import com.android.server.wifi.proto.WifiStatsLog;
import com.android.wifi.resources.R;
import org.junit.After;
@@ -112,6 +114,8 @@ public class WifiScoreReportTest extends WifiBaseTest {
public static final boolean TEST_USER_SELECTED = true;
public static final int TEST_NETWORK_SWITCH_DIALOG_DISABLED_MS = 300_000;
private static final int TEST_UID = 435546654;
+ private static final String EXTERNAL_SCORER_PKG_NAME = "com.google.android.carrier.carrierwifi";
+ private static final String DRY_RUN_SCORER_PKG_NAME = "com.example.xxx";
FakeClock mClock;
WifiScoreReport mWifiScoreReport;
@@ -120,6 +124,7 @@ public class WifiScoreReportTest extends WifiBaseTest {
@Mock WifiNetworkAgent mNetworkAgent;
WifiThreadRunner mWifiThreadRunner;
@Mock Context mContext;
+ @Mock PackageManager mMockPackageManager;
@Mock Resources mResources;
@Mock WifiMetrics mWifiMetrics;
@Mock PrintWriter mPrintWriter;
@@ -245,6 +250,10 @@ public class WifiScoreReportTest extends WifiBaseTest {
when(mResources.getInteger(
R.integer.config_wifiNetworkSwitchDialogDisabledMsWhenMarkedUsable))
.thenReturn(TEST_NETWORK_SWITCH_DIALOG_DISABLED_MS);
+ when(mContext.getPackageManager()).thenReturn(mMockPackageManager);
+ when(mMockPackageManager.getPackagesForUid(anyInt()))
+ .thenReturn(new String[]{EXTERNAL_SCORER_PKG_NAME});
+ when(mDeviceConfigFacade.getDryRunScorerPkgName()).thenReturn(DRY_RUN_SCORER_PKG_NAME);
when(mNetwork.getNetId()).thenReturn(0);
when(mNetworkAgent.getNetwork()).thenReturn(mNetwork);
when(mNetworkAgent.getCurrentNetworkCapabilities()).thenReturn(
@@ -347,10 +356,18 @@ public class WifiScoreReportTest extends WifiBaseTest {
verifySentAnyNetworkScore();
mWifiInfo.setRssi(-77);
+ assertEquals(WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_NONE,
+ mWifiScoreReport.getAospScorerPredictionStatusForEvaluation());
+ assertEquals(WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_NONE,
+ mWifiScoreReport.getExternalScorerPredictionStatusForEvaluation());
mWifiScoreReport.calculateAndReportScore();
// called again after calculateAndReportScore()
verifySentAnyNetworkScore(times(2));
verify(mWifiMetrics).incrementWifiScoreCount(eq(TEST_IFACE_NAME), anyInt());
+ assertEquals(WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ mWifiScoreReport.getAospScorerPredictionStatusForEvaluation());
+ assertEquals(WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_NONE,
+ mWifiScoreReport.getExternalScorerPredictionStatusForEvaluation());
}
@Test
@@ -417,7 +434,7 @@ public class WifiScoreReportTest extends WifiBaseTest {
{
NetworkScore networkScore = networkScoreCaptor.getValue();
assertEquals(WifiScoreReport.LINGERING_SCORE, networkScore.getLegacyInt());
- assertFalse(networkScore.isExiting());
+ assertTrue(networkScore.isExiting());
assertFalse(networkScore.isTransportPrimary());
assertEquals(NetworkScore.KEEP_CONNECTED_NONE, networkScore.getKeepConnectedReason());
}
@@ -473,7 +490,7 @@ public class WifiScoreReportTest extends WifiBaseTest {
{
NetworkScore networkScore = networkScoreCaptor.getValue();
assertEquals(WifiScoreReport.LINGERING_SCORE, networkScore.getLegacyInt());
- assertFalse(networkScore.isExiting());
+ assertTrue(networkScore.isExiting());
assertFalse(networkScore.isTransportPrimary());
}
// upon lingering, send session end to client.
@@ -962,19 +979,28 @@ public class WifiScoreReportTest extends WifiBaseTest {
mWifiScoreReport.enableVerboseLogging(true);
mWifiInfo.setFrequency(5220);
+ assertEquals(WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_NONE,
+ mWifiScoreReport.getAospScorerPredictionStatusForEvaluation());
// Reduce RSSI value to fall below the transition score
for (int rssi = -60; rssi >= -83; rssi -= 1) {
mWifiInfo.setRssi(rssi);
mWifiScoreReport.calculateAndReportScore();
}
assertTrue(mWifiInfo.getScore() < getTransitionScore());
+ assertEquals(WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_UNUSABLE,
+ mWifiScoreReport.getAospScorerPredictionStatusForEvaluation());
// Then, set high RSSI value to exceed the transition score
mWifiInfo.setRssi(-50);
// Reset the internal timer so that no need to wait for 9 seconds
mWifiScoreReport.reset();
+ assertEquals(WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_NONE,
+ mWifiScoreReport.getAospScorerPredictionStatusForEvaluation());
+
mWifiScoreReport.calculateAndReportScore();
assertTrue(mWifiInfo.getScore() > getTransitionScore());
+ assertEquals(WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ mWifiScoreReport.getAospScorerPredictionStatusForEvaluation());
}
/**
@@ -1187,6 +1213,120 @@ public class WifiScoreReportTest extends WifiBaseTest {
}
}
+ @Test
+ public void frameworkIgnoreTriggerUpdateOfWifiUsabilityStatsForDryRunScorer() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mMockPackageManager.getPackagesForUid(anyInt()))
+ .thenReturn(new String[]{DRY_RUN_SCORER_PKG_NAME});
+ WifiConnectedNetworkScorerImpl scorerImpl = new WifiConnectedNetworkScorerImpl();
+ // Register Client for verification.
+ mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, scorerImpl, TEST_UID);
+ verify(mExternalScoreUpdateObserverProxy).registerCallback(
+ mExternalScoreUpdateObserverCbCaptor.capture());
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ //mClock.mStepMillis = 0;
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID, TEST_USER_SELECTED);
+
+ //mClock.mWallClockMillis = 5001;
+ mExternalScoreUpdateObserverCbCaptor.getValue()
+ .triggerUpdateOfWifiUsabilityStats(scorerImpl.mSessionId);
+ mLooper.dispatchAll();
+ verify(mWifiNative, never()).getWifiLinkLayerStats(TEST_IFACE_NAME);
+ verify(mWifiNative, never()).signalPoll(TEST_IFACE_NAME);
+ }
+
+ /**
+ * Verify that WifiScoreReport gets updated score when notifyScoreUpdate() is called by apps.
+ */
+ @Test
+ public void frameworkIgnoreNotifyScoreUpdateFromDryRunScorer() throws Exception {
+ assertEquals(ConnectedScore.WIFI_INITIAL_SCORE, mWifiScoreReport.getLegacyIntScore());
+ when(mMockPackageManager.getPackagesForUid(anyInt()))
+ .thenReturn(new String[]{DRY_RUN_SCORER_PKG_NAME});
+ WifiConnectedNetworkScorerImpl scorerImpl = new WifiConnectedNetworkScorerImpl();
+ mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, scorerImpl, TEST_UID);
+ verify(mExternalScoreUpdateObserverProxy).registerCallback(
+ mExternalScoreUpdateObserverCbCaptor.capture());
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID, TEST_USER_SELECTED);
+ assertEquals(TEST_SESSION_ID, scorerImpl.mSessionId);
+
+ mExternalScoreUpdateObserverCbCaptor.getValue().notifyScoreUpdate(
+ scorerImpl.mSessionId, ConnectedScore.WIFI_INITIAL_SCORE - 1);
+ mLooper.dispatchAll();
+
+ assertEquals(ConnectedScore.WIFI_INITIAL_SCORE, mWifiScoreReport.getLegacyIntScore());
+ }
+
+ @Test
+ public void frameworkIgnoreNotifyStatusUpdateFromDryRunScorer() throws Exception {
+ assertEquals(ConnectedScore.WIFI_INITIAL_SCORE, mWifiScoreReport.getLegacyIntScore());
+ when(mMockPackageManager.getPackagesForUid(anyInt()))
+ .thenReturn(new String[]{DRY_RUN_SCORER_PKG_NAME});
+ WifiConnectedNetworkScorerImpl scorerImpl = new WifiConnectedNetworkScorerImpl();
+ mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, scorerImpl, TEST_UID);
+ verify(mExternalScoreUpdateObserverProxy).registerCallback(
+ mExternalScoreUpdateObserverCbCaptor.capture());
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID, TEST_USER_SELECTED);
+ assertEquals(TEST_SESSION_ID, scorerImpl.mSessionId);
+
+ mExternalScoreUpdateObserverCbCaptor.getValue().notifyStatusUpdate(
+ scorerImpl.mSessionId, true);
+ mLooper.dispatchAll();
+ assertTrue(mWifiInfo.isUsable());
+ mExternalScoreUpdateObserverCbCaptor.getValue().notifyStatusUpdate(
+ scorerImpl.mSessionId, false);
+ mLooper.dispatchAll();
+ assertTrue(mWifiInfo.isUsable());
+ }
+
+ /**
+ * Verify that WifiScoreReport gets NUD request only once when requestNudOperation() is called
+ * by apps.
+ */
+ @Test
+ public void frameworkIgnoreRequestNudOperationForDryRunScorer() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mMockPackageManager.getPackagesForUid(anyInt()))
+ .thenReturn(new String[]{DRY_RUN_SCORER_PKG_NAME});
+ WifiConnectedNetworkScorerImpl scorerImpl = new WifiConnectedNetworkScorerImpl();
+ // Register Client for verification.
+ mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, scorerImpl, TEST_UID);
+ verify(mExternalScoreUpdateObserverProxy).registerCallback(
+ mExternalScoreUpdateObserverCbCaptor.capture());
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mClock.mStepMillis = 0;
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID, TEST_USER_SELECTED);
+
+ mClock.mWallClockMillis = 5001;
+ mExternalScoreUpdateObserverCbCaptor.getValue().requestNudOperation(scorerImpl.mSessionId);
+ mLooper.dispatchAll();
+ assertFalse(mWifiScoreReport.shouldCheckIpLayer());
+ assertEquals(0, mWifiScoreReport.getNudYes());
+ }
+
+ @Test
+ public void frameworkIgnoreBlocklistCurrentBssidForDryRunScorer() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ when(mMockPackageManager.getPackagesForUid(anyInt()))
+ .thenReturn(new String[]{DRY_RUN_SCORER_PKG_NAME});
+ WifiConnectedNetworkScorerImpl scorerImpl = new WifiConnectedNetworkScorerImpl();
+ // Register Client for verification.
+ mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, scorerImpl, TEST_UID);
+ verify(mExternalScoreUpdateObserverProxy).registerCallback(
+ mExternalScoreUpdateObserverCbCaptor.capture());
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mClock.mStepMillis = 0;
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID, TEST_USER_SELECTED);
+
+ mClock.mWallClockMillis = 5001;
+ mExternalScoreUpdateObserverCbCaptor.getValue().requestNudOperation(scorerImpl.mSessionId);
+ mLooper.dispatchAll();
+ verify(mWifiBlocklistMonitor, never())
+ .handleBssidConnectionFailure(any(), any(), anyInt(), anyInt());
+ }
+
/**
* Verify that WifiScoreReport triggers an update of WifiUsabilityStatsEntry.
*/
@@ -1721,9 +1861,13 @@ public class WifiScoreReportTest extends WifiBaseTest {
when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID, TEST_USER_SELECTED);
+ assertEquals(WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_NONE,
+ mWifiScoreReport.getExternalScorerPredictionStatusForEvaluation());
mExternalScoreUpdateObserverCbCaptor.getValue().notifyStatusUpdate(
scorerImpl.mSessionId, true);
mLooper.dispatchAll();
+ assertEquals(WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ mWifiScoreReport.getExternalScorerPredictionStatusForEvaluation());
{
ArgumentCaptor<NetworkScore> scoreCaptor = ArgumentCaptor.forClass(NetworkScore.class);
@@ -1738,6 +1882,8 @@ public class WifiScoreReportTest extends WifiBaseTest {
mExternalScoreUpdateObserverCbCaptor.getValue().notifyStatusUpdate(
scorerImpl.mSessionId, false);
mLooper.dispatchAll();
+ assertEquals(WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_UNUSABLE,
+ mWifiScoreReport.getExternalScorerPredictionStatusForEvaluation());
{
ArgumentCaptor<NetworkScore> scoreCaptor = ArgumentCaptor.forClass(NetworkScore.class);
@@ -1753,6 +1899,8 @@ public class WifiScoreReportTest extends WifiBaseTest {
mExternalScoreUpdateObserverCbCaptor.getValue().notifyStatusUpdate(
scorerImpl.mSessionId, true);
mLooper.dispatchAll();
+ assertEquals(WifiStatsLog.SCORER_PREDICTION_RESULT_REPORTED__WIFI_PREDICTED_USABILITY_STATE__WIFI_USABILITY_PREDICTED_USABLE,
+ mWifiScoreReport.getExternalScorerPredictionStatusForEvaluation());
verify(mWifiConnectivityManager).disableNetworkSwitchDialog(
TEST_NETWORK_SWITCH_DIALOG_DISABLED_MS);
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index 1e25a458c0..25cbb86de8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -103,8 +103,8 @@ import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.ignoreStubs;
+import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.isNull;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
@@ -244,6 +244,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.os.PowerProfile;
import com.android.modules.utils.ParceledListSlice;
+import com.android.modules.utils.StringParceledListSlice;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.WifiServiceImpl.LocalOnlyRequestorCallback;
import com.android.server.wifi.WifiServiceImpl.SoftApCallbackInternal;
@@ -505,7 +506,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Captor ArgumentCaptor<Intent> mIntentCaptor;
@Captor ArgumentCaptor<List> mListCaptor;
@Mock TwtManager mTwtManager;
- @Mock WifiResourceCache mWifiResourceCache;
+ @Mock WifiResourceCache mResourceCache;
@Rule
// For frameworks
@@ -528,8 +529,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper = new TestLooper();
mApplicationInfo = new ApplicationInfo();
mApplicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
- when(mResources.getInteger(
- eq(R.integer.config_wifiHardwareSoftapMaxClientCount)))
+ when(mResourceCache.getInteger(R.integer.config_wifiHardwareSoftapMaxClientCount))
.thenReturn(10);
WifiInjector.sWifiInjector = mWifiInjector;
when(mRequestInfo.getPid()).thenReturn(mPid);
@@ -566,7 +566,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mHandlerThread.getThreadHandler()).thenReturn(new Handler(mLooper.getLooper()));
when(mHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
when(mContext.getResources()).thenReturn(mResources);
- when(mContext.getResourceCache()).thenReturn(mWifiResourceCache);
+ when(mContext.getResourceCache()).thenReturn(mResourceCache);
when(mContext.getContentResolver()).thenReturn(mContentResolver);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(mPackageInfo);
@@ -861,7 +861,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
WifiDiagnostics.REPORT_REASON_USER_ACTION);
verify(mWifiDiagnostics).dump(any(), any(), any());
verify(mPasspointNetworkNominateHelper).dump(any());
- verify(mWifiResourceCache).dump(any());
+ verify(mResourceCache).dump(any());
}
@Test
@@ -1191,7 +1191,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testSetWifiEnabledDialogForThirdPartyAppsTargetingBelowQSdk() throws Exception {
- when(mResources.getBoolean(
+ when(mResourceCache.getBoolean(
R.bool.config_showConfirmationDialogForThirdPartyAppsEnablingWifi))
.thenReturn(true);
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
@@ -1357,7 +1357,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testSetWifiEnabledNoDialogForNonThirdPartyAppsTargetingBelowQSdk() {
- when(mResources.getBoolean(
+ when(mResourceCache.getBoolean(
R.bool.config_showConfirmationDialogForThirdPartyAppsEnablingWifi))
.thenReturn(true);
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
@@ -1639,13 +1639,14 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testRegisterSubsystemRestartThrowsSecurityExceptionOnMissingPermissions() {
assumeTrue(SdkLevel.isAtLeastS());
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiServiceImpl.registerSubsystemRestartCallback(null));
+
doThrow(new SecurityException()).when(mContext)
.enforceCallingOrSelfPermission(eq(ACCESS_WIFI_STATE),
eq("WifiService"));
- try {
- mWifiServiceImpl.registerSubsystemRestartCallback(mSubsystemRestartCallback);
- fail("expected SecurityException");
- } catch (SecurityException expected) { }
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.registerSubsystemRestartCallback(mSubsystemRestartCallback));
}
/**
@@ -1655,13 +1656,15 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testUnregisterSubsystemRestartThrowsSecurityExceptionOnMissingPermissions() {
assumeTrue(SdkLevel.isAtLeastS());
+ assertThrows(IllegalArgumentException.class,
+ () -> mWifiServiceImpl.unregisterSubsystemRestartCallback(null));
+
doThrow(new SecurityException()).when(mContext)
.enforceCallingOrSelfPermission(eq(ACCESS_WIFI_STATE),
eq("WifiService"));
- try {
- mWifiServiceImpl.unregisterSubsystemRestartCallback(mSubsystemRestartCallback);
- fail("expected SecurityException");
- } catch (SecurityException expected) { }
+ assertThrows(SecurityException.class,
+ () -> mWifiServiceImpl.unregisterSubsystemRestartCallback(
+ mSubsystemRestartCallback));
}
@@ -2079,7 +2082,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testSetCoexUnsafeChannelsDefaultAlgorithmDisabled() {
assumeTrue(SdkLevel.isAtLeastS());
- when(mResources.getBoolean(R.bool.config_wifiDefaultCoexAlgorithmEnabled))
+ when(mResourceCache.getBoolean(R.bool.config_wifiDefaultCoexAlgorithmEnabled))
.thenReturn(false);
List<CoexUnsafeChannel> unsafeChannels = new ArrayList<>();
unsafeChannels.addAll(Arrays.asList(new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 6),
@@ -2098,7 +2101,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testSetCoexUnsafeChannelsDefaultAlgorithmEnabled() {
assumeTrue(SdkLevel.isAtLeastS());
- when(mResources.getBoolean(R.bool.config_wifiDefaultCoexAlgorithmEnabled))
+ when(mResourceCache.getBoolean(R.bool.config_wifiDefaultCoexAlgorithmEnabled))
.thenReturn(true);
List<CoexUnsafeChannel> unsafeChannels = new ArrayList<>();
unsafeChannels.add(new CoexUnsafeChannel(WIFI_BAND_24_GHZ, 6));
@@ -2456,7 +2459,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported24gWithOverride() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(true);
assertTrue(mWifiServiceImpl.is24GHzBandSupported());
verify(mActiveModeWarden, never()).isBandSupportedForSta(anyInt());
}
@@ -2466,7 +2469,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported5gWithOverride() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(true);
assertTrue(mWifiServiceImpl.is5GHzBandSupported());
verify(mActiveModeWarden, never()).isBandSupportedForSta(anyInt());
}
@@ -2476,7 +2479,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported6gWithOverride() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(true);
assertTrue(mWifiServiceImpl.is6GHzBandSupported());
verify(mActiveModeWarden, never()).isBandSupportedForSta(anyInt());
}
@@ -2486,7 +2489,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported24gNoOverrideNoChannels() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(false);
when(mActiveModeWarden.isBandSupportedForSta(WIFI_BAND_24_GHZ)).thenReturn(false);
assertFalse(mWifiServiceImpl.is24GHzBandSupported());
verify(mActiveModeWarden).isBandSupportedForSta(WifiScanner.WIFI_BAND_24_GHZ);
@@ -2497,7 +2500,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported5gNoOverrideNoChannels() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(false);
when(mActiveModeWarden.isBandSupportedForSta(WIFI_BAND_5_GHZ)).thenReturn(false);
assertFalse(mWifiServiceImpl.is5GHzBandSupported());
verify(mActiveModeWarden).isBandSupportedForSta(WifiScanner.WIFI_BAND_5_GHZ);
@@ -2508,7 +2511,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported24gNoOverrideWithChannels() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(false);
when(mActiveModeWarden.isBandSupportedForSta(WIFI_BAND_24_GHZ)).thenReturn(true);
assertTrue(mWifiServiceImpl.is24GHzBandSupported());
verify(mActiveModeWarden).isBandSupportedForSta(WifiScanner.WIFI_BAND_24_GHZ);
@@ -2519,7 +2522,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported5gNoOverrideWithChannels() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(false);
when(mActiveModeWarden.isBandSupportedForSta(WIFI_BAND_5_GHZ)).thenReturn(true);
assertTrue(mWifiServiceImpl.is5GHzBandSupported());
verify(mActiveModeWarden).isBandSupportedForSta(WifiScanner.WIFI_BAND_5_GHZ);
@@ -2530,7 +2533,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported6gNoOverrideNoChannels() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(false);
when(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_6_GHZ)).thenReturn(
false);
assertFalse(mWifiServiceImpl.is6GHzBandSupported());
@@ -2542,7 +2545,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test
public void testIsWifiBandSupported6gNoOverrideWithChannels() throws Exception {
- when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(false);
when(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_6_GHZ)).thenReturn(
true);
assertTrue(mWifiServiceImpl.is6GHzBandSupported());
@@ -2550,56 +2553,56 @@ public class WifiServiceImplTest extends WifiBaseTest {
}
private void setup24GhzSupported() {
- when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiSoftap24ghzSupported)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftap24ghzSupported)).thenReturn(true);
}
private void setup24GhzUnsupported(boolean isOnlyUnsupportedSoftAp) {
- when(mResources.getBoolean(R.bool.config_wifiSoftap24ghzSupported)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftap24ghzSupported)).thenReturn(false);
if (!isOnlyUnsupportedSoftAp) {
- when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(false);
when(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_24_GHZ))
.thenReturn(false);
}
}
private void setup5GhzSupported() {
- when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiSoftap5ghzSupported)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftap5ghzSupported)).thenReturn(true);
}
private void setup5GhzUnsupported(boolean isOnlyUnsupportedSoftAp) {
- when(mResources.getBoolean(R.bool.config_wifiSoftap5ghzSupported)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftap5ghzSupported)).thenReturn(false);
if (!isOnlyUnsupportedSoftAp) {
- when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(false);
when(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_5_GHZ))
.thenReturn(false);
}
}
private void setup6GhzSupported() {
- when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiSoftap6ghzSupported)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftap6ghzSupported)).thenReturn(true);
}
private void setup6GhzUnsupported(boolean isOnlyUnsupportedSoftAp) {
- when(mResources.getBoolean(R.bool.config_wifiSoftap6ghzSupported)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftap6ghzSupported)).thenReturn(false);
if (!isOnlyUnsupportedSoftAp) {
- when(mResources.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifi6ghzSupport)).thenReturn(false);
when(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_6_GHZ))
.thenReturn(false);
}
}
private void setup60GhzSupported() {
- when(mResources.getBoolean(R.bool.config_wifi60ghzSupport)).thenReturn(true);
- when(mResources.getBoolean(R.bool.config_wifiSoftap60ghzSupported)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifi60ghzSupport)).thenReturn(true);
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftap60ghzSupported)).thenReturn(true);
}
private void setup60GhzUnsupported(boolean isOnlyUnsupportedSoftAp) {
- when(mResources.getBoolean(R.bool.config_wifiSoftap60ghzSupported)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftap60ghzSupported)).thenReturn(false);
if (!isOnlyUnsupportedSoftAp) {
- when(mResources.getBoolean(R.bool.config_wifi60ghzSupport)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifi60ghzSupport)).thenReturn(false);
when(mActiveModeWarden.isBandSupportedForSta(WifiScanner.WIFI_BAND_60_GHZ))
.thenReturn(false);
}
@@ -3467,7 +3470,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.startAutoDispatch();
Map<WifiNetworkSuggestion, List<ScanResult>> retrievedScanResults =
mWifiServiceImpl.getMatchingScanResults(
- matchingSuggestions, null, packageName, featureId);
+ new ParceledListSlice<>(matchingSuggestions),
+ new ParceledListSlice<>(null), packageName, featureId);
mLooper.stopAutoDispatchAndIgnoreExceptions();
ScanTestUtil.assertScanResultsEquals(scanResults,
@@ -3498,7 +3502,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.startAutoDispatch();
Map<WifiNetworkSuggestion, List<ScanResult>> retrievedScanResults =
mWifiServiceImpl.getMatchingScanResults(
- matchingSuggestions, scanResultList, packageName, featureId);
+ new ParceledListSlice<>(matchingSuggestions),
+ new ParceledListSlice<>(scanResultList), packageName, featureId);
mLooper.stopAutoDispatchAndIgnoreExceptions();
ScanTestUtil.assertScanResultsEquals(scanResults,
@@ -3532,7 +3537,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.startAutoDispatch();
Map<WifiNetworkSuggestion, List<ScanResult>> retrievedScanResults =
mWifiServiceImpl.getMatchingScanResults(
- matchingSuggestions, null, packageName, featureId);
+ new ParceledListSlice<>(matchingSuggestions), null, packageName, featureId);
mLooper.stopAutoDispatchAndIgnoreExceptions();
assertTrue(retrievedScanResults.isEmpty());
@@ -4846,7 +4851,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test(expected = SecurityException.class)
public void testGetAllMatchingPasspointProfilesForScanResultsWithoutPermissions() {
- mWifiServiceImpl.getAllMatchingPasspointProfilesForScanResults(new ArrayList<>());
+ mWifiServiceImpl.getAllMatchingPasspointProfilesForScanResults(
+ new ParceledListSlice<>(Collections.emptyList()));
}
/**
@@ -4859,7 +4865,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
mLooper.startAutoDispatch();
- mWifiServiceImpl.getAllMatchingPasspointProfilesForScanResults(createScanResultList());
+ mWifiServiceImpl.getAllMatchingPasspointProfilesForScanResults(
+ new ParceledListSlice<>(createScanResultList()));
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mPasspointManager).getAllMatchingPasspointProfilesForScanResults(any());
}
@@ -4874,7 +4881,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
mLooper.startAutoDispatch();
- mWifiServiceImpl.getAllMatchingPasspointProfilesForScanResults(new ArrayList<>());
+ mWifiServiceImpl.getAllMatchingPasspointProfilesForScanResults(
+ new ParceledListSlice<>(Collections.emptyList()));
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mPasspointManager, never()).getAllMatchingPasspointProfilesForScanResults(any());
}
@@ -4886,7 +4894,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test(expected = SecurityException.class)
public void testGetWifiConfigsForPasspointProfilesWithoutPermissions() {
- mWifiServiceImpl.getWifiConfigsForPasspointProfiles(new ArrayList<>());
+ mWifiServiceImpl.getWifiConfigsForPasspointProfiles(
+ new StringParceledListSlice(Collections.emptyList()));
}
/**
@@ -4896,7 +4905,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test(expected = SecurityException.class)
public void testGetMatchingOsuProvidersWithoutPermissions() {
- mWifiServiceImpl.getMatchingOsuProviders(new ArrayList<>());
+ mWifiServiceImpl.getMatchingOsuProviders(new ParceledListSlice<>(Collections.emptyList()));
}
/**
@@ -4909,7 +4918,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
mLooper.startAutoDispatch();
- mWifiServiceImpl.getMatchingOsuProviders(createScanResultList());
+ mWifiServiceImpl.getMatchingOsuProviders(new ParceledListSlice<>(createScanResultList()));
mLooper.stopAutoDispatch();
verify(mPasspointManager).getMatchingOsuProviders(any());
}
@@ -4922,7 +4931,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void testGetMatchingOsuProvidersWithInvalidScanResult() {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
- mWifiServiceImpl.getMatchingOsuProviders(new ArrayList<>());
+ mWifiServiceImpl.getMatchingOsuProviders(new ParceledListSlice<>(Collections.emptyList()));
mLooper.dispatchAll();
verify(mPasspointManager, never()).getMatchingOsuProviders(any());
}
@@ -4934,7 +4943,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test(expected = SecurityException.class)
public void testGetMatchingPasspointConfigsForOsuProvidersWithoutPermissions() {
- mWifiServiceImpl.getMatchingPasspointConfigsForOsuProviders(new ArrayList<>());
+ mWifiServiceImpl.getMatchingPasspointConfigsForOsuProviders(
+ new ParceledListSlice<>(Collections.emptyList()));
}
/**
@@ -5039,14 +5049,15 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mPasspointManager.getProviderConfigs(anyInt(), anyBoolean()))
.thenReturn(expectedConfigs);
mLooper.startAutoDispatch();
- assertEquals(expectedConfigs, mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE));
+ assertEquals(expectedConfigs,
+ mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE).getList());
mLooper.stopAutoDispatchAndIgnoreExceptions();
reset(mPasspointManager);
when(mPasspointManager.getProviderConfigs(anyInt(), anyBoolean()))
.thenReturn(new ArrayList<PasspointConfiguration>());
mLooper.startAutoDispatch();
- assertTrue(mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE).isEmpty());
+ assertTrue(mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE).getList().isEmpty());
mLooper.stopAutoDispatchAndIgnoreExceptions();
}
@@ -5099,7 +5110,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
private void testRestoreNetworkConfiguration(int configNum, int batchNum,
boolean allowOverride) {
List<WifiConfiguration> configurations = new ArrayList<>();
- when(mResources.getInteger(
+ when(mResourceCache.getInteger(
eq(R.integer.config_wifiConfigurationRestoreNetworksBatchNum)))
.thenReturn(batchNum);
WifiConfiguration config = new WifiConfiguration();
@@ -6846,6 +6857,31 @@ public class WifiServiceImplTest extends WifiBaseTest {
}
/**
+ * Verify that add or update networks is allowed for apps targeting below Q SDK.
+ */
+ @Test
+ public void testAddOrUpdateNetworkWithBssidAllowListIsNotAllowedForAppsNotPrivileged()
+ throws Exception {
+ doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
+ .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
+ when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), any(), eq(false))).thenReturn(
+ new NetworkUpdateResult(0));
+ when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
+ eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ config.setBssidAllowlist(Collections.emptyList());
+ mLooper.startAutoDispatch();
+ assertEquals(-1,
+ mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+
+ verifyCheckChangePermission(TEST_PACKAGE_NAME);
+ verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt(), any(), eq(false));
+ verify(mWifiMetrics, never()).incrementNumAddOrUpdateNetworkCalls();
+ }
+
+ /**
* Verify that add or update networks is not allowed for apps targeting below Q SDK
* when DISALLOW_ADD_WIFI_CONFIG user restriction is set.
*/
@@ -7278,8 +7314,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
nullable(String.class))).thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
- mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
- TEST_FEATURE_ID));
+ mWifiServiceImpl.addNetworkSuggestions(mock(ParceledListSlice.class),
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID));
mLooper.stopAutoDispatchAndIgnoreExceptions();
when(mWifiNetworkSuggestionsManager.add(any(), anyInt(), anyString(),
@@ -7287,8 +7323,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE);
mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE,
- mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
- TEST_FEATURE_ID));
+ mWifiServiceImpl.addNetworkSuggestions(mock(ParceledListSlice.class),
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID));
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWifiNetworkSuggestionsManager, times(2)).add(
@@ -7311,8 +7347,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
- mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
- TEST_FEATURE_ID));
+ mWifiServiceImpl.addNetworkSuggestions(mock(ParceledListSlice.class),
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID));
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWifiNetworkSuggestionsManager).add(
@@ -7335,8 +7371,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
- mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
- TEST_FEATURE_ID));
+ mWifiServiceImpl.addNetworkSuggestions(mock(ParceledListSlice.class),
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID));
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWifiNetworkSuggestionsManager).add(
@@ -7358,8 +7394,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
- mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
- TEST_FEATURE_ID));
+ mWifiServiceImpl.addNetworkSuggestions(mock(ParceledListSlice.class),
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID));
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWifiNetworkSuggestionsManager).add(
@@ -7381,8 +7417,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
- mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
- TEST_FEATURE_ID));
+ mWifiServiceImpl.addNetworkSuggestions(mock(ParceledListSlice.class),
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID));
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWifiNetworkSuggestionsManager).add(
@@ -7403,8 +7439,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_RESTRICTED_BY_ADMIN,
- mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
- TEST_FEATURE_ID));
+ mWifiServiceImpl.addNetworkSuggestions(mock(ParceledListSlice.class),
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID));
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWifiNetworkSuggestionsManager, never()).add(any(), eq(Binder.getCallingUid()),
@@ -7421,8 +7457,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
- mWifiServiceImpl.addNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
- TEST_FEATURE_ID));
+ mWifiServiceImpl.addNetworkSuggestions(mock(ParceledListSlice.class),
+ TEST_PACKAGE_NAME, TEST_FEATURE_ID));
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWifiNetworkSuggestionsManager, never()).add(any(), eq(Binder.getCallingUid()),
@@ -7439,8 +7475,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
.thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID);
mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID,
- mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
- ACTION_REMOVE_SUGGESTION_DISCONNECT));
+ mWifiServiceImpl.removeNetworkSuggestions(mock(ParceledListSlice.class),
+ TEST_PACKAGE_NAME, ACTION_REMOVE_SUGGESTION_DISCONNECT));
mLooper.stopAutoDispatchAndIgnoreExceptions();
when(mWifiNetworkSuggestionsManager.remove(any(), anyInt(), anyString(),
@@ -7448,8 +7484,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
.thenReturn(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS);
mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
- mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
- ACTION_REMOVE_SUGGESTION_DISCONNECT));
+ mWifiServiceImpl.removeNetworkSuggestions(mock(ParceledListSlice.class),
+ TEST_PACKAGE_NAME, ACTION_REMOVE_SUGGESTION_DISCONNECT));
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWifiNetworkSuggestionsManager, times(2)).remove(any(), anyInt(),
@@ -7466,8 +7502,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL,
- mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME,
- ACTION_REMOVE_SUGGESTION_DISCONNECT));
+ mWifiServiceImpl.removeNetworkSuggestions(mock(ParceledListSlice.class),
+ TEST_PACKAGE_NAME, ACTION_REMOVE_SUGGESTION_DISCONNECT));
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWifiNetworkSuggestionsManager, never()).remove(any(), anyInt(),
@@ -7482,7 +7518,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void testRemoveNetworkSuggestionsFailureWithInvalidAction() {
mLooper.startAutoDispatch();
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_REMOVE_INVALID,
- mWifiServiceImpl.removeNetworkSuggestions(mock(List.class), TEST_PACKAGE_NAME, 0));
+ mWifiServiceImpl.removeNetworkSuggestions(mock(ParceledListSlice.class),
+ TEST_PACKAGE_NAME, 0));
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWifiNetworkSuggestionsManager, never()).remove(any(), anyInt(),
eq(TEST_PACKAGE_NAME), anyInt());
@@ -7522,7 +7559,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
List<WifiNetworkSuggestion> testList = new ArrayList<>();
when(mWifiNetworkSuggestionsManager.get(anyString(), anyInt())).thenReturn(testList);
mLooper.startAutoDispatch();
- assertEquals(testList, mWifiServiceImpl.getNetworkSuggestions(TEST_PACKAGE_NAME));
+ assertEquals(testList, mWifiServiceImpl.getNetworkSuggestions(TEST_PACKAGE_NAME).getList());
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWifiNetworkSuggestionsManager).get(eq(TEST_PACKAGE_NAME), anyInt());
@@ -7537,7 +7574,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
mWifiServiceImpl = makeWifiServiceImplWithMockRunnerWhichTimesOut();
mLooper.startAutoDispatch();
- assertTrue(mWifiServiceImpl.getNetworkSuggestions(TEST_PACKAGE_NAME).isEmpty());
+ assertTrue(mWifiServiceImpl.getNetworkSuggestions(TEST_PACKAGE_NAME).getList().isEmpty());
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWifiNetworkSuggestionsManager, never()).get(eq(TEST_PACKAGE_NAME), anyInt());
@@ -7551,7 +7588,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void testDisableEphemeralNetworkWithNetworkSettingsPerm() throws Exception {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
- mWifiServiceImpl.disableEphemeralNetwork(new String(), TEST_PACKAGE_NAME);
+ mWifiServiceImpl.disableEphemeralNetwork("", TEST_PACKAGE_NAME);
mLooper.dispatchAll();
verify(mWifiConfigManager).userTemporarilyDisabledNetwork(anyString(), anyInt());
}
@@ -7564,7 +7601,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void testDisableEphemeralNetworkWithoutNetworkSettingsPerm() throws Exception {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
- mWifiServiceImpl.disableEphemeralNetwork(new String(), TEST_PACKAGE_NAME);
+ mWifiServiceImpl.disableEphemeralNetwork("", TEST_PACKAGE_NAME);
mLooper.dispatchAll();
verify(mWifiConfigManager, never()).userTemporarilyDisabledNetwork(anyString(), anyInt());
}
@@ -8395,7 +8432,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mWifiSettingsConfigStore.get(
eq(SHOW_DIALOG_WHEN_THIRD_PARTY_APPS_ENABLE_WIFI_SET_BY_API)))
.thenReturn(false);
- when(mResources.getBoolean(
+ when(mResourceCache.getBoolean(
R.bool.config_showConfirmationDialogForThirdPartyAppsEnablingWifi))
.thenReturn(false);
assertFalse(mWifiServiceImpl.isThirdPartyAppEnablingWifiConfirmationDialogEnabled());
@@ -8528,7 +8565,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void testSetSsidsDoNotBlocklist_NoPermission() throws Exception {
// by default no permissions are given so the call should fail.
mWifiServiceImpl.setSsidsAllowlist(TEST_PACKAGE_NAME,
- Collections.EMPTY_LIST);
+ new ParceledListSlice<>(Collections.emptyList()));
}
@Test
@@ -8537,14 +8574,15 @@ public class WifiServiceImplTest extends WifiBaseTest {
// verify setting an empty list
mWifiServiceImpl.setSsidsAllowlist(TEST_PACKAGE_NAME,
- Collections.EMPTY_LIST);
+ new ParceledListSlice<>(Collections.emptyList()));
mLooper.dispatchAll();
- verify(mWifiBlocklistMonitor).setSsidsAllowlist(Collections.EMPTY_LIST);
+ verify(mWifiBlocklistMonitor).setSsidsAllowlist(Collections.emptyList());
// verify setting a list of valid SSIDs
List<WifiSsid> expectedSsids = new ArrayList<>();
expectedSsids.add(WifiSsid.fromString(TEST_SSID_WITH_QUOTES));
- mWifiServiceImpl.setSsidsAllowlist(TEST_PACKAGE_NAME, expectedSsids);
+ mWifiServiceImpl.setSsidsAllowlist(TEST_PACKAGE_NAME,
+ new ParceledListSlice<>(expectedSsids));
mLooper.dispatchAll();
verify(mWifiBlocklistMonitor).setSsidsAllowlist(expectedSsids);
}
@@ -8558,7 +8596,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
List<WifiSsid> expectedSsids = new ArrayList<>();
expectedSsids.add(WifiSsid.fromString(TEST_SSID_WITH_QUOTES));
- mWifiServiceImpl.setSsidsAllowlist(TEST_PACKAGE_NAME, expectedSsids);
+ mWifiServiceImpl.setSsidsAllowlist(TEST_PACKAGE_NAME,
+ new ParceledListSlice<>(expectedSsids));
mLooper.dispatchAll();
verify(mWifiBlocklistMonitor).setSsidsAllowlist(expectedSsids);
}
@@ -9002,7 +9041,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
*/
@Test(expected = SecurityException.class)
public void testGetWifiConfigsForMatchedNetworkSuggestionsWithoutPermissions() {
- mWifiServiceImpl.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>());
+ mWifiServiceImpl.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
+ new ParceledListSlice<>(Collections.emptyList()));
}
/**
@@ -9016,7 +9056,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
mLooper.startAutoDispatch();
mWifiServiceImpl
- .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(createScanResultList());
+ .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
+ new ParceledListSlice<>(createScanResultList()));
mLooper.stopAutoDispatch();
verify(mWifiNetworkSuggestionsManager)
.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any());
@@ -9033,7 +9074,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
mLooper.startAutoDispatch();
mWifiServiceImpl
- .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(createScanResultList());
+ .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
+ new ParceledListSlice<>(createScanResultList()));
mLooper.stopAutoDispatch();
verify(mWifiNetworkSuggestionsManager)
.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any());
@@ -9044,7 +9086,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
mWifiServiceImpl
- .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(new ArrayList<>());
+ .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
+ new ParceledListSlice<>(Collections.emptyList()));
mLooper.dispatchAll();
verify(mWifiNetworkSuggestionsManager, never())
.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(any());
@@ -9133,7 +9176,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
.thenReturn(PackageManager.PERMISSION_DENIED);
try {
mWifiServiceImpl.addCustomDhcpOptions(WifiSsid.fromString(TEST_SSID_WITH_QUOTES),
- TEST_OUI, new ArrayList<DhcpOption>());
+ TEST_OUI, new ParceledListSlice<>(Collections.emptyList()));
fail("expected SecurityException");
} catch (SecurityException expected) {
}
@@ -9166,7 +9209,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void testAddCustomDhcpOptionsAndVerify() throws Exception {
assumeTrue(SdkLevel.isAtLeastT());
mWifiServiceImpl.addCustomDhcpOptions(WifiSsid.fromString(TEST_SSID_WITH_QUOTES), TEST_OUI,
- new ArrayList<DhcpOption>());
+ new ParceledListSlice<>(Collections.emptyList()));
mLooper.dispatchAll();
verify(mWifiConfigManager).addCustomDhcpOptions(
WifiSsid.fromString(TEST_SSID_WITH_QUOTES), TEST_OUI, new ArrayList<DhcpOption>());
@@ -9437,7 +9480,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
mLooper.stopAutoDispatchAndIgnoreExceptions();
verify(mWakeupController).dump(any(), any(), any());
verify(mPasspointNetworkNominateHelper).dump(any());
- verify(mWifiResourceCache).dump(any());
+ verify(mResourceCache).dump(any());
}
/**
@@ -10726,7 +10769,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
@Test
public void testFailureCallbacksTriggeredWhenSoftApFailsBecauseNonSupportedConfiguration()
throws Exception {
- when(mResources.getBoolean(R.bool.config_wifiSoftap6ghzSupported)).thenReturn(false);
+ when(mResourceCache.getBoolean(R.bool.config_wifiSoftap6ghzSupported)).thenReturn(false);
setupForCustomLohs();
SoftApConfiguration lohsConfig = createValidSoftApConfiguration();
SoftApConfiguration customizedConfig = new SoftApConfiguration.Builder(lohsConfig)
@@ -11291,7 +11334,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
mWifiServiceImpl.notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST,
- Arrays.asList(WifiSsid.fromUtf8Text("SSID")));
+ new ParceledListSlice<>(List.of(WifiSsid.fromUtf8Text("SSID"))));
mLooper.dispatchAll();
verify(mClientModeManager).disconnect();
@@ -11319,7 +11362,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
mWifiServiceImpl.notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST,
- Arrays.asList(WifiSsid.fromUtf8Text(TEST_SSID)));
+ new ParceledListSlice<>(List.of(WifiSsid.fromUtf8Text(TEST_SSID))));
mLooper.dispatchAll();
verify(mClientModeManager).disconnect();
@@ -11344,7 +11387,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
mWifiServiceImpl.notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST,
- Arrays.asList(WifiSsid.fromUtf8Text("SSID")));
+ new ParceledListSlice<>(List.of(WifiSsid.fromUtf8Text("SSID"))));
mLooper.dispatchAll();
verify(mClientModeManager, never()).disconnect();
@@ -11373,7 +11416,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
when(mClientModeManager.getConnectionInfo()).thenReturn(wifiInfo);
mWifiServiceImpl.notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST,
- Arrays.asList(WifiSsid.fromUtf8Text(TEST_SSID)));
+ new ParceledListSlice<>(List.of(WifiSsid.fromUtf8Text("SSID"))));
mLooper.dispatchAll();
verify(mClientModeManager, never()).disconnect();
@@ -11862,13 +11905,15 @@ public class WifiServiceImplTest extends WifiBaseTest {
List<QosPolicyParams> paramsList = createDownlinkQosPolicyParamsList(5, true);
IBinder binder = mock(IBinder.class);
IListListener listener = mock(IListListener.class);
- mWifiServiceImpl.addQosPolicies(paramsList, binder, TEST_PACKAGE_NAME, listener);
+ mWifiServiceImpl.addQosPolicies(new ParceledListSlice<>(paramsList), binder,
+ TEST_PACKAGE_NAME, listener);
int expectedNumCalls = 1;
if (SdkLevel.isAtLeastV()) {
// Uplink policies are supported on SDK >= V
paramsList = createUplinkQosPolicyParamsList(5);
- mWifiServiceImpl.addQosPolicies(paramsList, binder, TEST_PACKAGE_NAME, listener);
+ mWifiServiceImpl.addQosPolicies(new ParceledListSlice<>(paramsList), binder,
+ TEST_PACKAGE_NAME, listener);
expectedNumCalls += 1;
}
@@ -11891,7 +11936,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
// Feature disabled
when(mApplicationQosPolicyRequestHandler.isFeatureEnabled()).thenReturn(false);
- mWifiServiceImpl.addQosPolicies(paramsList, binder, TEST_PACKAGE_NAME, listener);
+ mWifiServiceImpl.addQosPolicies(new ParceledListSlice<>(paramsList), binder,
+ TEST_PACKAGE_NAME, listener);
enableQosPolicyFeature();
verify(listener).onResult(mListCaptor.capture());
@@ -11902,11 +11948,14 @@ public class WifiServiceImplTest extends WifiBaseTest {
// Null argument
assertThrows(NullPointerException.class, () ->
- mWifiServiceImpl.addQosPolicies(null, binder, TEST_PACKAGE_NAME, listener));
+ mWifiServiceImpl.addQosPolicies(new ParceledListSlice<>(null), binder,
+ TEST_PACKAGE_NAME, listener));
assertThrows(NullPointerException.class, () ->
- mWifiServiceImpl.addQosPolicies(paramsList, null, TEST_PACKAGE_NAME, listener));
+ mWifiServiceImpl.addQosPolicies(new ParceledListSlice<>(paramsList), null,
+ TEST_PACKAGE_NAME, listener));
assertThrows(NullPointerException.class, () ->
- mWifiServiceImpl.addQosPolicies(paramsList, binder, TEST_PACKAGE_NAME, null));
+ mWifiServiceImpl.addQosPolicies(new ParceledListSlice<>(paramsList), binder,
+ TEST_PACKAGE_NAME, null));
// Invalid QoS policy params list
List<QosPolicyParams> emptyList = createDownlinkQosPolicyParamsList(0, true);
@@ -11914,14 +11963,14 @@ public class WifiServiceImplTest extends WifiBaseTest {
WifiManager.getMaxNumberOfPoliciesPerQosRequest() + 1, true);
List<QosPolicyParams> duplicatePolicyList = createDownlinkQosPolicyParamsList(5, false);
assertThrows(IllegalArgumentException.class, () ->
- mWifiServiceImpl.addQosPolicies(emptyList, binder, TEST_PACKAGE_NAME,
- listener));
+ mWifiServiceImpl.addQosPolicies(new ParceledListSlice<>(emptyList), binder,
+ TEST_PACKAGE_NAME, listener));
assertThrows(IllegalArgumentException.class, () ->
- mWifiServiceImpl.addQosPolicies(largeList, binder, TEST_PACKAGE_NAME,
- listener));
+ mWifiServiceImpl.addQosPolicies(new ParceledListSlice<>(largeList), binder,
+ TEST_PACKAGE_NAME, listener));
assertThrows(IllegalArgumentException.class, () ->
- mWifiServiceImpl.addQosPolicies(
- duplicatePolicyList, binder, TEST_PACKAGE_NAME, listener));
+ mWifiServiceImpl.addQosPolicies(new ParceledListSlice<>(duplicatePolicyList),
+ binder, TEST_PACKAGE_NAME, listener));
if (SdkLevel.isAtLeastV()) {
List<QosPolicyParams> mixedDirectionList = createDownlinkQosPolicyParamsList(1, true);
@@ -11932,8 +11981,8 @@ public class WifiServiceImplTest extends WifiBaseTest {
.setQosCharacteristics(mockQosCharacteristics)
.build());
assertThrows(IllegalArgumentException.class, () ->
- mWifiServiceImpl.addQosPolicies(
- mixedDirectionList, binder, TEST_PACKAGE_NAME, listener));
+ mWifiServiceImpl.addQosPolicies(new ParceledListSlice<>(mixedDirectionList),
+ binder, TEST_PACKAGE_NAME, listener));
}
}
@@ -12829,4 +12878,32 @@ public class WifiServiceImplTest extends WifiBaseTest {
// Only WEP disconnect
verify(cmmWep).disconnect();
}
+
+ @Test
+ public void testGetWifiConfigForMatchedNetworkSuggestionsSharedWithUserForMultiTypeConfigs() {
+ long featureFlags = WifiManager.WIFI_FEATURE_WPA3_SAE | WifiManager.WIFI_FEATURE_OWE;
+ List<WifiConfiguration> testConfigs = setupMultiTypeConfigs(featureFlags, true, true);
+ when(mWifiNetworkSuggestionsManager
+ .getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(anyList()))
+ .thenReturn(testConfigs);
+ when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
+ anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+ ScanResult[] scanResults =
+ ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0]
+ .getResults();
+ List<ScanResult> scanResultList =
+ new ArrayList<>(Arrays.asList(scanResults));
+
+ mLooper.startAutoDispatch();
+ ParceledListSlice<WifiConfiguration> configs =
+ mWifiServiceImpl.getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(
+ new ParceledListSlice<>(scanResultList));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+
+ List<WifiConfiguration> expectedConfigs = generateExpectedConfigs(
+ testConfigs, true, true);
+ WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+ expectedConfigs, configs.getList());
+ }
+
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java
index 9252aa8f41..a63c4d47b2 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiShellCommandTest.java
@@ -23,6 +23,9 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.wifi.WifiManager.ACTION_REMOVE_SUGGESTION_DISCONNECT;
import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
+import static android.net.wifi.WifiManager.ROAMING_MODE_NONE;
+import static android.net.wifi.WifiManager.ROAMING_MODE_NORMAL;
+import static android.net.wifi.WifiManager.ROAMING_MODE_AGGRESSIVE;
import static com.android.server.wifi.WifiShellCommand.SHELL_PACKAGE_NAME;
@@ -57,6 +60,7 @@ import android.net.wifi.WifiInfo;
import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiScanner;
+import android.net.wifi.WifiSsid;
import android.os.Binder;
import android.os.Handler;
import android.os.PatternMatcher;
@@ -65,6 +69,7 @@ import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
+import com.android.modules.utils.ParceledListSlice;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.coex.CoexManager;
@@ -78,6 +83,7 @@ import org.mockito.MockitoAnnotations;
import java.io.FileDescriptor;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
/**
* Unit tests for {@link com.android.server.wifi.WifiShellCommand}.
@@ -190,7 +196,7 @@ public class WifiShellCommandTest extends WifiBaseTest {
mWifiShellCommand.exec(
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"set-poll-rssi-interval-msecs", "5"});
- verify(mWifiGlobals, never()).setPollRssiIntervalMillis(anyInt());
+ verify(mPrimaryClientModeManager, never()).setLinkLayerStatsPollingInterval(anyInt());
assertFalse(mWifiShellCommand.getErrPrintWriter().toString().isEmpty());
BinderUtil.setUid(Process.ROOT_UID);
@@ -198,13 +204,38 @@ public class WifiShellCommandTest extends WifiBaseTest {
mWifiShellCommand.exec(
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"set-poll-rssi-interval-msecs", "5"});
- verify(mWifiGlobals).setPollRssiIntervalMillis(5);
+ verify(mPrimaryClientModeManager).setLinkLayerStatsPollingInterval(5);
// invalid arg
mWifiShellCommand.exec(
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"set-poll-rssi-interval-msecs", "0"});
verifyNoMoreInteractions(mWifiGlobals);
+ verifyNoMoreInteractions(mPrimaryClientModeManager);
+ assertFalse(mWifiShellCommand.getErrPrintWriter().toString().isEmpty());
+
+ mWifiShellCommand.exec(
+ new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
+ new String[]{"set-poll-rssi-interval-msecs", "4", "8"});
+ verify(mWifiGlobals).setPollRssiShortIntervalMillis(4);
+ verify(mWifiGlobals).setPollRssiLongIntervalMillis(8);
+ verify(mWifiGlobals).setPollRssiIntervalMillis(4);
+ verify(mPrimaryClientModeManager).setLinkLayerStatsPollingInterval(0);
+
+ // invalid arg
+ mWifiShellCommand.exec(
+ new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
+ new String[]{"set-poll-rssi-interval-msecs", "8", "4"});
+ verifyNoMoreInteractions(mWifiGlobals);
+ verifyNoMoreInteractions(mPrimaryClientModeManager);
+ assertFalse(mWifiShellCommand.getErrPrintWriter().toString().isEmpty());
+
+ // invalid arg
+ mWifiShellCommand.exec(
+ new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
+ new String[]{"set-poll-rssi-interval-msecs", "4", "8", "12"});
+ verifyNoMoreInteractions(mWifiGlobals);
+ verifyNoMoreInteractions(mPrimaryClientModeManager);
assertFalse(mWifiShellCommand.getErrPrintWriter().toString().isEmpty());
}
@@ -604,9 +635,9 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"add-suggestion", "ssid1234", "open", "-u"});
verify(mWifiService).addNetworkSuggestions(argThat(sL -> {
- return (sL.size() == 1)
- && (sL.get(0).getSsid().equals("ssid1234"))
- && (sL.get(0).isUntrusted());
+ return (sL.getList().size() == 1)
+ && (sL.getList().get(0).getSsid().equals("ssid1234"))
+ && (sL.getList().get(0).isUntrusted());
}), eq(SHELL_PACKAGE_NAME), any());
verify(mConnectivityManager).requestNetwork(argThat(nR -> {
return (nR.hasTransport(TRANSPORT_WIFI))
@@ -614,18 +645,18 @@ public class WifiShellCommandTest extends WifiBaseTest {
}), any(ConnectivityManager.NetworkCallback.class));
when(mWifiService.getNetworkSuggestions(any()))
- .thenReturn(Arrays.asList(
+ .thenReturn(new ParceledListSlice<>(List.of(
new WifiNetworkSuggestion.Builder()
.setSsid("ssid1234")
.setUntrusted(true)
- .build()));
+ .build())));
mWifiShellCommand.exec(
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"remove-suggestion", "ssid1234"});
verify(mWifiService).removeNetworkSuggestions(argThat(sL -> {
- return (sL.size() == 1)
- && (sL.get(0).getSsid().equals("ssid1234"))
- && (sL.get(0).isUntrusted());
+ return (sL.getList().size() == 1)
+ && (sL.getList().get(0).getSsid().equals("ssid1234"))
+ && (sL.getList().get(0).isUntrusted());
}), eq(SHELL_PACKAGE_NAME), eq(ACTION_REMOVE_SUGGESTION_DISCONNECT));
verify(mConnectivityManager).unregisterNetworkCallback(
any(ConnectivityManager.NetworkCallback.class));
@@ -639,9 +670,9 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"add-suggestion", "ssid1234", "open", "-o"});
verify(mWifiService).addNetworkSuggestions(argThat(sL -> {
- return (sL.size() == 1)
- && (sL.get(0).getSsid().equals("ssid1234"))
- && (sL.get(0).isOemPaid());
+ return (sL.getList().size() == 1)
+ && (sL.getList().get(0).getSsid().equals("ssid1234"))
+ && (sL.getList().get(0).isOemPaid());
}), eq(SHELL_PACKAGE_NAME), any());
verify(mConnectivityManager).requestNetwork(argThat(nR -> {
return (nR.hasTransport(TRANSPORT_WIFI))
@@ -649,18 +680,18 @@ public class WifiShellCommandTest extends WifiBaseTest {
}), any(ConnectivityManager.NetworkCallback.class));
when(mWifiService.getNetworkSuggestions(any()))
- .thenReturn(Arrays.asList(
+ .thenReturn(new ParceledListSlice<>(List.of(
new WifiNetworkSuggestion.Builder()
.setSsid("ssid1234")
.setOemPaid(true)
- .build()));
+ .build())));
mWifiShellCommand.exec(
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"remove-suggestion", "ssid1234"});
verify(mWifiService).removeNetworkSuggestions(argThat(sL -> {
- return (sL.size() == 1)
- && (sL.get(0).getSsid().equals("ssid1234"))
- && (sL.get(0).isOemPaid());
+ return (sL.getList().size() == 1)
+ && (sL.getList().get(0).getSsid().equals("ssid1234"))
+ && (sL.getList().get(0).isOemPaid());
}), eq(SHELL_PACKAGE_NAME), eq(ACTION_REMOVE_SUGGESTION_DISCONNECT));
verify(mConnectivityManager).unregisterNetworkCallback(
any(ConnectivityManager.NetworkCallback.class));
@@ -674,9 +705,9 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"add-suggestion", "ssid1234", "open", "-p"});
verify(mWifiService).addNetworkSuggestions(argThat(sL -> {
- return (sL.size() == 1)
- && (sL.get(0).getSsid().equals("ssid1234"))
- && (sL.get(0).isOemPrivate());
+ return (sL.getList().size() == 1)
+ && (sL.getList().get(0).getSsid().equals("ssid1234"))
+ && (sL.getList().get(0).isOemPrivate());
}), eq(SHELL_PACKAGE_NAME), any());
verify(mConnectivityManager).requestNetwork(argThat(nR -> {
return (nR.hasTransport(TRANSPORT_WIFI))
@@ -684,18 +715,18 @@ public class WifiShellCommandTest extends WifiBaseTest {
}), any(ConnectivityManager.NetworkCallback.class));
when(mWifiService.getNetworkSuggestions(any()))
- .thenReturn(Arrays.asList(
+ .thenReturn(new ParceledListSlice<>(List.of(
new WifiNetworkSuggestion.Builder()
.setSsid("ssid1234")
.setOemPrivate(true)
- .build()));
+ .build())));
mWifiShellCommand.exec(
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"remove-suggestion", "ssid1234"});
verify(mWifiService).removeNetworkSuggestions(argThat(sL -> {
- return (sL.size() == 1)
- && (sL.get(0).getSsid().equals("ssid1234"))
- && (sL.get(0).isOemPrivate());
+ return (sL.getList().size() == 1)
+ && (sL.getList().get(0).getSsid().equals("ssid1234"))
+ && (sL.getList().get(0).isOemPrivate());
}), eq(SHELL_PACKAGE_NAME), eq(ACTION_REMOVE_SUGGESTION_DISCONNECT));
verify(mConnectivityManager).unregisterNetworkCallback(
any(ConnectivityManager.NetworkCallback.class));
@@ -708,9 +739,9 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"add-suggestion", "ssid1234", "open"});
verify(mWifiService).addNetworkSuggestions(argThat(sL -> {
- return (sL.size() == 1)
- && (sL.get(0).getSsid().equals("ssid1234"))
- && (sL.get(0).getWifiConfiguration().macRandomizationSetting
+ return (sL.getList().size() == 1)
+ && (sL.getList().get(0).getSsid().equals("ssid1234"))
+ && (sL.getList().get(0).getWifiConfiguration().macRandomizationSetting
== WifiConfiguration.RANDOMIZATION_PERSISTENT);
}), eq(SHELL_PACKAGE_NAME), any());
@@ -720,9 +751,9 @@ public class WifiShellCommandTest extends WifiBaseTest {
new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
new String[]{"add-suggestion", "ssid1234", "open", "-r"});
verify(mWifiService).addNetworkSuggestions(argThat(sL -> {
- return (sL.size() == 1)
- && (sL.get(0).getSsid().equals("ssid1234"))
- && (sL.get(0).getWifiConfiguration().macRandomizationSetting
+ return (sL.getList().size() == 1)
+ && (sL.getList().get(0).getSsid().equals("ssid1234"))
+ && (sL.getList().get(0).getWifiConfiguration().macRandomizationSetting
== WifiConfiguration.RANDOMIZATION_NON_PERSISTENT);
}), eq(SHELL_PACKAGE_NAME), any());
}
@@ -1042,4 +1073,51 @@ public class WifiShellCommandTest extends WifiBaseTest {
anyInt(), eq(WifiAvailableChannel.FILTER_REGULATORY), eq(SHELL_PACKAGE_NAME),
any());
}
+
+ @Test
+ public void testSetSsidRoamingMode() {
+ BinderUtil.setUid(Process.ROOT_UID);
+ final String testSsid = "testssid";
+ final String hexSsid = "68656c6c6f20776f726c64";
+ ArgumentCaptor<WifiSsid> wifiSsidCaptor = ArgumentCaptor.forClass(
+ WifiSsid.class);
+
+ // Unsupported mode
+ mWifiShellCommand.exec(
+ new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
+ new String[]{"set-ssid-roaming-mode", testSsid, "abcd"});
+ verify(mWifiService, never()).setPerSsidRoamingMode(any(), anyInt(), anyString());
+
+ // None mode
+ mWifiShellCommand.exec(
+ new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
+ new String[]{"set-ssid-roaming-mode", testSsid, "none"});
+ verify(mWifiService).setPerSsidRoamingMode(
+ wifiSsidCaptor.capture(), eq(ROAMING_MODE_NONE), eq(SHELL_PACKAGE_NAME));
+ assertEquals("\"" + testSsid + "\"", wifiSsidCaptor.getValue().toString());
+
+ // Normal mode
+ mWifiShellCommand.exec(
+ new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
+ new String[]{"set-ssid-roaming-mode", testSsid, "normal"});
+ verify(mWifiService).setPerSsidRoamingMode(
+ wifiSsidCaptor.capture(), eq(ROAMING_MODE_NORMAL), eq(SHELL_PACKAGE_NAME));
+ assertEquals("\"" + testSsid + "\"", wifiSsidCaptor.getValue().toString());
+
+ // Aggressive mode
+ mWifiShellCommand.exec(
+ new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
+ new String[]{"set-ssid-roaming-mode", testSsid, "aggressive"});
+ verify(mWifiService).setPerSsidRoamingMode(
+ wifiSsidCaptor.capture(), eq(ROAMING_MODE_AGGRESSIVE), eq(SHELL_PACKAGE_NAME));
+ assertEquals("\"" + testSsid + "\"", wifiSsidCaptor.getValue().toString());
+
+ // Test with "hello world" SSID encoded in hexadecimal UTF-8
+ mWifiShellCommand.exec(
+ new Binder(), new FileDescriptor(), new FileDescriptor(), new FileDescriptor(),
+ new String[]{"set-ssid-roaming-mode", hexSsid, "aggressive", "-x"});
+ verify(mWifiService, times(2)).setPerSsidRoamingMode(
+ wifiSsidCaptor.capture(), eq(ROAMING_MODE_AGGRESSIVE), eq(SHELL_PACKAGE_NAME));
+ assertEquals("\"hello world\"", wifiSsidCaptor.getValue().toString());
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
index c958fc1a3a..0862fd7245 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java
@@ -18,6 +18,7 @@ package com.android.server.wifi;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_AP;
import static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_STA;
+import static com.android.server.wifi.util.GeneralUtil.longToBitset;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -86,6 +87,7 @@ import org.mockito.stubbing.Answer;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.Collections;
import java.util.List;
import java.util.Random;
@@ -553,10 +555,10 @@ public class WifiVendorHalTest extends WifiBaseTest {
*/
@Test
public void testGetSupportedFeatures() throws Exception {
- long staIfaceCaps =
- WifiManager.WIFI_FEATURE_SCANNER | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS;
- long chipCaps = WifiManager.WIFI_FEATURE_TX_POWER_LIMIT;
- WifiChip.Response<Long> chipCapsResponse = new WifiChip.Response<>(chipCaps);
+ BitSet staIfaceCaps = longToBitset(
+ WifiManager.WIFI_FEATURE_SCANNER | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS);
+ BitSet chipCaps = longToBitset(WifiManager.WIFI_FEATURE_TX_POWER_LIMIT);
+ WifiChip.Response<BitSet> chipCapsResponse = new WifiChip.Response<>(chipCaps);
chipCapsResponse.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS);
when(mWifiStaIface.getCapabilities()).thenReturn(staIfaceCaps);
when(mWifiChip.getCapabilitiesAfterIfacesExist()).thenReturn(chipCapsResponse);
@@ -568,7 +570,7 @@ public class WifiVendorHalTest extends WifiBaseTest {
when(mWifiGlobals.isWpa3SaeH2eSupported()).thenReturn(true);
when(mHalDeviceManager.is24g5gDbsSupported(any())).thenReturn(true);
- long expectedFeatureSet = (
+ BitSet expectedFeatureSet = longToBitset(
WifiManager.WIFI_FEATURE_SCANNER
| WifiManager.WIFI_FEATURE_LINK_LAYER_STATS
| WifiManager.WIFI_FEATURE_TX_POWER_LIMIT
@@ -578,7 +580,8 @@ public class WifiVendorHalTest extends WifiBaseTest {
| WifiManager.WIFI_FEATURE_DUAL_BAND_SIMULTANEOUS
);
assertTrue(mWifiVendorHal.startVendorHalSta(mConcreteClientModeManager));
- assertEquals(expectedFeatureSet, mWifiVendorHal.getSupportedFeatureSet(TEST_IFACE_NAME));
+ assertTrue(expectedFeatureSet.equals(
+ mWifiVendorHal.getSupportedFeatureSet(TEST_IFACE_NAME)));
}
/**
@@ -603,12 +606,13 @@ public class WifiVendorHalTest extends WifiBaseTest {
when(mPackageManager.hasSystemFeature(eq(PackageManager.FEATURE_WIFI_AWARE)))
.thenReturn(true);
- long expectedFeatureSet = (
+ BitSet expectedFeatureSet = longToBitset(
WifiManager.WIFI_FEATURE_INFRA
| WifiManager.WIFI_FEATURE_P2P
| WifiManager.WIFI_FEATURE_AWARE
);
- assertEquals(expectedFeatureSet, mWifiVendorHal.getSupportedFeatureSet(TEST_IFACE_NAME));
+ assertTrue(expectedFeatureSet.equals(
+ mWifiVendorHal.getSupportedFeatureSet(TEST_IFACE_NAME)));
}
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/aware/PairingConfigManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/aware/PairingConfigManagerTest.java
new file mode 100644
index 0000000000..95656604c7
--- /dev/null
+++ b/service/tests/wifitests/src/com/android/server/wifi/aware/PairingConfigManagerTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi.aware;
+
+import static com.android.server.wifi.aware.PairingConfigManager.NIR;
+import static com.android.server.wifi.aware.PairingConfigManager.TAG_SIZE_IN_BYTE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.net.MacAddress;
+import android.net.wifi.aware.Characteristics;
+
+import com.android.server.wifi.WifiBaseTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Unit test harness for PairingConfigManager.
+ */
+public class PairingConfigManagerTest extends WifiBaseTest {
+ private PairingConfigManager mPairingConfigManager;
+ private final String mPackageName = "some.package";
+ private final String mPackageName1 = "another.package";
+ private final String mAlias = "alias";
+ private final byte[] mNouce = "nounce".getBytes();
+ private final String mMac = "fa:45:23:23:12:12";
+
+ @Before
+ public void setup() {
+ mPairingConfigManager = new PairingConfigManager();
+ }
+
+ /**
+ * Test get new NIK for the App
+ */
+ @Test
+ public void testCallingPackageNik() {
+ byte[] nik = mPairingConfigManager.getNikForCallingPackage(mPackageName);
+ assertFalse(Arrays.equals(nik,
+ mPairingConfigManager.getNikForCallingPackage(mPackageName1)));
+ mPairingConfigManager.removePackage(mPackageName);
+ assertFalse(Arrays.equals(nik,
+ mPairingConfigManager.getNikForCallingPackage(mPackageName)));
+ }
+
+ /**
+ * Test add paired device and match
+ */
+ @Test
+ public void testAddPairedPeerDevice() {
+ byte[] localNik = mPairingConfigManager.getNikForCallingPackage(mPackageName);
+ byte[] peerNik = mPairingConfigManager.getNikForCallingPackage(mPackageName1);
+ PairingConfigManager.PairingSecurityAssociationInfo pairingInfo =
+ new PairingConfigManager.PairingSecurityAssociationInfo(peerNik, localNik,
+ new byte[16], WifiAwareStateManager.NAN_PAIRING_AKM_PASN,
+ Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128);
+ mPairingConfigManager.addPairedDeviceSecurityAssociation(mPackageName, mAlias, pairingInfo);
+ byte[] mac = MacAddress.fromString(mMac).toByteArray();
+ byte[] peerTag = generateTag(peerNik, mNouce, mac);
+ String peerAlias = mPairingConfigManager.getPairedDeviceAlias(mPackageName, mNouce, peerTag,
+ mac);
+ assertEquals(mAlias, peerAlias);
+ assertEquals(pairingInfo, mPairingConfigManager.getSecurityInfoPairedDevice(peerAlias));
+ mPairingConfigManager.removePairedDevice(mPackageName, mAlias);
+ assertNull(mPairingConfigManager.getPairedDeviceAlias(mPackageName, mNouce, peerTag,
+ mac));
+ }
+
+ /**
+ * Test remove App will clear the paired device
+ */
+ @Test
+ public void testRemovePackages() {
+ byte[] localNik = mPairingConfigManager.getNikForCallingPackage(mPackageName);
+ byte[] peerNik = mPairingConfigManager.getNikForCallingPackage(mPackageName1);
+ PairingConfigManager.PairingSecurityAssociationInfo pairingInfo =
+ new PairingConfigManager.PairingSecurityAssociationInfo(peerNik, localNik,
+ new byte[16], WifiAwareStateManager.NAN_PAIRING_AKM_PASN,
+ Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128);
+ mPairingConfigManager.addPairedDeviceSecurityAssociation(mPackageName, mAlias, pairingInfo);
+ List<String> allAlias = mPairingConfigManager.getAllPairedDevices(mPackageName);
+ assertEquals(1, allAlias.size());
+ assertEquals(mAlias, allAlias.get(0));
+ mPairingConfigManager.removePackage(mPackageName1);
+ allAlias = mPairingConfigManager.getAllPairedDevices(mPackageName);
+ assertEquals(1, allAlias.size());
+ assertEquals(mAlias, allAlias.get(0));
+ mPairingConfigManager.removePackage(mPackageName);
+ allAlias = mPairingConfigManager.getAllPairedDevices(mPackageName);
+ assertTrue(allAlias.isEmpty());
+ }
+
+ private byte[] generateTag(byte[] nik, byte[] nonce, byte[] mac) {
+ SecretKeySpec spec = new SecretKeySpec(nik, "HmacSHA256");
+ try {
+ Mac hash = Mac.getInstance("HmacSHA256");
+ hash.init(spec);
+ hash.update(NIR);
+ hash.update(mac);
+ hash.update(nonce);
+ return Arrays.copyOf(hash.doFinal(), TAG_SIZE_IN_BYTE);
+ } catch (NoSuchAlgorithmException | InvalidKeyException | IllegalStateException e) {
+ return null;
+ }
+ }
+}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
index 51537dccda..ee53e22771 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
@@ -761,7 +761,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
IWifiAwareEventCallback mockCallback1 = mock(IWifiAwareEventCallback.class);
IWifiAwareEventCallback mockCallback2 = mock(IWifiAwareEventCallback.class);
ArgumentCaptor<Short> transactionIdCapture = ArgumentCaptor.forClass(Short.class);
- InOrder inOrder = inOrder(mockCallback1, mockCallback2, mMockNative);
+ InOrder inOrder = inOrder(mockCallback1, mockCallback2, mMockNative, mMockNativeManager);
mDut.enableUsage();
mMockLooper.dispatchAll();
@@ -827,7 +827,8 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
validateInternalClientInfoCleanedUp(clientId1);
validateInternalClientInfoCleanedUp(clientId2);
-
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNativeManager).releaseAware();
verifyNoMoreInteractions(mockCallback1, mockCallback2, mMockNative);
}
@@ -3826,95 +3827,6 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
}
/**
- * Validate aware enable/disable during doze transitions.
- */
- @Test
- public void testEnableDisableOnDoze() throws Exception {
- final int clientId = 188;
- final int uid = 1000;
- final int pid = 2000;
- final String callingPackage = "com.google.somePackage";
- final String callingFeature = "com.google.someFeature";
-
- setSettableParam(WifiAwareStateManager.PARAM_ON_IDLE_DISABLE_AWARE, Integer.toString(1),
- true);
-
- ConfigRequest configRequest = new ConfigRequest.Builder().build();
-
- ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
- IWifiAwareEventCallback mockCallback = mock(IWifiAwareEventCallback.class);
- InOrder inOrder = inOrder(mMockContext, mMockNativeManager, mMockNative, mockCallback);
- mMockLooper.dispatchAll();
- inOrder.verify(mMockNativeManager).start(any(Handler.class));
- inOrder.verify(mMockNativeManager).tryToGetAware(new WorkSource(Process.WIFI_UID));
- inOrder.verify(mMockNativeManager).releaseAware();
-
- mDut.enableUsage();
- mMockLooper.dispatchAll();
-
- // (1) connect
- mDut.connect(clientId, uid, pid, callingPackage, callingFeature, mockCallback,
- configRequest, false, mExtras, false);
- mMockLooper.dispatchAll();
- inOrder.verify(mMockNativeManager).tryToGetAware(new WorkSource(uid, callingPackage));
- inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
- eq(configRequest), eq(false), eq(true), eq(true), eq(false), eq(false), eq(false),
- anyInt(), anyInt());
- mDut.onConfigSuccessResponse(transactionId.getValue());
- mMockLooper.dispatchAll();
- assertTrue(mDut.isDeviceAttached());
- inOrder.verify(mockCallback).onConnectSuccess(clientId);
-
- // (2) set the App to isIgnoringBatteryOptimizations to true and power state change: DOZE
- when(mMockPowerManager.isIgnoringBatteryOptimizations(callingPackage)).thenReturn(true);
- simulatePowerStateChangeDoze(true);
- mMockLooper.dispatchAll();
- assertTrue(mDut.isUsageEnabled());
- inOrder.verify(mockCallback, never()).onAttachTerminate();
-
- // (3) set the App to isIgnoringBatteryOptimizations to false and power state change: DOZE
- when(mMockPowerManager.isIgnoringBatteryOptimizations(callingPackage)).thenReturn(false);
- simulatePowerStateChangeDoze(true);
- mMockLooper.dispatchAll();
- collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
- inOrder.verify(mockCallback).onAttachTerminate();
- validateCorrectAwareStatusChangeBroadcast(inOrder);
- inOrder.verify(mMockNative).disable(transactionId.capture());
- assertFalse(mDut.isDeviceAttached());
- mDut.onDisableResponse(transactionId.getValue(), NanStatusCode.SUCCESS);
- mMockLooper.dispatchAll();
- inOrder.verify(mMockNativeManager).releaseAware();
-
- // (4) power state change: SCREEN ON (but DOZE still on - fakish but expect no changes)
- simulatePowerStateChangeInteractive(false);
- mMockLooper.dispatchAll();
-
- // and same for other gating changes -> no changes
- simulateLocationModeChange(false);
- simulateWifiStateChange(false);
- mMockLooper.dispatchAll();
-
- // and same for other gating changes -> no changes
- simulateD2dAllowedChange(false);
- mMockLooper.dispatchAll();
- simulateD2dAllowedChange(true);
- mMockLooper.dispatchAll();
-
- // and same for other gating changes -> no changes
- simulateLocationModeChange(true);
- simulateWifiStateChange(true);
- mMockLooper.dispatchAll();
-
- // (5) power state change: DOZE OFF
- simulatePowerStateChangeDoze(false);
- mMockLooper.dispatchAll();
- collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
- validateCorrectAwareStatusChangeBroadcast(inOrder);
-
- verifyNoMoreInteractions(mMockNativeManager, mMockNative, mockCallback);
- }
-
- /**
* Validate aware enable/disable during LOCATION MODE transitions on pre-T, Aware should be
* disabled.
*/
@@ -4182,6 +4094,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mockCallback).onAttachTerminate();
collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
assertFalse(mDut.isDeviceAttached());
+ mMockLooper.dispatchAll();
validateCorrectAwareStatusChangeBroadcast(inOrder);
// (3) try reconnect client
@@ -4679,7 +4592,8 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final String alias = "alias";
AwarePairingConfig pairingConfig = new AwarePairingConfig(true, true, true,
- AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN);
+ AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN,
+ WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128);
ConfigRequest configRequest = new ConfigRequest.Builder().build();
PublishConfig publishConfig = new PublishConfig.Builder()
.setPairingConfig(pairingConfig).build();
@@ -4813,7 +4727,8 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final String alias = "alias";
AwarePairingConfig pairingConfig = new AwarePairingConfig(true, true, true,
- AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN);
+ AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN,
+ WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128);
ConfigRequest configRequest = new ConfigRequest.Builder().build();
PublishConfig publishConfig = new PublishConfig.Builder()
.setPairingConfig(pairingConfig).build();
@@ -4941,7 +4856,8 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final String alias = "alias";
AwarePairingConfig pairingConfig = new AwarePairingConfig(true, true, true,
- AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN);
+ AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN,
+ WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128);
ConfigRequest configRequest = new ConfigRequest.Builder().build();
SubscribeConfig subscribeConfig = new SubscribeConfig.Builder()
@@ -5072,7 +4988,8 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final String alias = "alias";
AwarePairingConfig pairingConfig = new AwarePairingConfig(true, true, true,
- AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN);
+ AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN,
+ WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128);
ConfigRequest configRequest = new ConfigRequest.Builder().build();
SubscribeConfig subscribeConfig = new SubscribeConfig.Builder()
@@ -5196,7 +5113,8 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
final String alias = "alias";
AwarePairingConfig pairingConfig = new AwarePairingConfig(true, true, true,
- AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN);
+ AwarePairingConfig.PAIRING_BOOTSTRAPPING_QR_SCAN,
+ WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128);
ConfigRequest configRequest = new ConfigRequest.Builder().build();
SubscribeConfig subscribeConfig = new SubscribeConfig.Builder()
@@ -5880,7 +5798,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
IWifiAwareEventCallback mockCallback1 = mock(IWifiAwareEventCallback.class);
IWifiAwareEventCallback mockCallback2 = mock(IWifiAwareEventCallback.class);
ArgumentCaptor<Short> transactionIdCapture = ArgumentCaptor.forClass(Short.class);
- InOrder inOrder = inOrder(mockCallback1, mockCallback2, mMockNative);
+ InOrder inOrder = inOrder(mockCallback1, mockCallback2, mMockNative, mMockNativeManager);
mDut.enableUsage();
mMockLooper.dispatchAll();
@@ -5919,7 +5837,8 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
validateInternalClientInfoCleanedUp(clientId1);
validateInternalClientInfoCleanedUp(clientId2);
-
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNativeManager).releaseAware();
verifyNoMoreInteractions(mockCallback1, mockCallback2, mMockNative);
}
@@ -5948,7 +5867,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
IWifiAwareEventCallback mockCallback1 = mock(IWifiAwareEventCallback.class);
IWifiAwareEventCallback mockCallback2 = mock(IWifiAwareEventCallback.class);
ArgumentCaptor<Short> transactionIdCapture = ArgumentCaptor.forClass(Short.class);
- InOrder inOrder = inOrder(mockCallback1, mockCallback2, mMockNative);
+ InOrder inOrder = inOrder(mockCallback1, mockCallback2, mMockNative, mMockNativeManager);
mDut.enableUsage();
mMockLooper.dispatchAll();
@@ -5999,7 +5918,8 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
validateInternalClientInfoCleanedUp(clientId1);
validateInternalClientInfoCleanedUp(clientId2);
-
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNativeManager).releaseAware();
verifyNoMoreInteractions(mockCallback1, mockCallback2, mMockNative);
}
@@ -6060,7 +5980,8 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
inOrder.verify(mockCallback1).onAttachTerminate();
validateInternalClientInfoCleanedUp(clientId1);
-
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNativeManager).releaseAware();
verifyNoMoreInteractions(mockCallback1, mMockNative);
}
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/b2b/WifiRoamingModeManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/b2b/WifiRoamingModeManagerTest.java
index f4b7bfc212..89a6f32b49 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/b2b/WifiRoamingModeManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/b2b/WifiRoamingModeManagerTest.java
@@ -16,7 +16,6 @@
package com.android.server.wifi.b2b;
-import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.never;
@@ -29,7 +28,6 @@ import android.net.wifi.WifiSsid;
import androidx.test.filters.SmallTest;
-import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.ActiveModeWarden;
import com.android.server.wifi.ClientModeManager;
import com.android.server.wifi.WifiBaseTest;
@@ -71,7 +69,6 @@ public class WifiRoamingModeManagerTest extends WifiBaseTest {
@Test
public void testSetPerSsidRoamingMode() {
- assumeTrue(SdkLevel.isAtLeastV());
when(mWifiRoamingConfigStore.getRoamingMode(CURRENT_SSID)).thenReturn(
TEST_ROAMING_MODE);
mWifiRoamingModeManager.setPerSsidRoamingMode(WifiSsid.fromString(CURRENT_SSID),
@@ -84,7 +81,6 @@ public class WifiRoamingModeManagerTest extends WifiBaseTest {
@Test
public void testRemovePerSsidRoamingMode() {
- assumeTrue(SdkLevel.isAtLeastV());
mWifiRoamingModeManager.removePerSsidRoamingMode(WifiSsid.fromString(TEST_SSID), false);
verify(mWifiRoamingConfigStore).removeRoamingMode(TEST_SSID, false);
verify(mActiveModeWarden).getConnectionInfo();
@@ -94,7 +90,6 @@ public class WifiRoamingModeManagerTest extends WifiBaseTest {
@Test
public void testGetPerSsidRoamingMode() {
- assumeTrue(SdkLevel.isAtLeastV());
mWifiRoamingModeManager.getPerSsidRoamingModes(false);
verify(mWifiRoamingConfigStore).getPerSsidRoamingModes(false);
verify(mActiveModeWarden, never()).getConnectionInfo();
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipAidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipAidlImplTest.java
index 8e65ef6ef9..2850a1abec 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipAidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipAidlImplTest.java
@@ -17,6 +17,7 @@
package com.android.server.wifi.hal;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.server.wifi.util.GeneralUtil.longToBitset;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -65,6 +66,7 @@ import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.List;
import java.util.Random;
@@ -123,12 +125,12 @@ public class WifiChipAidlImplTest extends WifiBaseTest {
| android.hardware.wifi.IWifiChip.FeatureSetMask.D2D_RTT
| android.hardware.wifi.IWifiChip.FeatureSetMask.D2AP_RTT
);
- long expected = (
+ BitSet expected = longToBitset(
WifiManager.WIFI_FEATURE_TX_POWER_LIMIT
| WifiManager.WIFI_FEATURE_D2D_RTT
| WifiManager.WIFI_FEATURE_D2AP_RTT
);
- assertEquals(expected, mDut.halToFrameworkChipFeatureSet(halFeatures));
+ assertTrue(expected.equals(mDut.halToFrameworkChipFeatureSet(halFeatures)));
}
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipHidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipHidlImplTest.java
index 26bcca3b18..53dd5b47a5 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipHidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiChipHidlImplTest.java
@@ -16,6 +16,8 @@
package com.android.server.wifi.hal;
+import static com.android.server.wifi.util.GeneralUtil.longToBitset;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -63,6 +65,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.List;
import java.util.Random;
@@ -153,12 +156,12 @@ public class WifiChipHidlImplTest extends WifiBaseTest {
| android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2D_RTT
| android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2AP_RTT
);
- long expected = (
+ BitSet expected = longToBitset(
WifiManager.WIFI_FEATURE_TX_POWER_LIMIT
| WifiManager.WIFI_FEATURE_D2D_RTT
| WifiManager.WIFI_FEATURE_D2AP_RTT
);
- assertEquals(expected, mDut.wifiFeatureMaskFromChipCapabilities(caps));
+ assertTrue(expected.equals(mDut.wifiFeatureMaskFromChipCapabilities(caps)));
}
/**
@@ -170,11 +173,11 @@ public class WifiChipHidlImplTest extends WifiBaseTest {
android.hardware.wifi.V1_3.IWifiChip.ChipCapabilityMask.SET_LATENCY_MODE
| android.hardware.wifi.V1_1.IWifiChip.ChipCapabilityMask.D2D_RTT
);
- long expected = (
+ BitSet expected = longToBitset(
WifiManager.WIFI_FEATURE_LOW_LATENCY
| WifiManager.WIFI_FEATURE_D2D_RTT
);
- assertEquals(expected, mDut.wifiFeatureMaskFromChipCapabilities_1_3(caps));
+ assertTrue(expected.equals(mDut.wifiFeatureMaskFromChipCapabilities_1_3(caps)));
}
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceAidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceAidlImplTest.java
index 192c97ac8f..d633b57b8e 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceAidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiNanIfaceAidlImplTest.java
@@ -18,9 +18,14 @@ package com.android.server.wifi.hal;
import static android.hardware.wifi.V1_0.NanCipherSuiteType.SHARED_KEY_128_MASK;
import static android.hardware.wifi.V1_0.NanCipherSuiteType.SHARED_KEY_256_MASK;
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128;
+import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_256;
import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128;
import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
+import static com.android.server.wifi.aware.WifiAwareStateManager.NAN_PAIRING_AKM_PASN;
+import static com.android.server.wifi.aware.WifiAwareStateManager.NAN_PAIRING_AKM_SAE;
+
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -33,10 +38,12 @@ import android.hardware.wifi.IWifiNanIface;
import android.hardware.wifi.NanBandIndex;
import android.hardware.wifi.NanBootstrappingRequest;
import android.hardware.wifi.NanBootstrappingResponse;
+import android.hardware.wifi.NanCipherSuiteType;
import android.hardware.wifi.NanConfigRequest;
import android.hardware.wifi.NanConfigRequestSupplemental;
import android.hardware.wifi.NanDataPathSecurityType;
import android.hardware.wifi.NanEnableRequest;
+import android.hardware.wifi.NanPairingAkm;
import android.hardware.wifi.NanPairingRequest;
import android.hardware.wifi.NanPairingRequestType;
import android.hardware.wifi.NanPairingSecurityType;
@@ -506,7 +513,8 @@ public class WifiNanIfaceAidlImplTest extends WifiBaseTest {
ArgumentCaptor<NanRespondToPairingIndicationRequest> reqCaptor = ArgumentCaptor.forClass(
NanRespondToPairingIndicationRequest.class);
assertTrue(mDut.respondToPairingRequest(tid, 1, true, null, true,
- NanPairingRequestType.NAN_PAIRING_SETUP, null, null , 0, 0));
+ NanPairingRequestType.NAN_PAIRING_SETUP, null, null , NAN_PAIRING_AKM_PASN,
+ WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_256));
verify(mIWifiNanIfaceMock).respondToPairingIndicationRequest(eq((char) tid),
reqCaptor.capture());
NanRespondToPairingIndicationRequest request = reqCaptor.getValue();
@@ -518,6 +526,9 @@ public class WifiNanIfaceAidlImplTest extends WifiBaseTest {
assertArrayEquals(new byte[0], request.securityConfig.passphrase);
assertTrue(request.enablePairingCache);
assertArrayEquals(new byte[16], request.pairingIdentityKey);
+ assertEquals(NanCipherSuiteType.PUBLIC_KEY_PASN_256_MASK,
+ request.securityConfig.cipherType);
+ assertEquals(NanPairingAkm.PASN, request.securityConfig.akm);
}
@Test
@@ -527,17 +538,21 @@ public class WifiNanIfaceAidlImplTest extends WifiBaseTest {
ArgumentCaptor<NanPairingRequest> reqCaptor = ArgumentCaptor.forClass(
NanPairingRequest.class);
assertTrue(mDut.initiateNanPairingRequest(tid, 1, peer, null, true,
- NanPairingRequestType.NAN_PAIRING_SETUP, null, null , 0, 0));
+ NanPairingRequestType.NAN_PAIRING_SETUP, null, "PASSWORD", NAN_PAIRING_AKM_SAE,
+ WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128));
verify(mIWifiNanIfaceMock).initiatePairingRequest(eq((char) tid),
reqCaptor.capture());
NanPairingRequest request = reqCaptor.getValue();
assertEquals(NanPairingRequestType.NAN_PAIRING_SETUP, request.requestType);
assertEquals(1, request.peerId);
- assertEquals(NanPairingSecurityType.OPPORTUNISTIC, request.securityConfig.securityType);
+ assertEquals(NanPairingSecurityType.PASSPHRASE, request.securityConfig.securityType);
assertArrayEquals(new byte[32], request.securityConfig.pmk);
- assertArrayEquals(new byte[0], request.securityConfig.passphrase);
+ assertArrayEquals("PASSWORD".getBytes(), request.securityConfig.passphrase);
assertTrue(request.enablePairingCache);
assertArrayEquals(new byte[16], request.pairingIdentityKey);
+ assertEquals(NanCipherSuiteType.PUBLIC_KEY_PASN_128_MASK,
+ request.securityConfig.cipherType);
+ assertEquals(NanPairingAkm.SAE, request.securityConfig.akm);
}
@Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerAidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerAidlImplTest.java
index 6b541a7bd3..199b0e3313 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerAidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiRttControllerAidlImplTest.java
@@ -131,7 +131,7 @@ public class WifiRttControllerAidlImplTest extends WifiBaseTest {
@Test
public void testRangeRequest() throws Exception {
int cmdId = 55;
- RangingRequest request = RttTestUtils.getDummyRangingRequest((byte) 0);
+ RangingRequest request = RttTestUtils.getDummyRangingRequestWith11az((byte) 0);
// (1) issue range request
mDut.rangeRequest(cmdId, request);
@@ -175,6 +175,22 @@ public class WifiRttControllerAidlImplTest extends WifiBaseTest {
collector.checkThat("entry 2: rtt burst size", rttConfig.numFramesPerBurst,
equalTo(RangingRequest.getMaxRttBurstSize()));
+ rttConfig = halRequest[3];
+ collector.checkThat("entry 0: MAC", rttConfig.addr,
+ equalTo(MacAddress.fromString("00:11:22:33:44:00").toByteArray()));
+ collector.checkThat("entry 0: rtt type", rttConfig.type,
+ equalTo(RttType.TWO_SIDED_11AZ_NTB));
+ collector.checkThat("entry 0: peer type", rttConfig.peer, equalTo(RttPeerType.AP));
+ collector.checkThat("entry 0: lci", rttConfig.mustRequestLci, equalTo(true));
+ collector.checkThat("entry 0: lcr", rttConfig.mustRequestLcr, equalTo(true));
+ collector.checkThat("entry 0: rtt burst size", rttConfig.numFramesPerBurst,
+ equalTo(RangingRequest.getMaxRttBurstSize()));
+ // ntbMinMeasurementTime in units of 100 us
+ // DEFAULT_NTB_MIN_TIME_BETWEEN_MEASUREMENTS_MICROS = 250000 --> 2500 * 100 us
+ collector.checkThat("", rttConfig.ntbMinMeasurementTime, equalTo(2500L));
+ // ntbMaxMeasurementTime in units of 10 ms
+ // DEFAULT_NTB_MAX_TIME_BETWEEN_MEASUREMENTS_MICROS = 15000000 --> 1500 * 10 ms
+ collector.checkThat("", rttConfig.ntbMaxMeasurementTime, equalTo(1500L));
verifyNoMoreInteractions(mIWifiRttControllerMock);
}
@@ -350,6 +366,63 @@ public class WifiRttControllerAidlImplTest extends WifiBaseTest {
}
/**
+ * Validate correct 11az NTB result conversion from HAL to framework.
+ */
+ @Test
+ public void test11azNtbRangeResults() throws Exception {
+ int cmdId = 55;
+ RttResult[] results = new RttResult[1];
+ RttResult res = createRttResult();
+ res.type = RttType.TWO_SIDED_11AZ_NTB;
+ res.addr = MacAddress.byteAddrFromStringAddr("05:06:07:08:09:0A");
+ res.ntbMaxMeasurementTime = 10; // 10 * 10000 us = 100000 us
+ res.ntbMinMeasurementTime = 100; // 100 * 100 us = 10000 us
+ res.numRxSpatialStreams = 2;
+ res.numTxSpatialStreams = 3;
+ res.i2rTxLtfRepetitionCount = 3;
+ res.r2iTxLtfRepetitionCount = 2;
+ res.status = RttStatus.SUCCESS;
+ res.distanceInMm = 1500;
+ res.timeStampInUs = 6000;
+ res.packetBw = RttBw.BW_80MHZ;
+ results[0] = res;
+
+ // (1) have the HAL call us with results
+ mEventCallbackCaptor.getValue().onResults(cmdId, results);
+
+ // (2) verify call to framework
+ verify(mRangingResultsCallbackMock).onRangingResults(eq(cmdId), mRttResultCaptor.capture());
+
+ // verify contents of the framework results
+ List<RangingResult> rttR = mRttResultCaptor.getValue();
+
+ collector.checkThat("number of entries", rttR.size(), equalTo(1));
+
+ RangingResult rttResult = rttR.get(0);
+ collector.checkThat("Type", rttResult.is80211azNtbMeasurement(), equalTo(true));
+ collector.checkThat("status", rttResult.getStatus(),
+ equalTo(WifiRttController.FRAMEWORK_RTT_STATUS_SUCCESS));
+ collector.checkThat("mac", rttResult.getMacAddress().toByteArray(),
+ equalTo(MacAddress.fromString("05:06:07:08:09:0A").toByteArray()));
+ collector.checkThat("ntbMaxMeasurementTime",
+ rttResult.getMaxTimeBetweenNtbMeasurementsMicros(), equalTo(100000L));
+ collector.checkThat("ntbMinMeasurementTime",
+ rttResult.getMinTimeBetweenNtbMeasurementsMicros(), equalTo(10000L));
+ collector.checkThat("numRxSpatialStreams", rttResult.get80211azNumberOfRxSpatialStreams(),
+ equalTo(2));
+ collector.checkThat("numTxSpatialStreams", rttResult.get80211azNumberOfTxSpatialStreams(),
+ equalTo(3));
+ collector.checkThat("i2rTxLtfRepetitionCount",
+ rttResult.get80211azInitiatorTxLtfRepetitionsCount(), equalTo(3));
+ collector.checkThat("r2iTxLtfRepetitionCount",
+ rttResult.get80211azResponderTxLtfRepetitionsCount(), equalTo(2));
+ collector.checkThat("distanceCm", rttResult.getDistanceMm(), equalTo(1500));
+ collector.checkThat("timestamp", rttResult.getRangingTimestampMillis(), equalTo(6L));
+ collector.checkThat("channelBw", rttResult.getMeasurementBandwidth(),
+ equalTo(ScanResult.CHANNEL_WIDTH_80MHZ));
+ verifyNoMoreInteractions(mIWifiRttControllerMock);
+ }
+ /**
* Validate correct cleanup when a null array of results is provided by HAL.
*/
@Test
@@ -428,11 +501,14 @@ public class WifiRttControllerAidlImplTest extends WifiBaseTest {
cap.lciSupported = true;
cap.lcrSupported = true;
cap.responderSupported = true; // unused
+ cap.ntbInitiatorSupported = true;
cap.preambleSupport = RttPreamble.LEGACY | RttPreamble.HT | RttPreamble.VHT
| RttPreamble.HE;
+ cap.azPreambleSupport = cap.preambleSupport;
cap.bwSupport =
RttBw.BW_5MHZ | RttBw.BW_10MHZ | RttBw.BW_20MHZ | RttBw.BW_40MHZ | RttBw.BW_80MHZ
| RttBw.BW_160MHZ;
+ cap.azBwSupport = cap.bwSupport;
cap.mcVersion = 1; // unused
return cap;
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceAidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceAidlImplTest.java
index 668e105e53..4a0a4e3e9f 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceAidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceAidlImplTest.java
@@ -16,9 +16,12 @@
package com.android.server.wifi.hal;
+import static com.android.server.wifi.util.GeneralUtil.longToBitset;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -68,6 +71,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.nio.charset.StandardCharsets;
+import java.util.BitSet;
import java.util.List;
import java.util.Random;
@@ -96,10 +100,10 @@ public class WifiStaIfaceAidlImplTest extends WifiBaseTest {
IWifiStaIface.FeatureSetMask.BACKGROUND_SCAN
| IWifiStaIface.FeatureSetMask.LINK_LAYER_STATS
);
- long expected = (
+ BitSet expected = longToBitset(
WifiManager.WIFI_FEATURE_SCANNER
| WifiManager.WIFI_FEATURE_LINK_LAYER_STATS);
- assertEquals(expected, mDut.halToFrameworkStaFeatureSet(halFeatures));
+ assertTrue(expected.equals(mDut.halToFrameworkStaFeatureSet(halFeatures)));
}
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceHidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceHidlImplTest.java
index d41ba3af2e..8adb4fd171 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceHidlImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hal/WifiStaIfaceHidlImplTest.java
@@ -16,6 +16,8 @@
package com.android.server.wifi.hal;
+import static com.android.server.wifi.util.GeneralUtil.longToBitset;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -68,6 +70,7 @@ import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.Collections;
import java.util.List;
import java.util.Random;
@@ -143,10 +146,10 @@ public class WifiStaIfaceHidlImplTest extends WifiBaseTest {
IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN
| IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS
);
- long expected = (
+ BitSet expected = longToBitset(
WifiManager.WIFI_FEATURE_SCANNER
| WifiManager.WIFI_FEATURE_LINK_LAYER_STATS);
- assertEquals(expected, mDut.halToFrameworkStaIfaceCapability(caps));
+ assertTrue(expected.equals(mDut.halToFrameworkStaIfaceCapability(caps)));
}
/**
diff --git a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelperTest.java b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelperTest.java
index 4e59dda89b..a77c3db361 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelperTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkNominateHelperTest.java
@@ -266,8 +266,6 @@ public class PasspointNetworkNominateHelperTest extends WifiBaseTest {
assertEquals(RANDOMIZATION_NONE, addedConfig.getValue().macRandomizationSetting);
verify(mWifiConfigManager).enableNetwork(
eq(TEST_NETWORK_ID), eq(false), eq(TEST_UID), any());
- verify(mWifiConfigManager).setNetworkCandidateScanResult(
- eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt(), any());
verify(mWifiConfigManager).updateScanDetailForNetwork(
eq(TEST_NETWORK_ID), any(ScanDetail.class));
@@ -320,8 +318,6 @@ public class PasspointNetworkNominateHelperTest extends WifiBaseTest {
assertTrue(addedConfig.getValue().isHomeProviderNetwork);
verify(mWifiConfigManager).enableNetwork(
eq(TEST_NETWORK_ID), eq(false), eq(TEST_UID), any());
- verify(mWifiConfigManager).setNetworkCandidateScanResult(
- eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt(), any());
verify(mWifiConfigManager).updateScanDetailForNetwork(
eq(TEST_NETWORK_ID), any(ScanDetail.class));
}
@@ -363,8 +359,6 @@ public class PasspointNetworkNominateHelperTest extends WifiBaseTest {
assertFalse(addedConfig.getValue().isHomeProviderNetwork);
verify(mWifiConfigManager).enableNetwork(
eq(TEST_NETWORK_ID), eq(false), eq(TEST_UID), any());
- verify(mWifiConfigManager).setNetworkCandidateScanResult(
- eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt(), any());
verify(mWifiConfigManager).updateScanDetailForNetwork(
eq(TEST_NETWORK_ID), any(ScanDetail.class));
}
@@ -465,13 +459,6 @@ public class PasspointNetworkNominateHelperTest extends WifiBaseTest {
.getPasspointNetworkCandidates(scanDetails);
assertEquals(1, candidates.size());
-
- // Verify network candidate information is updated.
- ArgumentCaptor<ScanResult> updatedCandidateScanResult =
- ArgumentCaptor.forClass(ScanResult.class);
- verify(mWifiConfigManager).setNetworkCandidateScanResult(eq(TEST_NETWORK_ID),
- updatedCandidateScanResult.capture(), anyInt(), any());
- assertEquals(TEST_BSSID2, updatedCandidateScanResult.getValue().BSSID);
ArgumentCaptor<ScanDetail> updatedCandidateScanDetail =
ArgumentCaptor.forClass(ScanDetail.class);
verify(mWifiConfigManager).updateScanDetailForNetwork(eq(TEST_NETWORK_ID),
@@ -864,8 +851,6 @@ public class PasspointNetworkNominateHelperTest extends WifiBaseTest {
assertTrue(addedConfig.getValue().isHomeProviderNetwork);
verify(mWifiConfigManager).enableNetwork(
eq(TEST_NETWORK_ID), eq(false), eq(TEST_UID), any());
- verify(mWifiConfigManager).setNetworkCandidateScanResult(
- eq(TEST_NETWORK_ID), any(ScanResult.class), anyInt(), any());
verify(mWifiConfigManager).updateScanDetailForNetwork(
eq(TEST_NETWORK_ID), any(ScanDetail.class));
@@ -934,10 +919,6 @@ public class PasspointNetworkNominateHelperTest extends WifiBaseTest {
verify(mWifiConfigManager)
.enableNetwork(eq(TEST_NETWORK_ID2), eq(false), anyInt(), any());
verify(mWifiConfigManager)
- .setNetworkCandidateScanResult(eq(TEST_NETWORK_ID), any(), anyInt(), any());
- verify(mWifiConfigManager)
- .setNetworkCandidateScanResult(eq(TEST_NETWORK_ID2), any(), anyInt(), any());
- verify(mWifiConfigManager)
.updateScanDetailForNetwork(eq(TEST_NETWORK_ID), eq(scanDetails.get(0)));
verify(mWifiConfigManager)
.updateScanDetailForNetwork(eq(TEST_NETWORK_ID2), eq(scanDetails.get(0)));
diff --git a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java
index dba7220a05..2ec2e59152 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java
@@ -29,6 +29,7 @@ import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_P2P_DEVICE_AD
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_P2P_DEVICE_NAME;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_P2P_PENDING_FACTORY_RESET;
import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_VERBOSE_LOGGING_ENABLED;
+import static com.android.server.wifi.p2p.WifiP2pServiceImpl.IPC_DHCP_RESULTS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -78,6 +79,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.location.LocationManager;
import android.net.ConnectivityManager;
+import android.net.DhcpResultsParcelable;
import android.net.InetAddresses;
import android.net.LinkAddress;
import android.net.MacAddress;
@@ -202,6 +204,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
private static final String thisDeviceName = "thisDeviceName";
private static final String ANONYMIZED_DEVICE_ADDRESS = "02:00:00:00:00:00";
private static final String TEST_PACKAGE_NAME = "com.p2p.test";
+ private static final String TEST_PACKAGE2_NAME = "com.p2p.test2";
private static final String TEST_NETWORK_NAME = "DIRECT-xy-NEW";
private static final String TEST_ANDROID_ID = "314Deadbeef";
private static final String[] TEST_REQUIRED_PERMISSIONS_T =
@@ -230,8 +233,10 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
private BroadcastReceiver mTetherStateReceiver;
private BroadcastReceiver mUserRestrictionReceiver;
private Handler mClientHandler;
+ private Handler mClient2Handler;
private Messenger mP2pStateMachineMessenger;
private Messenger mClientMessenger;
+ private Messenger mClient2Messenger;
private WifiP2pServiceImpl mWifiP2pServiceImpl;
private TestLooper mClientHanderLooper;
private TestLooper mLooper;
@@ -252,6 +257,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
private TetheringManager.TetheringEventCallback mTetheringEventCallback;
private Bundle mExtras = new Bundle();
private IWifiP2pListener mP2pListener = mock(IWifiP2pListener.class);
+ private IWifiP2pListener mP2pListener2 = mock(IWifiP2pListener.class);
private ArgumentCaptor<WifiSettingsConfigStore.OnSettingsChangedListener>
mD2DAllowedSettingsCallbackCaptor =
ArgumentCaptor.forClass(WifiSettingsConfigStore.OnSettingsChangedListener.class);
@@ -652,9 +658,10 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
/**
* Send WifiP2pMonitor.P2P_GROUP_REMOVED_EVENT.
*/
- private void sendGroupRemovedMsg() throws Exception {
+ private void sendGroupRemovedMsg(WifiP2pGroup group) throws Exception {
Message msg = Message.obtain();
msg.what = WifiP2pMonitor.P2P_GROUP_REMOVED_EVENT;
+ msg.obj = group;
mP2pStateMachineMessenger.send(Message.obtain(msg));
mLooper.dispatchAll();
}
@@ -1383,7 +1390,9 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
generatorTestData();
mClientHanderLooper = new TestLooper();
mClientHandler = spy(new Handler(mClientHanderLooper.getLooper()));
+ mClient2Handler = spy(new Handler(mClientHanderLooper.getLooper()));
mClientMessenger = new Messenger(mClientHandler);
+ mClient2Messenger = new Messenger(mClient2Handler);
mLooper = new TestLooper();
when(mContext.getSystemService(Context.ALARM_SERVICE))
@@ -1517,6 +1526,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
when(mDeviceConfigFacade.isP2pFailureBugreportEnabled()).thenReturn(false);
when(mContext.getSystemService(TetheringManager.class)).thenReturn(mTetheringManager);
when(mP2pListener.asBinder()).thenReturn(mock(IBinder.class));
+ when(mP2pListener2.asBinder()).thenReturn(mock(IBinder.class));
mWifiP2pServiceImpl = new WifiP2pServiceImpl(mContext, mWifiInjector);
if (supported) {
@@ -1579,6 +1589,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
mWifiP2pServiceImpl.handleBootCompleted();
if (SdkLevel.isAtLeastT()) {
mWifiP2pServiceImpl.registerWifiP2pListener(mP2pListener, TEST_PACKAGE_NAME, mExtras);
+ mWifiP2pServiceImpl.registerWifiP2pListener(mP2pListener2, TEST_PACKAGE2_NAME, mExtras);
}
}
@@ -2956,6 +2967,407 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
anyInt(), anyInt(), anyString(), eq(true));
}
+ /**
+ * Sets up the environment for P2P Ownership test where Client1 is the group owner.
+ */
+ private void groupOwnershipConfigTestSetup() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ when(mFeatureFlags.p2pOwnership()).thenReturn(true);
+ forceP2pEnabled(mClient1);
+ sendChannelInfoUpdateMsg(TEST_PACKAGE2_NAME, "testFeature", mClient2, mClient2Messenger);
+
+ // group created by client1
+ when(mWifiNative.p2pGroupAdd(any(), eq(false))).thenReturn(true);
+ sendCreateGroupMsgWithConfigValidAsGroup(mClientMessenger);
+ verify(mWifiNative).p2pGroupAdd(any(), eq(false));
+ assertTrue(mClientHandler.hasMessages(WifiP2pManager.CREATE_GROUP_SUCCEEDED));
+ assertFalse(mClient2Handler.hasMessages(WifiP2pManager.CREATE_GROUP_SUCCEEDED));
+
+ WifiP2pGroup group = new WifiP2pGroup();
+ group.setNetworkName("DIRECT-test");
+ group.setOwner(new WifiP2pDevice("thisDeviceMac"));
+ group.setIsGroupOwner(true);
+ group.setInterface(IFACE_NAME_P2P);
+ sendGroupStartedMsg(group);
+ simulateTetherReady();
+ reset(mClientHandler);
+ }
+
+ /**
+ * Sets up the environment for P2P Ownership test with WPS group.
+ */
+ private void groupOwnershipWpsTestSetup() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ mWifiP2pServiceImpl.registerWifiP2pListener(mP2pListener2, TEST_PACKAGE2_NAME, mExtras);
+ forceP2pEnabled(mClient1);
+ sendChannelInfoUpdateMsg(TEST_PACKAGE2_NAME, "testFeature", mClient2, mClient2Messenger);
+
+ // WPS group created
+ WifiP2pGroup group = new WifiP2pGroup();
+ group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
+ group.setNetworkName(TEST_NETWORK_NAME);
+ group.setOwner(new WifiP2pDevice("thisDeviceMac"));
+ group.setIsGroupOwner(true);
+ group.setInterface(IFACE_NAME_P2P);
+ sendGroupStartedMsg(group);
+ simulateTetherReady();
+ }
+
+ /** Verify that only the group owner can send an invitation connection */
+ @Test
+ public void testGroupOwnershipConfigJoinInvite() throws Exception {
+ groupOwnershipConfigTestSetup();
+
+ // client2 cannot send an invitation to join
+ sendConnectMsg(mClient2Messenger, mTestWifiP2pPeerConfig);
+ verify(mClient2Handler).sendMessage(mMessageCaptor.capture());
+ Message message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.CONNECT_FAILED, message.what);
+ assertEquals(WifiP2pManager.BUSY, message.arg1);
+
+ // client1 can send an invitation to join
+ when(mWifiNative.p2pInvite(any(), any())).thenReturn(true);
+ mockPeersList();
+ sendConnectMsg(mClientMessenger, mTestWifiP2pPeerConfig);
+ verify(mClientHandler).sendMessage(mMessageCaptor.capture());
+ message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.CONNECT_SUCCEEDED, message.what);
+ }
+
+ /** Verify that any client can send an invitation connection */
+ @Test
+ public void testGroupOwnershipWpsJoinInvite() throws Exception {
+ groupOwnershipWpsTestSetup();
+
+ // client1 can send an invitation to join
+ when(mWifiNative.p2pInvite(any(), any())).thenReturn(true);
+ mockPeersList();
+ sendConnectMsg(mClientMessenger, mTestWifiP2pPeerConfig);
+ verify(mClientHandler).sendMessage(mMessageCaptor.capture());
+ Message message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.CONNECT_SUCCEEDED, message.what);
+
+ // client2 can send an invitation to join
+ sendConnectMsg(mClient2Messenger, mTestWifiP2pPeerConfig);
+ verify(mClient2Handler).sendMessage(mMessageCaptor.capture());
+ message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.CONNECT_SUCCEEDED, message.what);
+ }
+
+ /** Verify that only the group owner can cancel an invitation connection */
+ @Test
+ public void testGroupOwnershipConfigCancelInvitationConnect() throws Exception {
+ groupOwnershipConfigTestSetup();
+
+ // client2 cannot cancel invitation connection
+ sendSimpleMsg(mClient2Messenger, WifiP2pManager.CANCEL_CONNECT);
+ verify(mClient2Handler).sendMessage(mMessageCaptor.capture());
+ Message message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.CANCEL_CONNECT_FAILED, message.what);
+ assertEquals(WifiP2pManager.BUSY, message.arg1);
+
+ // client1 can cancel invitation connection
+ sendSimpleMsg(mClientMessenger, WifiP2pManager.CANCEL_CONNECT);
+ verify(mClientHandler).sendMessage(mMessageCaptor.capture());
+ message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.CANCEL_CONNECT_SUCCEEDED, message.what);
+ }
+
+ /** Verify that any client can cancel an invitation connection */
+ @Test
+ public void testGroupOwnershipWpsCancelInvitationConnect() throws Exception {
+ groupOwnershipWpsTestSetup();
+
+ // client1 can cancel invitation connection
+ sendSimpleMsg(mClientMessenger, WifiP2pManager.CANCEL_CONNECT);
+ verify(mClientHandler).sendMessage(mMessageCaptor.capture());
+ Message message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.CANCEL_CONNECT_SUCCEEDED, message.what);
+
+ // client2 can cancel invitation connection
+ sendSimpleMsg(mClient2Messenger, WifiP2pManager.CANCEL_CONNECT);
+ verify(mClient2Handler).sendMessage(mMessageCaptor.capture());
+ message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.CANCEL_CONNECT_SUCCEEDED, message.what);
+ }
+
+ /** Verify that only the client that initiated the connection can cancel it */
+ @Test
+ public void testGroupOwnershipConfigCancelConnect() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ when(mFeatureFlags.p2pOwnership()).thenReturn(true);
+ forceP2pEnabled(mClient1);
+ sendChannelInfoUpdateMsg(TEST_PACKAGE2_NAME, "testFeature", mClient2, mClient2Messenger);
+
+ // group created by client1
+ when(mWifiNative.p2pGroupAdd(any(), eq(false))).thenReturn(true);
+ sendCreateGroupMsgWithConfigValidAsGroup(mClientMessenger);
+ verify(mWifiNative).p2pGroupAdd(any(), eq(false));
+ reset(mClientHandler);
+
+ // client2 cannot cancel connection
+ sendSimpleMsg(mClient2Messenger, WifiP2pManager.CANCEL_CONNECT);
+ verify(mClient2Handler).sendMessage(mMessageCaptor.capture());
+ Message message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.CANCEL_CONNECT_FAILED, message.what);
+ assertEquals(WifiP2pManager.BUSY, message.arg1);
+
+ // client1 can cancel connection
+ sendSimpleMsg(mClientMessenger, WifiP2pManager.CANCEL_CONNECT);
+ verify(mClientHandler).sendMessage(mMessageCaptor.capture());
+ message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.CANCEL_CONNECT_SUCCEEDED, message.what);
+ }
+
+ /** Verify that any client can cancel an ongoing WPS connection */
+ @Test
+ public void testGroupOwnershipWpsCancelConnect() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastV());
+ when(mFeatureFlags.p2pOwnership()).thenReturn(true);
+ forceP2pEnabled(mClient1);
+ sendChannelInfoUpdateMsg(TEST_PACKAGE2_NAME, "testFeature", mClient2, mClient2Messenger);
+
+ // connection initiated by client1
+ when(mWifiNative.p2pGroupAdd(anyBoolean())).thenReturn(true);
+ mockEnterGroupNegotiationState();
+
+ // client2 can cancel connection
+ sendSimpleMsg(mClient2Messenger, WifiP2pManager.CANCEL_CONNECT);
+ verify(mClient2Handler).sendMessage(mMessageCaptor.capture());
+ Message message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.CANCEL_CONNECT_SUCCEEDED, message.what);
+ }
+
+ /** Verify that only the group owner can remove the group */
+ @Test
+ public void testGroupOwnershipConfigRemoveGroup() throws Exception {
+ groupOwnershipConfigTestSetup();
+
+ // client2 cannot remove group
+ sendSimpleMsg(mClient2Messenger, WifiP2pManager.REMOVE_GROUP);
+ verify(mClient2Handler).sendMessage(mMessageCaptor.capture());
+ Message message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.REMOVE_GROUP_FAILED, message.what);
+ assertEquals(WifiP2pManager.BUSY, message.arg1);
+
+ // client1 can remove group
+ when(mWifiNative.p2pGroupRemove(eq(IFACE_NAME_P2P))).thenReturn(true);
+ sendSimpleMsg(mClientMessenger, WifiP2pManager.REMOVE_GROUP);
+ verify(mWifiNative).p2pGroupRemove(eq(IFACE_NAME_P2P));
+ verify(mClientHandler).sendMessage(mMessageCaptor.capture());
+ message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.REMOVE_GROUP_SUCCEEDED, message.what);
+ }
+
+ /** Verify that any client can remove the group */
+ @Test
+ public void testGroupOwnershipWpsRemoveGroup() throws Exception {
+ groupOwnershipWpsTestSetup();
+
+ // client2 can remove group
+ when(mWifiNative.p2pGroupRemove(eq(IFACE_NAME_P2P))).thenReturn(true);
+ sendSimpleMsg(mClient2Messenger, WifiP2pManager.REMOVE_GROUP);
+ verify(mWifiNative).p2pGroupRemove(eq(IFACE_NAME_P2P));
+ verify(mClient2Handler).sendMessage(mMessageCaptor.capture());
+ Message message = mMessageCaptor.getValue();
+ assertEquals(WifiP2pManager.REMOVE_GROUP_SUCCEEDED, message.what);
+ }
+
+ /** Verify that only the group owner can get group info */
+ @Test
+ public void testGroupOwnershipConfigGetGroupInformation() throws Exception {
+ groupOwnershipConfigTestSetup();
+
+ // client2 cannot get P2P group info
+ sendRequestGroupInfoMsg(mClient2Messenger);
+ verify(mClient2Handler).sendMessage(mMessageCaptor.capture());
+ assertEquals(WifiP2pManager.RESPONSE_GROUP_INFO, mMessageCaptor.getValue().what);
+ WifiP2pGroup wifiP2pGroup = (WifiP2pGroup) mMessageCaptor.getValue().obj;
+ assertNull(wifiP2pGroup);
+
+ // client1 can get P2P group info
+ sendRequestGroupInfoMsg(mClientMessenger);
+ verify(mClientHandler).sendMessage(mMessageCaptor.capture());
+ assertEquals(WifiP2pManager.RESPONSE_GROUP_INFO, mMessageCaptor.getValue().what);
+ wifiP2pGroup = (WifiP2pGroup) mMessageCaptor.getValue().obj;
+ assertNotNull(wifiP2pGroup);
+ }
+
+ /** Verify that any client can get group info */
+ @Test
+ public void testGroupOwnershipWpsGetGroupInformation() throws Exception {
+ groupOwnershipWpsTestSetup();
+
+ // client1 can get P2P group info
+ sendRequestGroupInfoMsg(mClientMessenger);
+ verify(mClientHandler).sendMessage(mMessageCaptor.capture());
+ assertEquals(WifiP2pManager.RESPONSE_GROUP_INFO, mMessageCaptor.getValue().what);
+ WifiP2pGroup wifiP2pGroup = (WifiP2pGroup) mMessageCaptor.getValue().obj;
+ assertNotNull(wifiP2pGroup);
+
+ // client2 can get P2P group info
+ sendRequestGroupInfoMsg(mClient2Messenger);
+ verify(mClient2Handler).sendMessage(mMessageCaptor.capture());
+ assertEquals(WifiP2pManager.RESPONSE_GROUP_INFO, mMessageCaptor.getValue().what);
+ wifiP2pGroup = (WifiP2pGroup) mMessageCaptor.getValue().obj;
+ assertNotNull(wifiP2pGroup);
+ }
+
+ /** Verify that only the group owner can get connection info */
+ @Test
+ public void testGroupOwnershipConfigGetConnectionInfo() throws Exception {
+ groupOwnershipConfigTestSetup();
+
+ // client2 cannot get P2P connection info
+ sendSimpleMsg(mClient2Messenger, WifiP2pManager.REQUEST_CONNECTION_INFO);
+ verify(mClient2Handler).sendMessage(mMessageCaptor.capture());
+ Message message = mMessageCaptor.getValue();
+ WifiP2pInfo info = (WifiP2pInfo) message.obj;
+ assertEquals(WifiP2pManager.RESPONSE_CONNECTION_INFO, message.what);
+ assertEquals((new WifiP2pInfo()).toString(), info.toString());
+
+ // client1 can get P2P connection info
+ sendSimpleMsg(mClientMessenger, WifiP2pManager.REQUEST_CONNECTION_INFO);
+ verify(mClientHandler).sendMessage(mMessageCaptor.capture());
+ message = mMessageCaptor.getValue();
+ info = (WifiP2pInfo) message.obj;
+ assertEquals(WifiP2pManager.RESPONSE_CONNECTION_INFO, mMessageCaptor.getValue().what);
+ assertTrue(info.groupFormed);
+ }
+
+ /** Verify that any client can get connection info */
+ @Test
+ public void testGroupOwnershipWpsGetConnectionInfo() throws Exception {
+ groupOwnershipWpsTestSetup();
+
+ // client1 can get P2P connection info
+ sendSimpleMsg(mClientMessenger, WifiP2pManager.REQUEST_CONNECTION_INFO);
+ verify(mClientHandler).sendMessage(mMessageCaptor.capture());
+ Message message = mMessageCaptor.getValue();
+ WifiP2pInfo info = (WifiP2pInfo) message.obj;
+ assertEquals(WifiP2pManager.RESPONSE_CONNECTION_INFO, mMessageCaptor.getValue().what);
+ assertTrue(info.groupFormed);
+
+ // client2 can get P2P connection info
+ sendSimpleMsg(mClient2Messenger, WifiP2pManager.REQUEST_CONNECTION_INFO);
+ verify(mClient2Handler).sendMessage(mMessageCaptor.capture());
+ message = mMessageCaptor.getValue();
+ info = (WifiP2pInfo) message.obj;
+ assertEquals(WifiP2pManager.RESPONSE_CONNECTION_INFO, mMessageCaptor.getValue().what);
+ assertTrue(info.groupFormed);
+ }
+
+ /** Verify that only the group owner receives the connection changed broadcast */
+ @Test
+ public void testGroupOwnershipConfigBroadcast() throws Exception {
+ groupOwnershipConfigTestSetup();
+
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mContext, atLeastOnce()).sendBroadcast(intentCaptor.capture(), any(), any());
+
+ ArrayList<Intent> intentArrayList = new ArrayList<>();
+ for (int i = 0; i < intentCaptor.getAllValues().size(); i++) {
+ Intent intent = intentCaptor.getAllValues().get(i);
+ if (intent.getAction().equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
+ intentArrayList.add(intent);
+ }
+ }
+ // Connection changed broadcast is sent 3 times:
+ // 1. Entering P2pEnabledState
+ // 2. Entering GroupCreatingState
+ // 3. Entering GroupCreatedState
+ // Each time, sendBroadcast is called twice (refer sendBroadcastWithExcludedPermissions)
+ // Verify group created broadcast only sent to client1
+ Intent intent = intentArrayList.get(4);
+ assertEquals(TEST_PACKAGE_NAME, intent.getPackage());
+ // Verify broadcast sent to NEARBY_WIFI_DEVICES apps do not have the package name set
+ intent = intentArrayList.get(5);
+ assertNull(intent.getPackage());
+ }
+
+ /** Verify that all clients receive the connection changed broadcast */
+ @Test
+ public void testGroupOwnershipWpsBroadcast() throws Exception {
+ groupOwnershipWpsTestSetup();
+
+ WifiP2pDevice connectedClientDevice = new WifiP2pDevice(mTestWifiP2pDevice);
+ connectedClientDevice.setInterfaceMacAddress(MacAddress.fromString(PEER_INTERFACE_ADDRESS));
+ sendApStaConnectedEvent(connectedClientDevice);
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mContext, atLeastOnce()).sendBroadcast(intentCaptor.capture(), any(), any());
+
+ ArrayList<Intent> intentArrayList = new ArrayList<>();
+ for (int i = 0; i < intentCaptor.getAllValues().size(); i++) {
+ Intent intent = intentCaptor.getAllValues().get(i);
+ if (intent.getAction().equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
+ intentArrayList.add(intent);
+ }
+ }
+ // Connection changed broadcast is sent 3 times:
+ // 1. Entering P2pEnabledState
+ // 2. Entering GroupCreatingState
+ // 3. Peer connection in GroupCreatedState
+ // Each time, sendBroadcast is called twice (refer sendBroadcastWithExcludedPermissions)
+ // Verify group created broadcast sent to all clients
+ Intent intent = intentArrayList.get(4);
+ assertNull(intent.getPackage());
+ }
+
+ /** Verify that only the group owner receives the group related callback */
+ @Test
+ public void testGroupOwnershipConfigP2pListener() throws Exception {
+ groupOwnershipConfigTestSetup();
+
+ verify(mP2pListener).onGroupCreated(any(), any());
+ verify(mP2pListener2, never()).onGroupCreated(any(), any());
+
+ WifiP2pDevice peerClientDevice = new WifiP2pDevice();
+ peerClientDevice.deviceName = "peerClientDeviceName";
+ peerClientDevice.deviceAddress = "11:22:33:aa:bb:cc";
+ peerClientDevice.setInterfaceMacAddress(MacAddress.fromString(PEER_INTERFACE_ADDRESS));
+ sendSimpleMsg(null, WifiP2pMonitor.AP_STA_CONNECTED_EVENT, peerClientDevice);
+ verify(mP2pListener).onPeerClientJoined(any(), any());
+ verify(mP2pListener2, never()).onPeerClientJoined(any(), any());
+
+ sendSimpleMsg(null, WifiP2pMonitor.AP_STA_DISCONNECTED_EVENT, peerClientDevice);
+ verify(mP2pListener).onPeerClientDisconnected(any(), any());
+ verify(mP2pListener2, never()).onPeerClientDisconnected(any(), any());
+
+ sendSimpleMsg(null, WifiP2pMonitor.P2P_FREQUENCY_CHANGED_EVENT, TEST_GROUP_FREQUENCY);
+ verify(mP2pListener).onFrequencyChanged(any(), any());
+ verify(mP2pListener2, never()).onFrequencyChanged(any(), any());
+ }
+
+ /** Verify that all clients receive the group related callback */
+ @Test
+ public void testGroupOwnershipWpsP2pListener() throws Exception {
+ groupOwnershipWpsTestSetup();
+
+ DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable();
+ dhcpResults.serverAddress = P2P_GO_IP;
+ sendSimpleMsg(mClientMessenger, IPC_DHCP_RESULTS, dhcpResults);
+ verify(mP2pListener).onGroupCreated(any(), any());
+ verify(mP2pListener2).onGroupCreated(any(), any());
+
+ WifiP2pDevice connectedClientDevice = new WifiP2pDevice(mTestWifiP2pDevice);
+ connectedClientDevice.setInterfaceMacAddress(MacAddress.fromString(PEER_INTERFACE_ADDRESS));
+ sendApStaConnectedEvent(connectedClientDevice);
+ verify(mP2pListener).onPeerClientJoined(any(), any());
+ verify(mP2pListener2).onPeerClientJoined(any(), any());
+
+ // Need to connect a second peer device before testing disconnect to avoid removing group
+ WifiP2pDevice secondPeerDevice = new WifiP2pDevice(connectedClientDevice);
+ secondPeerDevice.deviceAddress = "11:22:33:aa:bb:cc";
+ sendApStaConnectedEvent(secondPeerDevice);
+ sendSimpleMsg(null, WifiP2pMonitor.AP_STA_DISCONNECTED_EVENT, connectedClientDevice);
+ verify(mP2pListener).onPeerClientDisconnected(any(), any());
+ verify(mP2pListener2).onPeerClientDisconnected(any(), any());
+
+ sendSimpleMsg(null, WifiP2pMonitor.P2P_FREQUENCY_CHANGED_EVENT, TEST_GROUP_FREQUENCY);
+ verify(mP2pListener).onFrequencyChanged(any(), any());
+ verify(mP2pListener2).onFrequencyChanged(any(), any());
+ }
+
/** Verify the p2p randomized MAC feature is enabled if OEM supports it. */
@Test
public void testP2pRandomMacWithOemSupport() throws Exception {
@@ -3168,7 +3580,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
WifiP2pGroup groupCaptured = groupCaptor.getValue();
assertEquals(mTestWifiP2pNewPersistentGoGroup.toString(), groupCaptured.toString());
- sendGroupRemovedMsg();
+ sendGroupRemovedMsg(groupCaptured);
verify(mWifiP2pMetrics).endGroupEvent();
}
@@ -7197,6 +7609,33 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
WpsInfo.PBC, WifiP2pManager.CONNECTION_REQUEST_ACCEPT);
}
+ /**
+ * Verify sunny scenario for setConnectionRequestResult show pin event.
+ */
+ @Test
+ public void testSetConnectionRequestResultSuccessShowPin() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastS());
+ forceP2pEnabled(mClient1);
+ Binder binder = new Binder();
+ verifyAddExternalApprover(binder, true, true,
+ MacAddress.fromString(mTestWifiP2pDevice.deviceAddress));
+
+ WifiP2pProvDiscEvent pdEvent = new WifiP2pProvDiscEvent();
+ pdEvent.device = mTestWifiP2pDevice;
+ pdEvent.pin = "pin";
+ sendSimpleMsg(null,
+ WifiP2pMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT,
+ pdEvent);
+ mLooper.dispatchAll();
+
+ sendSetConnectionRequestResultMsg(mClientMessenger,
+ MacAddress.fromString(mTestWifiP2pDevice.deviceAddress),
+ WifiP2pManager.CONNECTION_REQUEST_ACCEPT, binder);
+
+ verify(mWifiNative).p2pConnect(any(), anyBoolean());
+ verify(mWifiNative, never()).p2pStopFind();
+ }
+
private void verifyMultiApproverMatch(List<MacAddress> addresses, MacAddress expectedMatch)
throws Exception {
when(mWifiPermissionsUtil.checkManageWifiNetworkSelectionPermission(anyInt()))
@@ -7785,7 +8224,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
verify(mWifiP2pMetrics).startGroupEvent(group);
verify(mWifiNative).p2pStopFind();
verify(mWifiNative).p2pExtListen(eq(false), anyInt(), anyInt(), eq(null));
- sendGroupRemovedMsg();
+ sendGroupRemovedMsg(group);
//force to back disabled state
mockEnterDisabledState();
@@ -8125,7 +8564,7 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
p2pGroupCaptor.capture());
assertEquals(TEST_GROUP_FREQUENCY, p2pGroupCaptor.getValue().getFrequency());
- sendGroupRemovedMsg();
+ sendGroupRemovedMsg(p2pGroup);
mockEnterDisabledState();
mLooper.dispatchAll();
verify(mP2pListener).onGroupRemoved();
@@ -8139,6 +8578,35 @@ public class WifiP2pServiceImplTest extends WifiBaseTest {
}
/**
+ * Verify that p2p listener group created callback is sent for negotiated GO
+ */
+ @Test
+ public void testP2pListenerWpsGroupCreated() throws Exception {
+ assumeTrue(SdkLevel.isAtLeastT());
+ forceP2pEnabled(mClient1);
+
+ WifiP2pGroup group = new WifiP2pGroup();
+ group.setNetworkId(WifiP2pGroup.NETWORK_ID_PERSISTENT);
+ group.setNetworkName(TEST_NETWORK_NAME);
+ group.setOwner(new WifiP2pDevice("thisDeviceMac"));
+ group.setIsGroupOwner(true);
+ group.setInterface(IFACE_NAME_P2P);
+ sendGroupStartedMsg(group);
+ simulateTetherReady();
+ ArgumentCaptor<WifiP2pInfo> p2pInfoCaptor = ArgumentCaptor.forClass(WifiP2pInfo.class);
+ ArgumentCaptor<WifiP2pGroup> p2pGroupCaptor = ArgumentCaptor.forClass(WifiP2pGroup.class);
+ WifiP2pDevice peerClientDevice = new WifiP2pDevice();
+ peerClientDevice.deviceName = "peerClientDeviceName";
+ peerClientDevice.deviceAddress = "11:22:33:aa:bb:cc";
+ peerClientDevice.setInterfaceMacAddress(MacAddress.fromString(PEER_INTERFACE_ADDRESS));
+ sendSimpleMsg(null, WifiP2pMonitor.AP_STA_CONNECTED_EVENT, peerClientDevice);
+ verify(mP2pListener).onGroupCreated(p2pInfoCaptor.capture(), p2pGroupCaptor.capture());
+ assertEquals(TEST_NETWORK_NAME, p2pGroupCaptor.getValue().getNetworkName());
+ assertFalse(p2pGroupCaptor.getValue().isClientListEmpty());
+ assertTrue(p2pInfoCaptor.getValue().groupFormed);
+ }
+
+ /**
* Verify that p2p disable when the D2d allowed value changes to false
*/
@Test
diff --git a/service/tests/wifitests/src/com/android/server/wifi/rtt/RttTestUtils.java b/service/tests/wifitests/src/com/android/server/wifi/rtt/RttTestUtils.java
index 2ddeeeb03e..1e7df0db7a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/rtt/RttTestUtils.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/rtt/RttTestUtils.java
@@ -77,6 +77,38 @@ public class RttTestUtils {
}
/**
+ * Returns a placeholder ranging request with 4 requests and a non-default in-range burst size:
+ * - First: 802.11mc capable
+ * - Second: 802.11mc not capable
+ * - Third: Aware peer
+ * - Fourth: 802.11az & 802.11mc capable
+ */
+ public static RangingRequest getDummyRangingRequestWith11az(byte lastMacByte) {
+ RangingRequest.Builder builder = new RangingRequest.Builder();
+
+ ScanResult scan1 = new ScanResult();
+ scan1.BSSID = "00:01:02:03:04:" + String.format("%02d", lastMacByte);
+ scan1.setFlag(ScanResult.FLAG_80211mc_RESPONDER);
+ scan1.channelWidth = ScanResult.CHANNEL_WIDTH_40MHZ;
+ ScanResult scan2 = new ScanResult();
+ scan2.BSSID = "0A:0B:0C:0D:0E:" + String.format("%02d", lastMacByte);
+ scan2.channelWidth = ScanResult.CHANNEL_WIDTH_20MHZ;
+ MacAddress mac1 = MacAddress.fromString("08:09:08:07:06:05");
+
+ builder.addAccessPoint(scan1);
+ builder.addNon80211mcCapableAccessPoint(scan2);
+ // Changing default RTT burst size to a valid, but maximum, value
+ builder.setRttBurstSize(RangingRequest.getMaxRttBurstSize());
+ builder.addWifiAwarePeer(mac1);
+ // Add 11az & 11mc supported AP
+ scan1.BSSID = "00:11:22:33:44:" + String.format("%02d", lastMacByte);
+ scan1.setFlag(ScanResult.FLAG_80211mc_RESPONDER);
+ scan1.setFlag(ScanResult.FLAG_80211az_NTB_RESPONDER);
+ scan1.channelWidth = ScanResult.CHANNEL_WIDTH_40MHZ;
+ builder.addAccessPoint(scan1);
+ return builder.build();
+ }
+ /**
* Returns a placeholder ranging request with 11mc request with a specified burst size.
*/
public static RangingRequest getDummyRangingRequestMcOnly(byte lastMacByte, int rttBurstSize) {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java
index 3d0b4e5579..469f505713 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java
@@ -484,9 +484,8 @@ public abstract class BaseWifiScannerImplTest extends WifiBaseTest {
mLooper.dispatchAll();
- for (ScanResult result : fullResults) {
- order.verify(eventHandler).onFullScanResult(eq(result), eq(0));
- }
+ order.verify(eventHandler).onFullScanResults(any(), eq(0));
+
order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
assertScanDataEquals(scanData, mScanner.getLatestSingleScanResults());
@@ -551,9 +550,7 @@ public abstract class BaseWifiScannerImplTest extends WifiBaseTest {
mLooper.dispatchAll();
if (expectFullResults) {
- for (ScanResult result : results.getRawScanResults()) {
- order.verify(eventHandler).onFullScanResult(eq(result), eq(0));
- }
+ order.verify(eventHandler).onFullScanResults(any(), eq(0));
}
order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java b/service/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
index b8f3a6bd46..971722a82c 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
@@ -2922,6 +2922,28 @@ public class WifiScanningServiceTest extends WifiBaseTest {
client.verifyPnoNetworkFoundReceived(scanResults.getRawScanResults());
}
+ @Test
+ public void testPnoStartStopBackToBack() throws Exception {
+ mWifiScanningServiceImpl.startService();
+ mLooper.dispatchAll();
+ assertTrue(mWifiScanningServiceImpl.setScanningEnabled(true, 0, TEST_PACKAGE_NAME));
+ mLooper.dispatchAll();
+
+ TestClient client = new TestClient();
+
+ // removing a unregistered client should not crash
+ mWifiScanningServiceImpl.stopPnoScan(client.listener, TEST_PACKAGE_NAME, null);
+ mLooper.dispatchAll();
+
+ // back to back start and stop should work
+ mWifiScanningServiceImpl.startPnoScan(client.listener, new WifiScanner.ScanSettings(),
+ new WifiScanner.PnoSettings(), TEST_PACKAGE_NAME, null);
+ mWifiScanningServiceImpl.stopPnoScan(client.listener, TEST_PACKAGE_NAME, null);
+ mLooper.dispatchAll();
+ client.verifyLinkedToDeath();
+ client.verifyUnlinkedToDeath();
+ }
+
/**
* Verifies that only clients with NETWORK_STACK permission can call restricted APIs.
*
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java
index 5774278cc1..749d05ef8d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/ApConfigUtilTest.java
@@ -42,8 +42,6 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.Context;
-import android.content.res.Resources;
import android.net.MacAddress;
import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.ScanResult;
@@ -51,9 +49,11 @@ import android.net.wifi.SoftApCapability;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.SoftApConfiguration.Builder;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiContext;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.nl80211.DeviceWiphyCapabilities;
+import android.net.wifi.util.WifiResourceCache;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -166,8 +166,8 @@ public class ApConfigUtilTest extends WifiBaseTest {
private static final int[] ALLOWED_60G_CHANS = {1, 2}; // ch# 1, 2
private static final int[] TEST_5G_DFS_FREQS = {5280, 5520}; // ch#56, 104
- @Mock Context mContext;
- @Mock Resources mResources;
+ @Mock WifiContext mContext;
+ @Mock WifiResourceCache mResources;
@Mock WifiNative mWifiNative;
@Mock CoexManager mCoexManager;
@Mock WifiSettingsConfigStore mConfigStore;
@@ -189,7 +189,7 @@ public class ApConfigUtilTest extends WifiBaseTest {
mCapability.setSupportedChannelList(SoftApConfiguration.BAND_2GHZ, ALLOWED_2G_CHANS);
mCapability.setSupportedChannelList(SoftApConfiguration.BAND_5GHZ, ALLOWED_5G_CHANS);
mCapability.setSupportedChannelList(SoftApConfiguration.BAND_60GHZ, ALLOWED_60G_CHANS);
- when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getResourceCache()).thenReturn(mResources);
when(mResources.getBoolean(R.bool.config_wifi24ghzSupport)).thenReturn(true);
when(mResources.getBoolean(R.bool.config_wifi5ghzSupport)).thenReturn(true);
when(mResources.getBoolean(R.bool.config_wifiSoftap24ghzSupported)).thenReturn(true);
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/HalAidlUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/HalAidlUtilTest.java
index 102ef51d8a..95b9779fdd 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/HalAidlUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/HalAidlUtilTest.java
@@ -19,15 +19,11 @@ package com.android.server.wifi.util;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
import android.hardware.wifi.common.OuiKeyedData;
import android.net.wifi.util.PersistableBundleUtils;
import android.os.PersistableBundle;
-import com.android.modules.utils.build.SdkLevel;
-
-import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
@@ -39,11 +35,6 @@ import java.util.List;
public class HalAidlUtilTest {
private static final int TEST_VENDOR_DATA_LIST_SIZE = 10;
- @Before
- public void setUp() throws Exception {
- assumeTrue(SdkLevel.isAtLeastV());
- }
-
private static PersistableBundle createTestPersistableBundle() {
PersistableBundle bundle = new PersistableBundle();
bundle.putString("stringKey", "someStringData");
diff --git a/service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java
index 0d5e495193..abc04e5f9d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java
@@ -466,11 +466,13 @@ public class InformationElementUtilTest extends WifiBaseTest {
InformationElement[] ies,
int beaconCap,
boolean isOweSupported,
+ boolean isRsnOverridingSupported,
String capsStr,
SparseIntArray unknownAkmMap) {
InformationElementUtil.Capabilities capabilities =
new InformationElementUtil.Capabilities();
- capabilities.from(ies, beaconCap, isOweSupported, 2400, unknownAkmMap);
+ capabilities.from(ies, beaconCap, isOweSupported, isRsnOverridingSupported, 2400,
+ unknownAkmMap);
String result = capabilities.generateCapabilitiesString();
assertEquals(capsStr, result);
@@ -484,7 +486,8 @@ public class InformationElementUtilTest extends WifiBaseTest {
SparseIntArray unknownAkmMap) {
InformationElement[] ies = new InformationElement[] { ie };
verifyCapabilityStringFromIes(
- new InformationElement[] {ie}, beaconCap, isOweSupported, capsStr, unknownAkmMap);
+ new InformationElement[] {ie}, beaconCap, isOweSupported, false, capsStr,
+ unknownAkmMap);
}
private void verifyCapabilityStringFromIeWithoutOweSupported(
@@ -801,6 +804,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
ies,
0x1 << 4,
false,
+ false,
"[WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][RSN-PSK-CCMP+TKIP]",
null);
}
@@ -1130,6 +1134,210 @@ public class InformationElementUtilTest extends WifiBaseTest {
}
/**
+ * Test Capabilities.generateCapabilitiesString() with RSN, RSNO & RSNO2 element
+ * This configuration is same as a Wi-Fi 7 supported AP configured in
+ * WPA3-Compatibility Mode operating on the 2.4GHz/5GHz.
+ * Expect the function to return a string with the proper security information.
+ */
+ @Test
+ public void buildCapabilities_rsnRsnoAndRsno2Element() {
+ //RSNE Element carries WPA-PSK (AKM: 2)
+ InformationElement ieRsn = new InformationElement();
+ ieRsn.id = InformationElement.EID_RSN;
+ ieRsn.bytes = new byte[] {
+ // RSNE Version (0x0001)
+ (byte) 0x01, (byte) 0x00,
+ // Group cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of pairwise cipher suites (1)
+ (byte) 0x01, (byte) 0x00,
+ // Pairwise Cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of AKMs (1)
+ (byte) 0x01, (byte) 0x00,
+ // PSK AKM
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x02,
+ // RSN capabilities
+ (byte) 0x00, (byte) 0x00,
+ };
+
+ //RSNE Override Element carries SAE (AKM: 8)
+ InformationElement ieRsno = new InformationElement();
+ ieRsno.id = InformationElement.EID_VSA;
+ ieRsno.bytes = new byte[] {
+ // RSNO (OUI type - 0x29) WFA vendor specific IE header
+ (byte) 0x50, (byte) 0x6F, (byte) 0x9A, (byte) 0x29,
+ // RSNE Version (0x0001)
+ (byte) 0x01, (byte) 0x00,
+ // Group cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of pairwise cipher suites (1)
+ (byte) 0x01, (byte) 0x00,
+ // Pairwise Cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of AKMs (1)
+ (byte) 0x01, (byte) 0x00,
+ // SAE AKM
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x08,
+ // RSN capabilities
+ (byte) 0xC0, (byte) 0x00 };
+
+ //RSNE Override Element 2 Element carries SAE_EXT_KEY (AKM: 24)
+ InformationElement ieRsno2 = new InformationElement();
+ ieRsno2.id = InformationElement.EID_VSA;
+ ieRsno2.bytes = new byte[]{
+ // RSNO2 (OUI type - 0x2A) WFA vendor specific IE header
+ (byte) 0x50, (byte) 0x6F, (byte) 0x9A, (byte) 0x2A,
+ // RSNE Version (0x0001)
+ (byte) 0x01, (byte) 0x00,
+ // Group cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of pairwise cipher suites (1)
+ (byte) 0x01, (byte) 0x00,
+ // Cipher suite: GCMP-256
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x09,
+ // Number of AKMs (1)
+ (byte) 0x01, (byte) 0x00,
+ // SAE-EXT-KEY AKM
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x18,
+ // Padding
+ // RSN capabilities
+ (byte) 0xC0, (byte) 0x00,
+ };
+
+ InformationElement[] ies = new InformationElement[] { ieRsn, ieRsno, ieRsno2 };
+
+ verifyCapabilityStringFromIes(
+ ies,
+ 0x1 << 4,
+ true,
+ true,
+ "[WPA2-PSK-CCMP][RSN-PSK-CCMP][RSN-SAE-CCMP][RSN-SAE_EXT_KEY-GCMP-256][MFPC][RSNO]",
+ null);
+ }
+
+ /**
+ * Test Capabilities.generateCapabilitiesString() with RSN, RSNO & RSNO2 element
+ * This configuration is same as a Wi-Fi 7 supported AP configured in
+ * WPA3-Compatibility Mode operating on the 6GHz band.
+ * Expect the function to return a string with the proper security information.
+ */
+ @Test
+ public void buildCapabilities_rsnAndRsno2Element() {
+ //RSNE Element carries SAE (AKM: 8)
+ InformationElement ieRsn = new InformationElement();
+ ieRsn.id = InformationElement.EID_RSN;
+ ieRsn.bytes = new byte[] {
+ // RSNE Version (0x0001)
+ (byte) 0x01, (byte) 0x00,
+ // Group cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of pairwise cipher suites (1)
+ (byte) 0x01, (byte) 0x00,
+ // Pairwise Cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of AKMs (1)
+ (byte) 0x01, (byte) 0x00,
+ // SAE AKM
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x08,
+ // RSN capabilities
+ (byte) 0xC0, (byte) 0x00,
+ };
+
+ //RSNE Override Element 2 Element carries SAE_EXT_KEY (AKM: 24)
+ InformationElement ieRsno2 = new InformationElement();
+ ieRsno2.id = InformationElement.EID_VSA;
+ ieRsno2.bytes = new byte[]{
+ // RSNO2 (OUI type - 0x2A) WFA vendor specific IE header
+ (byte) 0x50, (byte) 0x6F, (byte) 0x9A, (byte) 0x2A,
+ // RSNE Version (0x0001)
+ (byte) 0x01, (byte) 0x00,
+ // Group cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of pairwise cipher suites (1)
+ (byte) 0x01, (byte) 0x00,
+ // Cipher suite: GCMP-256
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x09,
+ // Number of AKMs (1)
+ (byte) 0x01, (byte) 0x00,
+ // SAE-EXT-KEY AKM
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x18,
+ // Padding
+ // RSN capabilities
+ (byte) 0xC0, (byte) 0x00,
+ };
+
+ InformationElement[] ies = new InformationElement[] { ieRsn, ieRsno2 };
+
+ verifyCapabilityStringFromIes(
+ ies,
+ 0x1 << 4,
+ true,
+ true,
+ "[RSN-SAE-CCMP][RSN-SAE_EXT_KEY-GCMP-256][MFPR][MFPC][RSNO]",
+ null);
+ }
+
+ /**
+ * Test Capabilities.generateCapabilitiesString() without RSN Overriding support.
+ * The AP advertise WPA2 security params in RSN IE and WPA3 security params in RSNO element.
+ * But without the RSN Overriding support, it is expected to return a capabilities string
+ * which contains only WPA2 security params.
+ */
+ @Test
+ public void buildCapabilities_rsnAndRsnoElementWithoutRsnOverridingSupport() {
+ //RSNE Element carries WPA-PSK (AKM: 2)
+ InformationElement ieRsn = new InformationElement();
+ ieRsn.id = InformationElement.EID_RSN;
+ ieRsn.bytes = new byte[] {
+ // RSNE Version (0x0001)
+ (byte) 0x01, (byte) 0x00,
+ // Group cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of pairwise cipher suites (1)
+ (byte) 0x01, (byte) 0x00,
+ // Pairwise Cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of AKMs (1)
+ (byte) 0x01, (byte) 0x00,
+ // PSK AKM
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x02,
+ // RSN capabilities
+ (byte) 0x00, (byte) 0x00,
+ };
+
+ //RSNE Override Element carries SAE (AKM: 8)
+ InformationElement ieRsno = new InformationElement();
+ ieRsno.id = InformationElement.EID_VSA;
+ ieRsno.bytes = new byte[] {
+ // RSNO (OUI type - 0x29) WFA vendor specific IE header
+ (byte) 0x50, (byte) 0x6F, (byte) 0x9A, (byte) 0x29,
+ // RSNE Version (0x0001)
+ (byte) 0x01, (byte) 0x00,
+ // Group cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of pairwise cipher suites (1)
+ (byte) 0x01, (byte) 0x00,
+ // Pairwise Cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of AKMs (1)
+ (byte) 0x01, (byte) 0x00,
+ // SAE AKM
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x08,
+ // RSN capabilities
+ (byte) 0xC0, (byte) 0x00 };
+ InformationElement[] ies = new InformationElement[] { ieRsn, ieRsno };
+
+ verifyCapabilityStringFromIes(
+ ies,
+ 0x1 << 4,
+ true,
+ false,
+ "[WPA2-PSK-CCMP][RSN-PSK-CCMP]",
+ null);
+ }
+
+ /**
* Test Capabilities.generateCapabilitiesString() with both RSN and WPA1 IE which are malformed.
* Expect the function to return a string with empty key management & pairswise cipher security
* information.
@@ -1148,7 +1356,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
(byte) 0xF2, (byte) 0x02, (byte) 0x02, (byte) 0x00,
(byte) 0x00, (byte) 0x50 };
InformationElement[] ies = new InformationElement[] { ieWpa, ieRsn };
- verifyCapabilityStringFromIes(ies, 0x1 << 4, false, "[WPA][RSN]", null);
+ verifyCapabilityStringFromIes(ies, 0x1 << 4, false, false, "[WPA][RSN]", null);
}
/**
@@ -1172,7 +1380,8 @@ public class InformationElementUtilTest extends WifiBaseTest {
ieWps.bytes = new byte[] { (byte) 0x00, (byte) 0x50, (byte) 0xF2, (byte) 0x04 };
InformationElement[] ies = new InformationElement[] { ieWpa, ieWps };
- verifyCapabilityStringFromIes(ies, 0x1 << 4, false, "[WPA-PSK-CCMP+TKIP][WPS]", null);
+ verifyCapabilityStringFromIes(ies, 0x1 << 4, false, false, "[WPA-PSK-CCMP+TKIP][WPS]",
+ null);
}
/**
@@ -1253,7 +1462,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
InformationElementUtil.Capabilities capabilities =
new InformationElementUtil.Capabilities();
- capabilities.from(new InformationElement[0], beaconCap, false, 2400, null);
+ capabilities.from(new InformationElement[0], beaconCap, false, false, 2400, null);
String result = capabilities.generateCapabilitiesString();
assertEquals("[IBSS]", result);
@@ -1270,7 +1479,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
InformationElementUtil.Capabilities capabilities =
new InformationElementUtil.Capabilities();
- capabilities.from(new InformationElement[0], beaconCap, false, 58320, null);
+ capabilities.from(new InformationElement[0], beaconCap, false, false, 58320, null);
String result = capabilities.generateCapabilitiesString();
assertEquals("[IBSS]", result);
@@ -1287,7 +1496,7 @@ public class InformationElementUtilTest extends WifiBaseTest {
InformationElementUtil.Capabilities capabilities =
new InformationElementUtil.Capabilities();
- capabilities.from(new InformationElement[0], beaconCap, false, 58320, null);
+ capabilities.from(new InformationElement[0], beaconCap, false, false, 58320, null);
String result = capabilities.generateCapabilitiesString();
assertEquals("[ESS]", result);